Source Code Cross Referenced for AbstractUsecase.java in  » Content-Management-System » apache-lenya-2.0 » org » apache » lenya » cms » usecase » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Content Management System » apache lenya 2.0 » org.apache.lenya.cms.usecase 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         *
017:         */
018:        package org.apache.lenya.cms.usecase;
019:
020:        import java.util.ArrayList;
021:        import java.util.Collections;
022:        import java.util.HashMap;
023:        import java.util.Iterator;
024:        import java.util.List;
025:        import java.util.Map;
026:        import java.util.Set;
027:
028:        import org.apache.avalon.framework.activity.Initializable;
029:        import org.apache.avalon.framework.configuration.Configurable;
030:        import org.apache.avalon.framework.configuration.Configuration;
031:        import org.apache.avalon.framework.configuration.ConfigurationException;
032:        import org.apache.avalon.framework.context.Context;
033:        import org.apache.avalon.framework.context.ContextException;
034:        import org.apache.avalon.framework.context.Contextualizable;
035:        import org.apache.avalon.framework.logger.AbstractLogEnabled;
036:        import org.apache.avalon.framework.service.ServiceException;
037:        import org.apache.avalon.framework.service.ServiceManager;
038:        import org.apache.avalon.framework.service.Serviceable;
039:        import org.apache.cocoon.components.ContextHelper;
040:        import org.apache.cocoon.environment.Request;
041:        import org.apache.cocoon.servlet.multipart.Part;
042:        import org.apache.lenya.cms.publication.DocumentFactory;
043:        import org.apache.lenya.cms.publication.DocumentUtil;
044:        import org.apache.lenya.cms.repository.Node;
045:        import org.apache.lenya.cms.repository.RepositoryException;
046:        import org.apache.lenya.cms.repository.RepositoryUtil;
047:        import org.apache.lenya.cms.repository.Session;
048:        import org.apache.lenya.transaction.ConcurrentModificationException;
049:        import org.apache.lenya.transaction.LockException;
050:        import org.apache.lenya.transaction.TransactionLock;
051:
052:        /**
053:         * Abstract usecase implementation.
054:         * 
055:         * @version $Id: AbstractUsecase.java 571548 2007-08-31 19:16:21Z rfrovarp $
056:         */
057:        public class AbstractUsecase extends AbstractLogEnabled implements 
058:                Usecase, Configurable, Contextualizable, Serviceable,
059:                Initializable {
060:
061:            protected static final String EVENT_CHECK_POSTCONDITIONS = "checkPostconditions";
062:
063:            protected static final String EVENT_EXECUTE = "execute";
064:
065:            protected static final String EVENT_CHECK_PRECONDITIONS = "checkPreconditions";
066:
067:            protected static final String EVENT_CHECK_EXECUTION_CONDITIONS = "checkExecutionConditions";
068:
069:            protected static final String ERROR_OBJECTS_CHECKED_OUT = "objects-checked-out";
070:
071:            protected static final StateMachine.Transition[] TRANSITIONS = {
072:                    new StateMachine.Transition("start", "preChecked",
073:                            EVENT_CHECK_PRECONDITIONS),
074:                    new StateMachine.Transition("preChecked", "preChecked",
075:                            EVENT_CHECK_PRECONDITIONS),
076:                    new StateMachine.Transition("preChecked", "nodesLocked",
077:                            "lockInvolvedObjects"),
078:                    new StateMachine.Transition("nodesLocked", "execChecked",
079:                            EVENT_CHECK_EXECUTION_CONDITIONS),
080:                    new StateMachine.Transition("execChecked", "execChecked",
081:                            EVENT_CHECK_EXECUTION_CONDITIONS),
082:                    new StateMachine.Transition("nodesLocked", "preChecked",
083:                            EVENT_CHECK_PRECONDITIONS),
084:                    new StateMachine.Transition("execChecked", "executed",
085:                            EVENT_EXECUTE),
086:                    new StateMachine.Transition("executed", "postChecked",
087:                            EVENT_CHECK_POSTCONDITIONS) };
088:
089:            protected static final StateMachine.Model MODEL = new StateMachine.Model(
090:                    "start", TRANSITIONS);
091:
092:            protected static final String PARAMETER_STATE_MACHINE = "private.stateMachine";
093:            protected static final String PARAMETER_SESSION = "private.session";
094:            protected static final String PARAMETER_FACTORY = "private.factory";
095:            protected static final String PARAMETER_CHECKOUT_RESTRICTED_TO_SESSION = "checkoutRestrictedToSession";
096:
097:            protected static final String PARAMETERS_INITIALIZED = "private.parametersInitialized";
098:
099:            /**
100:             * Override to initialize parameters.
101:             */
102:            protected void initParameters() {
103:            }
104:
105:            /**
106:             * Advance the usecase state machine to the next state. This method has to be called at the end
107:             * of the corresponding method to ensure that the subsequent methods can only be invoked if
108:             * nothing went wrong.
109:             * @param event The vent to invoke.
110:             */
111:            protected void advanceState(String event) {
112:                getStateMachine().invoke(event);
113:            }
114:
115:            protected StateMachine getStateMachine() {
116:                StateMachine machine = (StateMachine) getParameter(PARAMETER_STATE_MACHINE);
117:                return machine;
118:            }
119:
120:            protected void checkEvent(String event) {
121:                getStateMachine().checkEvent(event);
122:            }
123:
124:            protected String SOURCE_URL = "private.sourceUrl";
125:
126:            /**
127:             * @see org.apache.lenya.cms.usecase.Usecase#getSourceURL() We don't use getParameterAsString()
128:             *      because this will typically cause stack overflows or NPEs in connection with
129:             *      initParameters().
130:             */
131:            public String getSourceURL() {
132:                return (String) this .parameters.get(SOURCE_URL);
133:            }
134:
135:            /**
136:             * Returns the context.
137:             * @return A context.
138:             */
139:            protected Context getContext() {
140:                return this .context;
141:            }
142:
143:            /**
144:             * Determine if the usecase has error messages. Provides a way of checking for errors without
145:             * actually retrieving them.
146:             * @return true if the usecase resulted in error messages.
147:             */
148:            public boolean hasErrors() {
149:                boolean ret = false;
150:                if (this .errorMessages != null)
151:                    ret = !this .errorMessages.isEmpty();
152:
153:                if (getLogger().isDebugEnabled())
154:                    getLogger().debug(
155:                            "AbstractUsecase::hasErrors() called, returning "
156:                                    + ret);
157:
158:                return ret;
159:            }
160:
161:            /**
162:             * Determine if the usecase has info messages. Provides a way of checking for info messages
163:             * without actually retrieving them.
164:             * @return true if the usecase resulted in info messages being generated.
165:             */
166:            public boolean hasInfoMessages() {
167:                boolean ret = false;
168:                if (this .infoMessages != null)
169:                    ret = !this .infoMessages.isEmpty();
170:                return ret;
171:            }
172:
173:            /**
174:             * Checks if the operation can be executed and returns the error messages. Error messages
175:             * prevent the operation from being executed.
176:             * @return A boolean value.
177:             */
178:            public List getErrorMessages() {
179:                return Collections.unmodifiableList(new ArrayList(
180:                        this .errorMessages));
181:            }
182:
183:            /**
184:             * Returns the information messages to show on the confirmation screen.
185:             * @return An array of strings. Info messages do not prevent the operation from being executed.
186:             */
187:            public List getInfoMessages() {
188:                return Collections.unmodifiableList(new ArrayList(
189:                        this .infoMessages));
190:            }
191:
192:            private List errorMessages = new ArrayList();
193:            private List infoMessages = new ArrayList();
194:
195:            /**
196:             * Adds an error message.
197:             * @param message The message.
198:             */
199:            public void addErrorMessage(String message) {
200:                this .errorMessages.add(new UsecaseMessage(message));
201:            }
202:
203:            /**
204:             * Adds an error message.
205:             * @param message The message.
206:             * @param _params parameters
207:             */
208:            public void addErrorMessage(String message, String[] _params) {
209:                this .errorMessages.add(new UsecaseMessage(message, _params));
210:            }
211:
212:            /**
213:             * Adds an error message.
214:             * @param messages The messages.
215:             */
216:            public void addErrorMessages(String[] messages) {
217:                for (int i = 0; i < messages.length; i++) {
218:                    addErrorMessage(messages[i]);
219:                }
220:            }
221:
222:            /**
223:             * Adds an info message.
224:             * @param message The message.
225:             * @param _params parameters
226:             */
227:            public void addInfoMessage(String message, String[] _params) {
228:                this .infoMessages.add(new UsecaseMessage(message, _params));
229:            }
230:
231:            /**
232:             * Adds an info message.
233:             * @param message The message.
234:             */
235:            public void addInfoMessage(String message) {
236:                this .infoMessages.add(new UsecaseMessage(message));
237:            }
238:
239:            /**
240:             * @see org.apache.lenya.cms.usecase.Usecase#checkExecutionConditions()
241:             */
242:            public final void checkExecutionConditions()
243:                    throws UsecaseException {
244:                checkEvent(EVENT_CHECK_EXECUTION_CONDITIONS);
245:                try {
246:                    clearErrorMessages();
247:                    clearInfoMessages();
248:                    doCheckExecutionConditions();
249:                    dumpErrorMessages();
250:                } catch (Exception e) {
251:                    getLogger().error(e.getMessage(), e);
252:                    addErrorMessage(e.getMessage()
253:                            + " - Please consult the logfiles.");
254:                    if (getLogger().isDebugEnabled()) {
255:                        throw new UsecaseException(e);
256:                    }
257:                }
258:                if (!hasErrors()) {
259:                    advanceState(EVENT_CHECK_EXECUTION_CONDITIONS);
260:                }
261:            }
262:
263:            /**
264:             * Checks the execution conditions.
265:             * @throws Exception if an error occurs.
266:             */
267:            protected void doCheckExecutionConditions() throws Exception {
268:                // do nothing
269:            }
270:
271:            /**
272:             * @see org.apache.lenya.cms.usecase.Usecase#checkPreconditions()
273:             */
274:            public final void checkPreconditions() throws UsecaseException {
275:                checkEvent(EVENT_CHECK_PRECONDITIONS);
276:                try {
277:                    clearErrorMessages();
278:                    clearInfoMessages();
279:
280:                    Node[] nodes = getNodesToLock();
281:                    if (!canCheckOut(nodes)) {
282:                        addErrorMessage(ERROR_OBJECTS_CHECKED_OUT);
283:                    }
284:                    doCheckPreconditions();
285:
286:                    List _errorMessages = getErrorMessages();
287:                    for (int i = 0; i < _errorMessages.size(); i++) {
288:                        getLogger().info(_errorMessages.get(i).toString());
289:                    }
290:                } catch (Exception e) {
291:                    getLogger().error(e.getMessage(), e);
292:                    addErrorMessage(e.getMessage()
293:                            + " - Please consult the logfiles.");
294:                    if (getLogger().isDebugEnabled()) {
295:                        throw new UsecaseException(e);
296:                    }
297:                }
298:                if (!hasErrors()) {
299:                    advanceState(EVENT_CHECK_PRECONDITIONS);
300:                }
301:            }
302:
303:            /**
304:             * Checks the preconditions.
305:             * @throws Exception if an error occurs.
306:             */
307:            protected void doCheckPreconditions() throws Exception {
308:                // do nothing
309:            }
310:
311:            /**
312:             * Clears the error messages.
313:             */
314:            protected void clearErrorMessages() {
315:                this .errorMessages.clear();
316:            }
317:
318:            /**
319:             * Clears the info messages.
320:             */
321:            protected void clearInfoMessages() {
322:                this .infoMessages.clear();
323:            }
324:
325:            /**
326:             * @see org.apache.lenya.cms.usecase.Usecase#execute()
327:             */
328:            public final void execute() throws UsecaseException {
329:                checkEvent(EVENT_EXECUTE);
330:                Exception exception = null;
331:                try {
332:                    clearErrorMessages();
333:                    clearInfoMessages();
334:                    doExecute();
335:                    dumpErrorMessages();
336:                } catch (LockException e) {
337:                    exception = e;
338:                    addErrorMessage("The operation could not be completed because an involved object was changed by another user.");
339:                } catch (Exception e) {
340:                    exception = e;
341:                    getLogger().error(e.getMessage(), e);
342:                    addErrorMessage(e.getMessage()
343:                            + " - Please consult the logfiles.");
344:                    throw new UsecaseException(e);
345:                } finally {
346:                    try {
347:                        if (this .commitEnabled && getErrorMessages().isEmpty()
348:                                && exception == null) {
349:                            getSession().commit();
350:                        } else {
351:                            getSession().rollback();
352:                        }
353:                    } catch (ConcurrentModificationException e) {
354:                        getLogger().error(
355:                                "Could not commit usecase [" + getName()
356:                                        + "]: " + e.getMessage());
357:                        addErrorMessage(e.getMessage());
358:                    } catch (Exception e1) {
359:                        getLogger().error(
360:                                "Could not commit/rollback usecase ["
361:                                        + getName() + "]: ", e1);
362:                        addErrorMessage("Exception during commit or rollback: "
363:                                + e1.getMessage()
364:                                + " (see logfiles for details)");
365:                    }
366:                }
367:                if (!hasErrors()) {
368:                    advanceState(EVENT_EXECUTE);
369:                }
370:            }
371:
372:            /**
373:             * Dumps the error messages to the log.
374:             */
375:            protected void dumpErrorMessages() {
376:                List _errorMessages = getErrorMessages();
377:                for (int i = 0; i < _errorMessages.size(); i++) {
378:                    getLogger().error(_errorMessages.get(i).toString());
379:                }
380:            }
381:
382:            /**
383:             * @see org.apache.lenya.cms.usecase.Usecase#checkPostconditions()
384:             */
385:            public void checkPostconditions() throws UsecaseException {
386:                checkEvent(EVENT_CHECK_POSTCONDITIONS);
387:                try {
388:                    clearErrorMessages();
389:                    clearInfoMessages();
390:                    doCheckPostconditions();
391:                    dumpErrorMessages();
392:                } catch (Exception e) {
393:                    getLogger().error(e.getMessage(), e);
394:                    addErrorMessage(e.getMessage()
395:                            + " - Please consult the logfiles.");
396:                    if (getLogger().isDebugEnabled()) {
397:                        throw new UsecaseException(e);
398:                    }
399:                }
400:                if (!hasErrors()) {
401:                    advanceState(EVENT_CHECK_POSTCONDITIONS);
402:                }
403:            }
404:
405:            /**
406:             * Checks the post conditions.
407:             * @throws Exception if an error occured.
408:             */
409:            protected void doCheckPostconditions() throws Exception {
410:                // do nothing
411:            }
412:
413:            /**
414:             * Executes the operation.
415:             * @throws Exception when something went wrong.
416:             */
417:            protected void doExecute() throws Exception {
418:                // do nothing
419:            }
420:
421:            private Map parameters = new HashMap();
422:
423:            /**
424:             * @see org.apache.lenya.cms.usecase.Usecase#setParameter(java.lang.String, java.lang.Object)
425:             */
426:            public void setParameter(String name, Object value) {
427:                if (getLogger().isDebugEnabled()) {
428:                    getLogger().debug(
429:                            "Setting parameter [" + name + "] = [" + value
430:                                    + "]");
431:                }
432:                this .parameters.put(name, value);
433:                // set any exit parameters that are missing values
434:                if (this .exitUsecaseParameters.containsKey(name)
435:                        && this .exitUsecaseParameters.get(name) == null) {
436:                    setExitParameter(name, value.toString());
437:                }
438:            }
439:
440:            /**
441:             * @see org.apache.lenya.cms.usecase.Usecase#getParameter(java.lang.String)
442:             */
443:            public Object getParameter(String name) {
444:                if (!this .parameters.containsKey(name)) {
445:                    initializeParametersIfNotDone();
446:                }
447:                return this .parameters.get(name);
448:            }
449:
450:            /**
451:             * @see org.apache.lenya.cms.usecase.Usecase#getParameter(java.lang.String, java.lang.Object)
452:             */
453:            public Object getParameter(String name, Object defaultValue) {
454:                Object value = getParameter(name);
455:                if (value == null) {
456:                    value = defaultValue;
457:                }
458:                return value;
459:            }
460:
461:            /**
462:             * @see org.apache.lenya.cms.usecase.Usecase#getParameterAsString(java.lang.String)
463:             */
464:            public String getParameterAsString(String name) {
465:                String valueString = null;
466:                Object value = getParameter(name);
467:                if (value != null) {
468:                    valueString = value.toString();
469:                }
470:                return valueString;
471:            }
472:
473:            /**
474:             * Returns a parameter as string. If the parameter does not exist, a default value is returned.
475:             * @param name The parameter name.
476:             * @param defaultValue The default value.
477:             * @return A string.
478:             */
479:            public String getParameterAsString(String name, String defaultValue) {
480:                String valueString = defaultValue;
481:                Object value = getParameter(name);
482:                if (value != null) {
483:                    valueString = value.toString();
484:                }
485:                return valueString;
486:            }
487:
488:            /**
489:             * Returns a parameter as integer. If the parameter does not exist, a default value is returned.
490:             * @param name The parameter name.
491:             * @param defaultValue The default value.
492:             * @return An integer.
493:             */
494:            public int getParameterAsInteger(String name, int defaultValue) {
495:                int valueInt = defaultValue;
496:                Object value = getParameter(name);
497:                if (value != null) {
498:                    valueInt = Integer.valueOf(value.toString()).intValue();
499:                }
500:                return valueInt;
501:            }
502:
503:            /**
504:             * Returns a parameter as boolean. If the parameter does not exist, a default value is returned.
505:             * @param name The parameter name.
506:             * @param defaultValue The default value.
507:             * @return A boolean value..
508:             */
509:            public boolean getParameterAsBoolean(String name,
510:                    boolean defaultValue) {
511:                boolean valueBoolean = defaultValue;
512:                Object value = getParameter(name);
513:                if (value != null) {
514:                    if (value instanceof  String) {
515:                        valueBoolean = Boolean.valueOf((String) value)
516:                                .booleanValue();
517:                    } else if (value instanceof  Boolean) {
518:                        valueBoolean = ((Boolean) value).booleanValue();
519:                    } else {
520:                        throw new IllegalArgumentException(
521:                                "Cannot get boolean value of parameter ["
522:                                        + name + "] (class "
523:                                        + value.getClass().getName() + ")");
524:                    }
525:                }
526:                return valueBoolean;
527:            }
528:
529:            /**
530:             * Return a map of all parameters
531:             * @return the map
532:             */
533:            public Map getParameters() {
534:                initializeParametersIfNotDone();
535:                return Collections.unmodifiableMap(this .parameters);
536:            }
537:
538:            /**
539:             * Returns one of the strings "true" or "false" depending on whether the corresponding checkbox
540:             * was checked.
541:             * @param name The parameter name.
542:             * @return A string.
543:             */
544:            public String getBooleanCheckboxParameter(String name) {
545:                String value = "false";
546:                if (getParameter(name) != null
547:                        && getParameter(name).equals("on")) {
548:                    value = "true";
549:                }
550:                return value;
551:            }
552:
553:            private String EXIT_URI = "lenya.exitUri";
554:            private String DEFAULT_TARGET_URL = "private.defaultTargetUrl";
555:
556:            /**
557:             * Sets the default target URL which should be used if no explicit target URL is set.
558:             * @param url A URL string.
559:             */
560:            protected void setDefaultTargetURL(String url) {
561:                setParameter(DEFAULT_TARGET_URL, url);
562:            }
563:
564:            /**
565:             * If {@link #setDefaultTargetURL(String)}was not called, the source document (
566:             * {@link #getSourceURL()}) is returned.
567:             * @see org.apache.lenya.cms.usecase.Usecase#getTargetURL(boolean)
568:             */
569:            public String getTargetURL(boolean success) {
570:                String url = getParameterAsString(EXIT_URI);
571:                if (url == null) {
572:                    url = getParameterAsString(DEFAULT_TARGET_URL);
573:                }
574:                if (url == null) {
575:                    url = getSourceURL();
576:                }
577:                return url + getExitQueryString();
578:            }
579:
580:            /**
581:             * @see org.apache.lenya.cms.usecase.Usecase#setPart(java.lang.String,
582:             *      org.apache.cocoon.servlet.multipart.Part)
583:             */
584:            public void setPart(String name, Part value) {
585:                if (!Part.class.isInstance(value)) {
586:                    String className = "";
587:                    if (value != null) {
588:                        className = value.getClass().getName();
589:                    }
590:                    throw new RuntimeException(
591:                            "["
592:                                    + name
593:                                    + "] = ("
594:                                    + className
595:                                    + ")  ["
596:                                    + value
597:                                    + "] is not a part object. Maybe you have to enable uploads?");
598:                }
599:                setParameter(name, value);
600:            }
601:
602:            /**
603:             * @see org.apache.lenya.cms.usecase.Usecase#getPart(java.lang.String)
604:             */
605:            public Part getPart(String name) {
606:                return (Part) getParameter(name);
607:            }
608:
609:            protected DocumentFactory getDocumentFactory() {
610:                DocumentFactory factory = (DocumentFactory) getParameter(PARAMETER_FACTORY);
611:                Session session = getSession();
612:                if (factory == null || factory.getSession() != session) {
613:                    factory = DocumentUtil.createDocumentFactory(this .manager,
614:                            session);
615:                    setParameter(PARAMETER_FACTORY, factory);
616:                }
617:                return factory;
618:            }
619:
620:            /**
621:             * @see org.apache.avalon.framework.activity.Initializable#initialize()
622:             */
623:            public final void initialize() throws Exception {
624:                Request request = ContextHelper.getRequest(this .context);
625:                Session session = RepositoryUtil.getSession(this .manager,
626:                        request);
627:                setSession(session);
628:                setParameter(PARAMETER_STATE_MACHINE, new StateMachine(MODEL));
629:            }
630:
631:            /**
632:             * Does the actual initialization. Template method.
633:             */
634:            protected final void doInitialize() {
635:            }
636:
637:            /**
638:             * @see org.apache.lenya.cms.usecase.Usecase#advance()
639:             */
640:            public void advance() throws UsecaseException {
641:                // do nothing
642:            }
643:
644:            /**
645:             * Deletes a parameter.
646:             * @param name The parameter name.
647:             */
648:            protected void deleteParameter(String name) {
649:                this .parameters.remove(name);
650:            }
651:
652:            private String name;
653:
654:            /**
655:             * @see org.apache.lenya.cms.usecase.Usecase#setName(java.lang.String)
656:             */
657:            public void setName(String name) {
658:                this .name = name;
659:            }
660:
661:            /**
662:             * @see org.apache.lenya.cms.usecase.Usecase#getName()
663:             */
664:            public String getName() {
665:                return this .name;
666:            }
667:
668:            /**
669:             * @see org.apache.lenya.cms.usecase.Usecase#getParameterNames()
670:             */
671:            public String[] getParameterNames() {
672:                initializeParametersIfNotDone();
673:                Set keys = this .parameters.keySet();
674:                return (String[]) keys.toArray(new String[keys.size()]);
675:            }
676:
677:            protected void initializeParametersIfNotDone() {
678:                if (this .parameters.get(PARAMETERS_INITIALIZED) == null) {
679:                    this .parameters.put(PARAMETERS_INITIALIZED, Boolean.TRUE);
680:                    initParameters();
681:                }
682:            }
683:
684:            /**
685:             * @see org.apache.lenya.cms.usecase.Usecase#setSourceURL(java.lang.String)
686:             */
687:            public void setSourceURL(String url) {
688:                setParameter(SOURCE_URL, url);
689:            }
690:
691:            private UsecaseView view;
692:
693:            /**
694:             * @see org.apache.lenya.cms.usecase.Usecase#getView()
695:             */
696:            public UsecaseView getView() {
697:                try {
698:                    prepareView();
699:                } catch (Exception e) {
700:                    getLogger().error(
701:                            "View preparation for usecase [" + getName()
702:                                    + "] failed: ", e);
703:                    addErrorMessage(e.getMessage());
704:                }
705:                return this .view;
706:            }
707:
708:            /**
709:             * Override this method to prepare the view (add information messages etc.).
710:             * @throws Exception If an error occurs.
711:             */
712:            protected void prepareView() throws Exception {
713:            }
714:
715:            protected static final String ELEMENT_PARAMETER = "parameter";
716:            protected static final String ATTRIBUTE_NAME = "name";
717:            protected static final String ATTRIBUTE_VALUE = "value";
718:            protected static final String ELEMENT_VIEW = "view";
719:            protected static final String ELEMENT_TRANSACTION = "transaction";
720:            protected static final String ATTRIBUTE_POLICY = "policy";
721:            protected static final String VALUE_OPTIMISTIC = "optimistic";
722:            protected static final String VALUE_PESSIMISTIC = "pessimistic";
723:            protected static final String ELEMENT_EXIT = "exit";
724:            protected static final String ATTRIBUTE_USECASE = "usecase";
725:
726:            private boolean isOptimistic = true;
727:
728:            /**
729:             * @return <code>true</code> if the transaction policy is optimistic offline lock,
730:             *         <code>false</code> if it is pessimistic offline lock.
731:             */
732:            public boolean isOptimistic() {
733:                return this .isOptimistic;
734:            }
735:
736:            /**
737:             * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
738:             */
739:            public void configure(Configuration config)
740:                    throws ConfigurationException {
741:
742:                Configuration[] parameterConfigs = config
743:                        .getChildren(ELEMENT_PARAMETER);
744:                for (int i = 0; i < parameterConfigs.length; i++) {
745:                    String name = parameterConfigs[i]
746:                            .getAttribute(ATTRIBUTE_NAME);
747:                    String value = parameterConfigs[i]
748:                            .getAttribute(ATTRIBUTE_VALUE);
749:                    setParameter(name, value);
750:                }
751:
752:                Configuration viewConfig = config.getChild(ELEMENT_VIEW, false);
753:                if (viewConfig != null) {
754:                    this .view = new UsecaseView();
755:                    try {
756:                        view.service(this .manager);
757:                    } catch (ServiceException e) {
758:                        throw new ConfigurationException(
759:                                "Couldn't service view: ", e);
760:                    }
761:                    view.configure(viewConfig);
762:                }
763:
764:                Configuration transactionConfig = config.getChild(
765:                        ELEMENT_TRANSACTION, false);
766:                if (transactionConfig != null) {
767:                    String policy = transactionConfig
768:                            .getAttribute(ATTRIBUTE_POLICY);
769:                    if (policy.equals(VALUE_PESSIMISTIC)) {
770:                        this .isOptimistic = false;
771:                    }
772:                }
773:
774:                Configuration exitConfig = config.getChild(ELEMENT_EXIT, false);
775:                if (exitConfig != null) {
776:                    this .exitUsecaseName = exitConfig
777:                            .getAttribute(ATTRIBUTE_USECASE);
778:                    Configuration[] exitParameterConfigs = exitConfig
779:                            .getChildren(ELEMENT_PARAMETER);
780:                    for (int i = 0; i < exitParameterConfigs.length; i++) {
781:                        String name = exitParameterConfigs[i]
782:                                .getAttribute(ATTRIBUTE_NAME);
783:                        String value = null;
784:                        String[] attributeNames = exitParameterConfigs[i]
785:                                .getAttributeNames();
786:                        for (int j = 0; j < attributeNames.length; j++) {
787:                            if (attributeNames[j].equals(ATTRIBUTE_VALUE))
788:                                value = exitParameterConfigs[i]
789:                                        .getAttribute(ATTRIBUTE_VALUE);
790:                        }
791:                        setExitParameter(name, value);
792:                    }
793:                }
794:            }
795:
796:            /**
797:             * @see org.apache.lenya.cms.usecase.Usecase#setView(org.apache.lenya.cms.usecase.UsecaseView)
798:             */
799:            public void setView(UsecaseView view) {
800:                this .view = view;
801:            }
802:
803:            /**
804:             * @return The objects that could be changed during the usecase.
805:             * @throws UsecaseException if an error occurs.
806:             */
807:            protected Node[] getNodesToLock() throws UsecaseException {
808:                return new Node[0];
809:            }
810:
811:            /**
812:             * <p>
813:             * This method starts the transaction and locks all involved objects immediately.
814:             * This way, all changes to the objects in the session occur after the locking,
815:             * avoiding overriding changes of other sessions.
816:             * </p>
817:             * <p>
818:             * This method is locked via the class lock to avoid inter-usecase synchronization issues.
819:             * </p>
820:             * @see org.apache.lenya.cms.usecase.Usecase#lockInvolvedObjects()
821:             */
822:            public final void lockInvolvedObjects() throws UsecaseException {
823:                try {
824:                    startTransaction();
825:                } catch (RepositoryException e) {
826:                    throw new UsecaseException(e);
827:                }
828:                synchronized (TransactionLock.LOCK) {
829:                    lockInvolvedObjects(getNodesToLock());
830:                }
831:                advanceState("lockInvolvedObjects");
832:            }
833:
834:            /**
835:             * Start a transaction by using a new, modifiable session.
836:             * @throws RepositoryException if an error occurs.
837:             */
838:            protected void startTransaction() throws RepositoryException {
839:                if (this .commitEnabled) {
840:                    setSession(RepositoryUtil.createSession(this .manager,
841:                            getSession().getIdentity(), true));
842:                }
843:            }
844:
845:            /**
846:             * <p>
847:             * Lock the objects, for example when you need to change them (for example, delete). If you know
848:             * when entering the usecase what these objects are, you do not need to call this, the framework
849:             * will take of it if you implement getObjectsToLock(). If you do not know in advance what the
850:             * objects are, you can call this method explicitly when appropriate.
851:             * </p>
852:             * 
853:             * @param objects the transactionable objects to lock
854:             * @throws UsecaseException if an error occurs.
855:             * @see #lockInvolvedObjects()
856:             * @see #getNodesToLock()
857:             */
858:            public final void lockInvolvedObjects(Node[] objects)
859:                    throws UsecaseException {
860:                try {
861:                    for (int i = 0; i < objects.length; i++) {
862:                        if (!objects[i].isLocked()) {
863:                            objects[i].lock();
864:                        }
865:                        if (!isOptimistic()
866:                                && !objects[i]
867:                                        .isCheckedOutBySession(getSession())) {
868:                            objects[i].checkout(checkoutRestrictedToSession());
869:                        }
870:                    }
871:                } catch (RepositoryException e) {
872:                    throw new UsecaseException(e);
873:                }
874:            }
875:
876:            protected boolean canCheckOut(Node[] objects)
877:                    throws RepositoryException {
878:                boolean canExecute = true;
879:
880:                for (int i = 0; i < objects.length; i++) {
881:                    if (objects[i].isCheckedOut()
882:                            && !objects[i].isCheckedOutBySession(getSession())) {
883:                        if (getLogger().isDebugEnabled()) {
884:                            getLogger().debug(
885:                                    "AbstractUsecase::lockInvolvedObjects() can not execute, object ["
886:                                            + objects[i]
887:                                            + "] is already checked out");
888:                        }
889:                        canExecute = false;
890:                    }
891:                }
892:                return canExecute;
893:            }
894:
895:            /**
896:             * @see org.apache.lenya.cms.usecase.Usecase#cancel()
897:             */
898:            public void cancel() throws UsecaseException {
899:                if (getSession().isModifiable()) {
900:                    try {
901:                        getSession().rollback();
902:                    } catch (Exception e) {
903:                        throw new UsecaseException(e);
904:                    }
905:                }
906:            }
907:
908:            private String exitUsecaseName = null;
909:            private Map exitUsecaseParameters = new HashMap();
910:
911:            /**
912:             * Sets a parameter to pass to the exit usecase.
913:             * @param name The parameter name.
914:             * @param value The parameter value.
915:             */
916:            protected void setExitParameter(String name, String value) {
917:                this .exitUsecaseParameters.put(name, value);
918:            }
919:
920:            /**
921:             * Returns the query string to access the exit usecase of this usecase.
922:             * @return A query string of the form
923:             *         <code>?lenya.usecase=...&amp;param1=foo&amp;param2=bar</code>.
924:             */
925:            protected String getExitQueryString() {
926:                StringBuffer queryBuffer = new StringBuffer();
927:                if (this .exitUsecaseName != null) {
928:                    queryBuffer.append("?lenya.usecase=").append(
929:                            this .exitUsecaseName);
930:                    for (Iterator i = this .exitUsecaseParameters.keySet()
931:                            .iterator(); i.hasNext();) {
932:                        String key = (String) i.next();
933:                        String value = (String) this .exitUsecaseParameters
934:                                .get(key);
935:                        queryBuffer.append("&").append(key).append("=").append(
936:                                value);
937:                    }
938:                } else {
939:                    String exitUsecase = getParameterAsString("lenya.exitUsecase");
940:                    if (exitUsecase != null && !"".equals(exitUsecase)) {
941:                        queryBuffer.append("?lenya.usecase=").append(
942:                                exitUsecase);
943:                    }
944:                }
945:                return queryBuffer.toString();
946:            }
947:
948:            public Session getSession() {
949:                return (Session) getParameter(PARAMETER_SESSION);
950:            }
951:
952:            protected Context context;
953:
954:            /**
955:             * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
956:             */
957:            public void contextualize(Context context) throws ContextException {
958:                this .context = context;
959:            }
960:
961:            protected ServiceManager manager;
962:
963:            public void service(ServiceManager manager) throws ServiceException {
964:                this .manager = manager;
965:            }
966:
967:            protected void setSession(
968:                    org.apache.lenya.cms.repository.Session session) {
969:                setParameter(PARAMETER_SESSION, session);
970:            }
971:
972:            private boolean commitEnabled = true;
973:
974:            public void setTestSession(Session session) {
975:                this .commitEnabled = false;
976:                setSession(session);
977:            }
978:
979:            protected boolean checkoutRestrictedToSession() {
980:                return getParameterAsBoolean(
981:                        PARAMETER_CHECKOUT_RESTRICTED_TO_SESSION, true);
982:            }
983:
984:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.