Source Code Cross Referenced for ModelProcessor.java in  » UML » AndroMDA-3.2 » org » andromda » core » engine » 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 » UML » AndroMDA 3.2 » org.andromda.core.engine 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.andromda.core.engine;
002:
003:        import java.text.Collator;
004:        import java.util.ArrayList;
005:        import java.util.Arrays;
006:        import java.util.Collection;
007:        import java.util.Collections;
008:        import java.util.Comparator;
009:        import java.util.Iterator;
010:        import java.util.LinkedHashMap;
011:        import java.util.List;
012:        import java.util.Map;
013:
014:        import org.andromda.core.ModelValidationException;
015:        import org.andromda.core.cartridge.Cartridge;
016:        import org.andromda.core.common.AndroMDALogger;
017:        import org.andromda.core.common.BuildInformation;
018:        import org.andromda.core.common.ComponentContainer;
019:        import org.andromda.core.common.ExceptionRecorder;
020:        import org.andromda.core.common.Introspector;
021:        import org.andromda.core.common.ResourceWriter;
022:        import org.andromda.core.common.XmlObjectFactory;
023:        import org.andromda.core.configuration.Configuration;
024:        import org.andromda.core.configuration.Filters;
025:        import org.andromda.core.configuration.Model;
026:        import org.andromda.core.configuration.Namespace;
027:        import org.andromda.core.configuration.Namespaces;
028:        import org.andromda.core.configuration.Property;
029:        import org.andromda.core.metafacade.MetafacadeFactory;
030:        import org.andromda.core.metafacade.ModelAccessFacade;
031:        import org.andromda.core.metafacade.ModelValidationMessage;
032:        import org.andromda.core.namespace.NamespaceComponents;
033:        import org.andromda.core.repository.Repositories;
034:        import org.apache.commons.collections.comparators.ComparatorChain;
035:        import org.apache.commons.lang.StringUtils;
036:        import org.apache.log4j.Logger;
037:
038:        /**
039:         * <p>
040:         * Handles the processing of models. Facilitates Model Driven
041:         * Architecture by enabling the generation of source code, configuration files, and other such artifacts from a single
042:         * or multiple models. </p>
043:         *
044:         * @author Chad Brandon
045:         */
046:        public class ModelProcessor {
047:            /**
048:             * The logger instance.
049:             */
050:            private static final Logger logger = Logger
051:                    .getLogger(ModelProcessor.class);
052:
053:            /**
054:             * Creates a new instance the ModelProcessor.
055:             *
056:             * @return the shared ModelProcessor instance.
057:             */
058:            public static ModelProcessor newInstance() {
059:                return new ModelProcessor();
060:            }
061:
062:            private ModelProcessor() {
063:                // - do not allow instantiation
064:            }
065:
066:            /**
067:             * Re-configures this model processor from the given <code>configuration</code>
068:             * instance (if different from that of the one passed in during the call to
069:             * {@link #initialize(Configuration)}), and runs the model processor.
070:             *
071:             * @param configuration the configuration from which to configure this model
072:             *        processor instance.
073:             * @return any model validation messages collected during model processing (if
074:             *         model validation is enabled).
075:             */
076:            public ModelValidationMessage[] process(
077:                    final Configuration configuration) {
078:                this .configure(configuration);
079:                final List messages = this .process(configuration
080:                        .getRepositories());
081:                return messages != null ? (ModelValidationMessage[]) messages
082:                        .toArray(new ModelValidationMessage[0])
083:                        : new ModelValidationMessage[0];
084:            }
085:
086:            /**
087:             * Configures (or re-configures) the model processor if configuration
088:             * is required (the configuration has changed since the previous, or has
089:             * yet to be used).
090:             *
091:             * @param configuration the AndroMDA configuration instance.
092:             */
093:            private void configure(final Configuration configuration) {
094:                if (this .requiresConfiguration(configuration)) {
095:                    configuration.initialize();
096:                    this .reset();
097:                    final Property[] properties = configuration.getProperties();
098:                    final int propertyNumber = properties.length;
099:                    final Introspector introspector = Introspector.instance();
100:                    for (int ctr = 0; ctr < propertyNumber; ctr++) {
101:                        final Property property = properties[ctr];
102:                        try {
103:                            introspector.setProperty(this , property.getName(),
104:                                    property.getValue());
105:                        } catch (final Throwable throwable) {
106:                            AndroMDALogger
107:                                    .warn("Could not set model processor property '"
108:                                            + property.getName()
109:                                            + "' with a value of '"
110:                                            + property.getValue() + "'");
111:                        }
112:                    }
113:                    this .currentConfiguration = configuration;
114:                }
115:            }
116:
117:            /**
118:             * Processes all models contained within the <code>repositories</code>
119:             * with the discovered cartridges.
120:             *
121:             * @return any model validation messages that may have been collected during model loading/validation.
122:             */
123:            private List process(
124:                    final org.andromda.core.configuration.Repository[] repositories) {
125:                List messages = null;
126:                final long startTime = System.currentTimeMillis();
127:                final int repositoryNumber = repositories.length;
128:                for (int ctr = 0; ctr < repositoryNumber; ctr++) {
129:                    final org.andromda.core.configuration.Repository repository = repositories[ctr];
130:                    if (repository != null) {
131:                        final String repositoryName = repository.getName();
132:
133:                        // - filter out any invalid models (ones that don't have any uris defined)
134:                        final Model[] models = this 
135:                                .filterInvalidModels(repository.getModels());
136:                        if (models.length > 0) {
137:                            messages = this .processModels(repositoryName,
138:                                    models);
139:                            AndroMDALogger
140:                                    .info("completed model processing --> TIME: "
141:                                            + this 
142:                                                    .getDurationInSeconds(startTime)
143:                                            + "[s], RESOURCES WRITTEN: "
144:                                            + ResourceWriter.instance()
145:                                                    .getWrittenCount());
146:                        } else {
147:                            AndroMDALogger
148:                                    .warn("No model(s) found to process for repository '"
149:                                            + repositoryName + "'");
150:                        }
151:                    }
152:                }
153:                return messages == null ? Collections.EMPTY_LIST : messages;
154:            }
155:
156:            /**
157:             * The shared metafacade factory instance.
158:             */
159:            private final MetafacadeFactory factory = MetafacadeFactory
160:                    .getInstance();
161:
162:            /**
163:             * The shared namespaces instance.
164:             */
165:            private final Namespaces namespaces = Namespaces.instance();
166:
167:            /**
168:             * The shared repositories instance.
169:             */
170:            private final Repositories repositories = Repositories.instance();
171:
172:            /**
173:             * Processes multiple <code>models</code>.
174:             *
175:             * @param repositoryName the name of the repository that loads/reads the model.
176:             * @param models the Model(s) to process.
177:             * @return any model validation messages that may have been collected during validation/loading of
178:             *         the <code>models</code>.
179:             */
180:            private List processModels(final String repositoryName,
181:                    final Model[] models) {
182:                List messages = null;
183:                String cartridgeName = null;
184:                try {
185:                    boolean lastModifiedCheck = true;
186:                    long lastModified = 0;
187:                    final ResourceWriter writer = ResourceWriter.instance();
188:
189:                    // - get the time from the model that has the latest modified time
190:                    for (int ctr = 0; ctr < models.length; ctr++) {
191:                        final Model model = models[ctr];
192:                        writer.resetHistory(model.getUris()[0]);
193:                        lastModifiedCheck = model.isLastModifiedCheck()
194:                                && lastModifiedCheck;
195:
196:                        // - we go off the model that was most recently modified.
197:                        if (model.getLastModified() > lastModified) {
198:                            lastModified = model.getLastModified();
199:                        }
200:                    }
201:
202:                    if (!lastModifiedCheck
203:                            || writer.isHistoryBefore(lastModified)) {
204:                        final Collection cartridges = ComponentContainer
205:                                .instance().findComponentsOfType(
206:                                        Cartridge.class);
207:                        if (cartridges.isEmpty()) {
208:                            AndroMDALogger
209:                                    .warn("WARNING! No cartridges found, check your classpath!");
210:                        }
211:
212:                        final Map cartridgesByNamespace = this 
213:                                .loadCartridgesByNamespace(cartridges);
214:
215:                        // - we want to process by namespace so that the order within the configuration is kept
216:                        final Collection namespaces = this .namespaces
217:                                .getNamespaces();
218:
219:                        // - pre-load the models
220:                        messages = this .loadIfNecessary(models);
221:                        for (final Iterator iterator = namespaces.iterator(); iterator
222:                                .hasNext();) {
223:                            final Namespace namespace = (Namespace) iterator
224:                                    .next();
225:                            final Cartridge cartridge = (Cartridge) cartridgesByNamespace
226:                                    .get(namespace.getName());
227:                            if (cartridge != null) {
228:                                cartridgeName = cartridge.getNamespace();
229:                                if (this .shouldProcess(cartridgeName)) {
230:                                    // - set the active namespace on the shared factory and profile instances
231:                                    this .factory.setNamespace(cartridgeName);
232:                                    cartridge.initialize();
233:
234:                                    // - process each model with the cartridge
235:                                    for (int ctr = 0; ctr < models.length; ctr++) {
236:                                        final Model model = models[ctr];
237:
238:                                        // - set the namespace on the metafacades instance so we know the 
239:                                        //   correct facades to use
240:                                        this .factory.setModel(this .repositories
241:                                                .getImplementation(
242:                                                        repositoryName)
243:                                                .getModel(), model.getType());
244:                                        cartridge
245:                                                .processModelElements(this .factory);
246:                                        writer.writeHistory();
247:                                    }
248:                                    cartridge.shutdown();
249:                                }
250:                            }
251:                        }
252:                    }
253:                } catch (final ModelValidationException exception) {
254:                    // - we don't want to record model validation exceptions
255:                    throw exception;
256:                } catch (final Throwable throwable) {
257:                    final String messsage = "Error performing ModelProcessor.process with model(s) --> '"
258:                            + StringUtils.join(models, ",") + "'";
259:                    logger.error(messsage);
260:                    ExceptionRecorder.instance().record(messsage, throwable,
261:                            cartridgeName);
262:                    throw new ModelProcessorException(messsage, throwable);
263:                }
264:                return messages == null ? Collections.EMPTY_LIST : messages;
265:            }
266:
267:            /**
268:             * Loads the given list of <code>cartridges</code> into a map keyed by namespace.
269:             * 
270:             * @param cartridges the cartridges loaded.
271:             * @return the loaded cartridge map.
272:             */
273:            private Map loadCartridgesByNamespace(final Collection cartridges) {
274:                final Map cartridgesByNamespace = new LinkedHashMap();
275:                for (final Iterator iterator = cartridges.iterator(); iterator
276:                        .hasNext();) {
277:                    final Cartridge cartridge = (Cartridge) iterator.next();
278:                    cartridgesByNamespace.put(cartridge.getNamespace(),
279:                            cartridge);
280:                }
281:                return cartridgesByNamespace;
282:            }
283:
284:            /**
285:             * Initializes this model processor instance with the given
286:             * configuration.  This configuration information is overridden (if changed)
287:             * when calling {@link #process(Configuration)}
288:             *
289:             * @param configuration the configuration instance by which to initialize this
290:             *        model processor instance.
291:             */
292:            public void initialize(final Configuration configuration) {
293:                final long startTime = System.currentTimeMillis();
294:
295:                // - first, print the AndroMDA header
296:                this .printConsoleHeader();
297:
298:                // - second, configure this model processor 
299:                // - the ordering of this step is important: it needs to occur
300:                //   before everything else in the framework is initialized so that 
301:                //   we have all configuration information available (such as the
302:                //   namespace properties)
303:                this .configure(configuration);
304:
305:                // - the logger configuration may have changed - re-init the logger.
306:                AndroMDALogger.initialize();
307:
308:                // - discover all namespace components
309:                NamespaceComponents.instance().discover();
310:
311:                // - find and initialize any repositories
312:                repositories.initialize();
313:
314:                // - finally initialize the metafacade factory
315:                this .factory.initialize();
316:                this .printWorkCompleteMessage("core initialization", startTime);
317:            }
318:
319:            /**
320:             * Loads the model into the repository only when necessary (the model has a timestamp
321:             * later than the last timestamp of the loaded model).
322:             *
323:             * @param model the model to be loaded.
324:             */
325:            protected final List loadModelIfNecessary(final Model model) {
326:                final List validationMessages = new ArrayList();
327:                final long startTime = System.currentTimeMillis();
328:                if (this .repositories.loadModel(model)) {
329:                    this .printWorkCompleteMessage("loading", startTime);
330:
331:                    // - validate the model since loading has successfully occurred
332:                    final org.andromda.core.configuration.Repository repository = model
333:                            .getRepository();
334:                    final String repositoryName = repository != null ? repository
335:                            .getName()
336:                            : null;
337:                    validationMessages.addAll(this .validateModel(
338:                            repositoryName, model));
339:                }
340:                return validationMessages;
341:            }
342:
343:            /**
344:             * Validates the entire model with each cartridge namespace,
345:             * and returns any validation messages that occurred during validation
346:             * (also logs any validation failures).
347:             *
348:             * @param repositoryName the name of the repository storing the model to validate.
349:             * @return any {@link ModelValidationMessage} instances that may have been collected
350:             *         during validation.
351:             */
352:            private List validateModel(final String repositoryName,
353:                    final Model model) {
354:                final Filters constraints = model != null ? model
355:                        .getConstraints() : null;
356:                final List validationMessages = new ArrayList();
357:                if (this .modelValidation) {
358:                    final long startTime = System.currentTimeMillis();
359:                    AndroMDALogger.info("- validating model -");
360:                    final Collection cartridges = ComponentContainer.instance()
361:                            .findComponentsOfType(Cartridge.class);
362:                    final ModelAccessFacade modelAccessFacade = this .repositories
363:                            .getImplementation(repositoryName).getModel();
364:
365:                    // - clear out the factory's caches (such as any previous validation messages, etc.)
366:                    this .factory.clearCaches();
367:                    this .factory.setModel(modelAccessFacade, model.getType());
368:                    for (final Iterator iterator = cartridges.iterator(); iterator
369:                            .hasNext();) {
370:                        final Cartridge cartridge = (Cartridge) iterator.next();
371:                        final String cartridgeName = cartridge.getNamespace();
372:                        if (this .shouldProcess(cartridgeName)) {
373:                            // - set the active namespace on the shared factory and profile instances
374:                            this .factory.setNamespace(cartridgeName);
375:                            this .factory.validateAllMetafacades();
376:                        }
377:                    }
378:                    final List messages = this .factory.getValidationMessages();
379:                    this .filterAndSortValidationMessages(messages, constraints);
380:                    this .printValidationMessages(messages);
381:                    this .printWorkCompleteMessage("validation", startTime);
382:                    if (messages != null && !messages.isEmpty()) {
383:                        validationMessages.addAll(messages);
384:                    }
385:                }
386:                return validationMessages;
387:            }
388:
389:            /**
390:             * Prints a work complete message using the type of <code>unitOfWork</code> and
391:             * <code>startTime</code> as input.
392:             * @param unitOfWork the type of unit of work that was completed
393:             * @param startTime the time the unit of work was started.
394:             */
395:            private void printWorkCompleteMessage(final String unitOfWork,
396:                    final long startTime) {
397:                AndroMDALogger.info("- " + unitOfWork + " complete: "
398:                        + this .getDurationInSeconds(startTime) + "[s] -");
399:            }
400:
401:            /**
402:             * Calcuates the duration in seconds between the
403:             * given <code>startTime</code> and the current time.
404:             * @param startTime the time to compare against.
405:             * @return the duration of time in seconds.
406:             */
407:            private double getDurationInSeconds(final long startTime) {
408:                return ((System.currentTimeMillis() - startTime) / 1000.0);
409:            }
410:
411:            /**
412:             * Prints any model validation errors stored within the <code>factory</code>.
413:             */
414:            private void printValidationMessages(final List messages) {
415:                // - log all error messages
416:                if (messages != null && !messages.isEmpty()) {
417:                    final StringBuffer header = new StringBuffer(
418:                            "Model Validation Failed - " + messages.size()
419:                                    + " VALIDATION ERROR");
420:                    if (messages.size() > 1) {
421:                        header.append("S");
422:                    }
423:                    AndroMDALogger.error(header);
424:                    final Iterator iterator = messages.iterator();
425:                    for (int ctr = 1; iterator.hasNext(); ctr++) {
426:                        final ModelValidationMessage message = (ModelValidationMessage) iterator
427:                                .next();
428:                        AndroMDALogger.error(ctr + ") " + message);
429:                    }
430:                    AndroMDALogger.reset();
431:                    if (this .failOnValidationErrors) {
432:                        throw new ModelValidationException(
433:                                "Model validation failed!");
434:                    }
435:                }
436:            }
437:
438:            /**
439:             * The current configuration of this model processor.
440:             */
441:            private Configuration currentConfiguration = null;
442:
443:            /**
444:             * Determines whether or not this model processor needs to be reconfigured.
445:             * This is based on whether or not the new configuration is different
446:             * than the <code>currentConfiguration</code>.  We determine this checking
447:             * if their contents are equal or not, if not equal this method will
448:             * return true, otherwise false.
449:             *
450:             * @param configuration the configuration to compare to the lastConfiguration.
451:             * @return true/false
452:             */
453:            private boolean requiresConfiguration(
454:                    final Configuration configuration) {
455:                boolean requiresConfiguration = this .currentConfiguration == null
456:                        || this .currentConfiguration.getContents() == null
457:                        || configuration.getContents() == null;
458:                if (!requiresConfiguration) {
459:                    requiresConfiguration = !this .currentConfiguration
460:                            .getContents().equals(configuration.getContents());
461:                }
462:                return requiresConfiguration;
463:            }
464:
465:            /**
466:             * Checks to see if <em>any</em> of the repositories contain models
467:             * that need to be reloaded, and if so, re-loads them.
468:             *
469:             * @param repositories the repositories from which to load the model(s).
470:             */
471:            final List loadIfNecessary(
472:                    final org.andromda.core.configuration.Repository[] repositories) {
473:                final List messages = new ArrayList();
474:                if (repositories != null && repositories.length > 0) {
475:                    final int repositoryNumber = repositories.length;
476:                    for (int repositoryCtr = 0; repositoryCtr < repositoryNumber; repositoryCtr++) {
477:                        final org.andromda.core.configuration.Repository repository = repositories[repositoryCtr];
478:                        if (repository != null) {
479:                            messages.addAll(this .loadIfNecessary(repository
480:                                    .getModels()));
481:                        }
482:                    }
483:                }
484:                return messages;
485:            }
486:
487:            /**
488:             * Checks to see if <em>any</em> of the models need to be reloaded, and if so, re-loads them.
489:             *
490:             * @param models that will be loaded (if necessary).
491:             * @return any validation messages collected during loading.
492:             */
493:            private List loadIfNecessary(final Model[] models) {
494:                final List messages = new ArrayList();
495:                if (models != null && models.length > 0) {
496:                    final int modelNumber = models.length;
497:                    for (int modelCtr = 0; modelCtr < modelNumber; modelCtr++) {
498:                        messages.addAll(this 
499:                                .loadModelIfNecessary(models[modelCtr]));
500:                    }
501:                }
502:                return messages;
503:            }
504:
505:            /**
506:             * Stores the current version of AndroMDA.
507:             */
508:            private static final String VERSION = BuildInformation.instance()
509:                    .getBuildVersion();
510:
511:            /**
512:             * Prints the console header.
513:             */
514:            protected void printConsoleHeader() {
515:                AndroMDALogger.info("");
516:                AndroMDALogger.info("A n d r o M D A  -  " + VERSION);
517:                AndroMDALogger.info("");
518:            }
519:
520:            /**
521:             * Whether or not model validation should be performed.
522:             */
523:            private boolean modelValidation = true;
524:
525:            /**
526:             * Sets whether or not model validation should occur. This is useful for
527:             * performance reasons (i.e. if you have a large model it can significatly descrease the amount of time it takes for
528:             * AndroMDA to process a model). By default this is set to <code>true</code>.
529:             *
530:             * @param modelValidation true/false on whether model validation should be performed or not.
531:             */
532:            public void setModelValidation(final boolean modelValidation) {
533:                this .modelValidation = modelValidation;
534:            }
535:
536:            /**
537:             * A flag indicating whether or not failure should occur
538:             * when model validation errors are present.
539:             */
540:            private boolean failOnValidationErrors = true;
541:
542:            /**
543:             * Sets whether or not processing should fail when validation errors occur, default is <code>true</code>.
544:             *
545:             * @param failOnValidationErrors whether or not processing should fail if any validation errors are present.
546:             */
547:            public void setFailOnValidationErrors(
548:                    final boolean failOnValidationErrors) {
549:                this .failOnValidationErrors = failOnValidationErrors;
550:            }
551:
552:            /**
553:             * Stores the cartridge filter.
554:             */
555:            private List cartridgeFilter = null;
556:
557:            /**
558:             * Denotes whether or not the complement of filtered cartridges should be processed
559:             */
560:            private boolean negateCartridgeFilter = false;
561:
562:            /**
563:             * Indicates whether or not the <code>namespace</code> should be processed. This is determined in conjunction with
564:             * {@link #setCartridgeFilter(String)}. If the <code>cartridgeFilter</code> is not defined and the namespace is
565:             * present within the configuration, then this method will <strong>ALWAYS </strong> return true.
566:             *
567:             * @param namespace the name of the namespace to check whether or not it should be processed.
568:             * @return true/false on whether or not it should be processed.
569:             */
570:            protected boolean shouldProcess(final String namespace) {
571:                boolean shouldProcess = this .namespaces
572:                        .namespacePresent(namespace);
573:                if (shouldProcess) {
574:                    shouldProcess = this .cartridgeFilter == null
575:                            || this .cartridgeFilter.isEmpty();
576:                    if (!shouldProcess) {
577:                        shouldProcess = this .negateCartridgeFilter
578:                                ^ this .cartridgeFilter.contains(StringUtils
579:                                        .trimToEmpty(namespace));
580:                    }
581:                }
582:                return shouldProcess;
583:            }
584:
585:            /**
586:             * The prefix used for cartridge filter negation.
587:             */
588:            private static final String CARTRIDGE_FILTER_NEGATOR = "~";
589:
590:            /**
591:             * <p/>
592:             * Sets the current cartridge filter. This is a comma seperated list of namespaces (matching cartridges names) that
593:             * should be processed. </p>
594:             * <p/>
595:             * If this filter is defined, then any cartridge names found in this list <strong>will be processed </strong>, while
596:             * any other discovered cartridges <strong>will not be processed </strong>. </p>
597:             *
598:             * @param namespaces a comma seperated list of the cartridge namespaces to be processed.
599:             */
600:            public void setCartridgeFilter(String namespaces) {
601:                if (namespaces != null) {
602:                    namespaces = StringUtils.deleteWhitespace(namespaces);
603:                    if (namespaces.startsWith(CARTRIDGE_FILTER_NEGATOR)) {
604:                        this .negateCartridgeFilter = true;
605:                        namespaces = namespaces.substring(1);
606:                    } else {
607:                        this .negateCartridgeFilter = false;
608:                    }
609:                    if (StringUtils.isNotBlank(namespaces)) {
610:                        this .cartridgeFilter = Arrays.asList(namespaces
611:                                .split(","));
612:                    }
613:                }
614:            }
615:
616:            /**
617:             * Sets the encoding (UTF-8, ISO-8859-1, etc) for all output
618:             * produced during model processing.
619:             *
620:             * @param outputEncoding the encoding.
621:             */
622:            public void setOutputEncoding(final String outputEncoding) {
623:                ResourceWriter.instance().setEncoding(outputEncoding);
624:            }
625:
626:            /**
627:             * Sets <code>xmlValidation</code> to be true/false. This defines whether XML resources loaded by AndroMDA (such as
628:             * plugin descriptors) should be validated. Sometimes underlying parsers don't support XML Schema validation and in
629:             * that case, we want to be able to turn it off.
630:             *
631:             * @param xmlValidation true/false on whether we should validate XML resources used by AndroMDA
632:             */
633:            public void setXmlValidation(final boolean xmlValidation) {
634:                XmlObjectFactory.setDefaultValidating(xmlValidation);
635:            }
636:
637:            /**
638:             * <p/>
639:             * Sets the <code>loggingConfigurationUri</code> for AndroMDA. This is the URI to an external logging configuration
640:             * file. This is useful when you want to override the default logging configuration of AndroMDA. </p>
641:             * <p/>
642:             * You can retrieve the default log4j.xml contained within the {@link org.andromda.core.common}package, customize
643:             * it, and then specify the location of this logging file with this operation. </p>
644:             *
645:             * @param loggingConfigurationUri the URI to the external logging configuation file.
646:             */
647:            public void setLoggingConfigurationUri(
648:                    final String loggingConfigurationUri) {
649:                AndroMDALogger
650:                        .setLoggingConfigurationUri(loggingConfigurationUri);
651:            }
652:
653:            /**
654:             * Filters out any <em>invalid</em> models. This means models that either are null within the specified
655:             * <code>models</code> array or those that don't have URLs set.
656:             *
657:             * @param models the models to filter.
658:             * @return the array of valid models
659:             */
660:            private Model[] filterInvalidModels(final Model[] models) {
661:                final Collection validModels = new ArrayList(Arrays
662:                        .asList(models));
663:                for (final Iterator iterator = validModels.iterator(); iterator
664:                        .hasNext();) {
665:                    final Model model = (Model) iterator.next();
666:                    if (!(model != null && model.getUris() != null && model
667:                            .getUris().length > 0)) {
668:                        iterator.remove();
669:                    }
670:                }
671:                return (Model[]) validModels.toArray(new Model[0]);
672:            }
673:
674:            /**
675:             * Shuts down the model processor (reclaims any
676:             * resources).
677:             */
678:            public void shutdown() {
679:                // - shutdown the metafacade factory instance
680:                this .factory.shutdown();
681:
682:                // - shutdown the configuration namespaces instance
683:                this .namespaces.clear();
684:
685:                // - shutdown the container instance
686:                ComponentContainer.instance().shutdown();
687:
688:                // - shutdown the namespace components registry
689:                NamespaceComponents.instance().shutdown();
690:
691:                // - shutdown the introspector
692:                Introspector.instance().shutdown();
693:
694:                // - clear out any caches used by the configuration
695:                Configuration.clearCaches();
696:
697:                // - clear out any repositories
698:                this .repositories.clear();
699:            }
700:
701:            /**
702:             * Reinitializes the model processor's resources.
703:             */
704:            private void reset() {
705:                this .factory.reset();
706:                this .cartridgeFilter = null;
707:                this .setXmlValidation(true);
708:                this .setOutputEncoding(null);
709:                this .setModelValidation(true);
710:                this .setLoggingConfigurationUri(null);
711:                this .setFailOnValidationErrors(true);
712:            }
713:
714:            /**
715:             * Filters out any messages that should not be applied according to the AndroMDA configuration's
716:             * constraints and sorts the resulting <code>messages</code> first by type (i.e. the metafacade class)
717:             * and then by the <code>name</code> of the model element to which the validation message applies.
718:             *
719:             * @param messages the collection of messages to sort.
720:             * @param constraints any constraint filters to apply to the validation messages.
721:             */
722:            protected void filterAndSortValidationMessages(final List messages,
723:                    final Filters constraints) {
724:                if (constraints != null) {
725:                    // - perform constraint filtering (if any applies)
726:                    for (final Iterator iterator = messages.iterator(); iterator
727:                            .hasNext();) {
728:                        final ModelValidationMessage message = (ModelValidationMessage) iterator
729:                                .next();
730:                        if (message != null
731:                                && !constraints.isApply(message.getName())) {
732:                            iterator.remove();
733:                        }
734:                    }
735:                }
736:
737:                if (messages != null && !messages.isEmpty()) {
738:                    final ComparatorChain chain = new ComparatorChain();
739:                    chain.addComparator(new ValidationMessageTypeComparator());
740:                    chain.addComparator(new ValidationMessageNameComparator());
741:                    Collections.sort(messages, chain);
742:                }
743:            }
744:
745:            /**
746:             * Used to sort validation messages by <code>metafacadeClass</code>.
747:             */
748:            private final static class ValidationMessageTypeComparator
749:                    implements  Comparator {
750:                private final Collator collator = Collator.getInstance();
751:
752:                ValidationMessageTypeComparator() {
753:                    collator.setStrength(Collator.PRIMARY);
754:                }
755:
756:                public int compare(final Object objectA, final Object objectB) {
757:                    final ModelValidationMessage a = (ModelValidationMessage) objectA;
758:                    final ModelValidationMessage b = (ModelValidationMessage) objectB;
759:                    return collator.compare(a.getMetafacadeClass().getName(), b
760:                            .getMetafacadeClass().getName());
761:                }
762:            }
763:
764:            /**
765:             * Used to sort validation messages by <code>modelElementName</code>.
766:             */
767:            private final static class ValidationMessageNameComparator
768:                    implements  Comparator {
769:                private final Collator collator = Collator.getInstance();
770:
771:                ValidationMessageNameComparator() {
772:                    collator.setStrength(Collator.PRIMARY);
773:                }
774:
775:                public int compare(final Object objectA, final Object objectB) {
776:                    final ModelValidationMessage a = (ModelValidationMessage) objectA;
777:                    final ModelValidationMessage b = (ModelValidationMessage) objectB;
778:                    return collator.compare(StringUtils.trimToEmpty(a
779:                            .getMetafacadeName()), StringUtils.trimToEmpty(b
780:                            .getMetafacadeName()));
781:                }
782:            }
783:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.