001    /*
002     * Copyright 2004 Chris Nelson
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
007     * Unless required by applicable law or agreed to in writing,
008     * software distributed under the License is distributed on an "AS IS" BASIS,
009     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010     * See the License for the specific language governing permissions and limitations under the License.
011     */
012    package org.trails.page;
013    
014    import org.apache.commons.logging.Log;
015    import org.apache.commons.logging.LogFactory;
016    import org.apache.tapestry.IRequestCycle;
017    import org.apache.tapestry.annotations.Bean;
018    import org.apache.tapestry.annotations.Lifecycle;
019    import org.apache.tapestry.callback.ICallback;
020    import org.apache.tapestry.engine.ILink;
021    import org.trails.callback.TrailsPageCallback;
022    import org.trails.engine.TrailsPagesServiceParameter;
023    import org.trails.persistence.PersistenceException;
024    import org.trails.validation.TrailsValidationDelegate;
025    
026    /**
027     * This page will edit an instance contained in the model property
028     *
029     * @author Chris Nelson
030     */
031    public abstract class EditPage extends ModelPage implements IAssociationPage
032    {
033    
034            private static final Log LOG = LogFactory.getLog(EditPage.class);
035    
036            @Bean(lifecycle = Lifecycle.REQUEST)
037            public abstract TrailsValidationDelegate getDelegate();
038    
039            public abstract ICallback getNextPage();
040    
041            public abstract void setNextPage(ICallback NextPage);
042    
043            public ILink save(IRequestCycle cycle)
044            {
045                    if (save())
046                    {
047                            if (getCallbackStack() != null && !getCallbackStack().isEmpty())
048                            {
049                                    // When saving objects with assigned IDs, we need to removed the last element of the stack.
050                                    getCallbackStack().pop();
051                            }
052                            return linkToThisPage();
053                    }
054                    return null;
055            }
056    
057            private ILink defaultCallback()
058            {
059                    if (!isReferencedByParentPage())
060                    {
061                            return getTrailsPagesService().getLink(false, new TrailsPagesServiceParameter(PageType.LIST, getClassDescriptor()));
062                    } else {
063                            return getTrailsPagesService().getLink(false, new TrailsPagesServiceParameter(PageType.EDIT,
064                                            getDescriptorService().getClassDescriptor(getParent().getClass()), getParent(), null, null));
065                    }
066    
067            }
068    
069            private ILink linkToThisPage()
070            {
071                    return getTrailsPagesService()
072                                    .getLink(false, new TrailsPagesServiceParameter(PageType.EDIT, getClassDescriptor(), getModel(), getAssociationDescriptor(), getParent()));
073            }
074    
075            protected ICallback callbackToThisPage()
076            {
077                    return new TrailsPageCallback(new TrailsPagesServiceParameter(PageType.EDIT, getClassDescriptor(), getModel(),
078                                    getAssociationDescriptor(), getParent()), getTrailsPagesService());
079            }
080    
081            protected boolean save()
082            {
083                    if (!getDelegate().getHasErrors())
084                    {
085                            // We get hibernate errors when the cascade tries to
086                            // put the same object on the session twice
087                            // if (!cameFromChildCollection())
088                            // {
089                            try
090                            {
091                                    if (isReferencedByParentPage() && isModelNew())
092                                    {
093                                            setModel(getPersistenceService().saveCollectionElement(
094                                                            getAssociationDescriptor().getAddExpression(), getModel(), getParent()));
095                                    } else
096                                    {
097                                            setModel(getPersistenceService().save(getModel()));
098                                    }
099                            } catch (PersistenceException pe)
100                            {
101                                    getDelegate().record(pe);
102                                    return false;
103                            }
104                            // }
105                            return true;
106                    }
107                    return false;
108            }
109    
110            public ILink cancel(IRequestCycle cycle)
111            {
112                    return goBack(cycle);
113            }
114    
115            public ILink goBack(IRequestCycle cycle)
116            {
117    
118                    if (getCallbackStack() != null)
119                    {
120                            ICallback callback = getCallbackStack().popPreviousCallback();
121                            if (callback != null)
122                            {
123                                    callback.performCallback(cycle);
124                                    return null;
125                            }
126                    }
127                    return defaultCallback();
128            }
129    
130            public ILink saveAndReturn(IRequestCycle cycle)
131            {
132                    if (save())
133                    {
134                            return goBack(cycle);
135                    }
136                    return null;
137            }
138    
139            public ILink remove(IRequestCycle cycle)
140            {
141    
142                    try
143                    {
144                            if (isReferencedByParentPage())
145                            {
146    
147                                    getPersistenceService().removeCollectionElement(getAssociationDescriptor().getRemoveExpression(),
148                                                    getModel(), getParent());
149                            } else
150                            {
151                                    getPersistenceService().remove(getModel());
152                            }
153    
154                    } catch (PersistenceException pe)
155                    {
156                            getDelegate().record(pe);
157                            return null;
158    
159                    } catch (Exception e)
160                    {
161                            getDelegate().record(e);
162                            return null;
163                    }
164    
165                    return goBack(cycle);
166            }
167    
168            /**
169             * @return
170             */
171            public String getTitle()
172            {
173                    Object[] params = new Object[]{getClassDescriptor().getDisplayName()};
174                    if (isModelNew())
175                    {
176                            return getResourceBundleMessageSource()
177                                            .getMessageWithDefaultValue("org.trails.i18n.add", params, "[TRAILS][ORG.TRAILS.I18N.ADD]");
178                    } else
179                    {
180                            return getResourceBundleMessageSource()
181                                            .getMessageWithDefaultValue("org.trails.i18n.edit", params, "[TRAILS][ORG.TRAILS.I18N.EDIT]");
182                    }
183            }
184    
185            public boolean isReferencedByParentPage()
186            {
187                    return getParent() != null;
188            }
189    
190    }