001: // Copyright 2004, 2005 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.hivemind.ant;
016:
017: import java.util.ArrayList;
018: import java.util.Collection;
019: import java.util.HashSet;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Set;
023:
024: import javax.xml.parsers.DocumentBuilder;
025: import javax.xml.parsers.DocumentBuilderFactory;
026: import javax.xml.parsers.ParserConfigurationException;
027:
028: import org.apache.hivemind.ApplicationRuntimeException;
029: import org.apache.hivemind.Attribute;
030: import org.apache.hivemind.ClassResolver;
031: import org.apache.hivemind.ErrorHandler;
032: import org.apache.hivemind.ModuleDescriptorProvider;
033: import org.apache.hivemind.Occurances;
034: import org.apache.hivemind.impl.DefaultClassResolver;
035: import org.apache.hivemind.impl.DefaultErrorHandler;
036: import org.apache.hivemind.impl.XmlModuleDescriptorProvider;
037: import org.apache.hivemind.internal.Visibility;
038: import org.apache.hivemind.parse.AttributeMappingDescriptor;
039: import org.apache.hivemind.parse.ConfigurationPointDescriptor;
040: import org.apache.hivemind.parse.ContributionDescriptor;
041: import org.apache.hivemind.parse.ConversionDescriptor;
042: import org.apache.hivemind.parse.CreateInstanceDescriptor;
043: import org.apache.hivemind.parse.DependencyDescriptor;
044: import org.apache.hivemind.parse.ImplementationDescriptor;
045: import org.apache.hivemind.parse.InstanceBuilder;
046: import org.apache.hivemind.parse.InterceptorDescriptor;
047: import org.apache.hivemind.parse.InvokeFactoryDescriptor;
048: import org.apache.hivemind.parse.ModuleDescriptor;
049: import org.apache.hivemind.parse.ServicePointDescriptor;
050: import org.apache.hivemind.parse.SubModuleDescriptor;
051: import org.apache.hivemind.schema.AttributeModel;
052: import org.apache.hivemind.schema.ElementModel;
053: import org.apache.hivemind.schema.Rule;
054: import org.apache.hivemind.schema.impl.SchemaImpl;
055: import org.apache.hivemind.schema.rules.CreateObjectRule;
056: import org.apache.hivemind.schema.rules.InvokeParentRule;
057: import org.apache.hivemind.schema.rules.PushAttributeRule;
058: import org.apache.hivemind.schema.rules.PushContentRule;
059: import org.apache.hivemind.schema.rules.ReadAttributeRule;
060: import org.apache.hivemind.schema.rules.ReadContentRule;
061: import org.apache.hivemind.schema.rules.SetModuleRule;
062: import org.apache.hivemind.schema.rules.SetParentRule;
063: import org.apache.hivemind.schema.rules.SetPropertyRule;
064: import org.apache.hivemind.util.IdUtils;
065: import org.w3c.dom.Document;
066: import org.w3c.dom.Element;
067:
068: /**
069: * This class serializes a set of {@link ModuleDescriptor module descriptors} into a
070: * {@link Document XML document}. The set of module descriptors to process is specified indirectly
071: * by supplying one or several {@link ModuleDescriptorProvider} (see
072: * {@link #addModuleDescriptorProvider(ModuleDescriptorProvider)}). In this respect this class is
073: * used the same way as {@link org.apache.hivemind.impl.RegistryBuilder}. There is even a
074: * corresponding {@link #createDefaultRegistryDocument() static method} to serialize the modules of
075: * the default registry.
076: * <p>
077: * The resulting XML file does not conform to the hivemind module deployment descriptor schema. The
078: * following changes occur:
079: * <ul>
080: * <li>The outermost element is <registry> (which contains a list of <module>)
081: * <li>A unique id (unique within the file) is assigned to each <module>,
082: * <configuration-point>, <service-point>, <contribution>, &tl;schema> and
083: * <implementation> (this is to make it easier to generate links and anchors)
084: * <li>Unqualified ids are converted to qualified ids (whereever possible).
085: * </ul>
086: *
087: * @author Knut Wannheden
088: * @since 1.1
089: */
090: public class RegistrySerializer {
091: private Set _processedSchemas = new HashSet();
092:
093: private List _providers = new ArrayList();
094:
095: private ErrorHandler _handler;
096:
097: private Document _document;
098:
099: private ModuleDescriptor _md;
100:
101: public RegistrySerializer() {
102: _handler = new DefaultErrorHandler();
103: }
104:
105: public void addModuleDescriptorProvider(
106: ModuleDescriptorProvider provider) {
107: _providers.add(provider);
108: }
109:
110: public Document createRegistryDocument() {
111: DocumentBuilder builder = getBuilder();
112:
113: _document = builder.newDocument();
114:
115: Element registry = _document.createElement("registry");
116:
117: _document.appendChild(registry);
118:
119: for (Iterator i = _providers.iterator(); i.hasNext();) {
120: ModuleDescriptorProvider provider = (ModuleDescriptorProvider) i
121: .next();
122:
123: processModuleDescriptorProvider(registry, provider);
124: }
125:
126: return _document;
127: }
128:
129: private void processModuleDescriptorProvider(Element registry,
130: ModuleDescriptorProvider provider) {
131: for (Iterator j = provider.getModuleDescriptors(_handler)
132: .iterator(); j.hasNext();) {
133: _md = (ModuleDescriptor) j.next();
134:
135: Element module = getModuleElement(_md);
136:
137: registry.appendChild(module);
138: }
139: }
140:
141: private Element getModuleElement(ModuleDescriptor md) {
142: Element module = _document.createElement("module");
143:
144: module.setAttribute("id", md.getModuleId());
145: module.setAttribute("version", md.getVersion());
146: module.setAttribute("package", md.getPackageName());
147:
148: module
149: .appendChild(_document.createTextNode(md
150: .getAnnotation()));
151:
152: addDependencies(module);
153:
154: addServicePoints(module);
155:
156: addConfigurationPoints(module);
157:
158: addContributions(module);
159:
160: addImplementations(module);
161:
162: addSchemas(module);
163:
164: addSubModules(module);
165:
166: return module;
167: }
168:
169: private void addDependencies(Element module) {
170: List dependencies = _md.getDependencies();
171:
172: if (dependencies != null) {
173: for (Iterator i = dependencies.iterator(); i.hasNext();) {
174: DependencyDescriptor dd = (DependencyDescriptor) i
175: .next();
176:
177: Element dependency = getDependencyElement(dd);
178:
179: module.appendChild(dependency);
180: }
181: }
182: }
183:
184: private void addServicePoints(Element module) {
185: List servicePoints = _md.getServicePoints();
186:
187: if (servicePoints != null) {
188: for (Iterator i = servicePoints.iterator(); i.hasNext();) {
189: ServicePointDescriptor spd = (ServicePointDescriptor) i
190: .next();
191:
192: Element servicePoint = getServicePointElement(spd);
193:
194: module.appendChild(servicePoint);
195:
196: SchemaImpl s = (SchemaImpl) spd.getParametersSchema();
197:
198: if (s != null && s.getId() != null)
199: addSchema(module, s, "schema");
200: }
201: }
202: }
203:
204: private void addConfigurationPoints(Element module) {
205: List configurationPoints = _md.getConfigurationPoints();
206:
207: if (configurationPoints != null) {
208: for (Iterator i = configurationPoints.iterator(); i
209: .hasNext();) {
210: ConfigurationPointDescriptor cpd = (ConfigurationPointDescriptor) i
211: .next();
212:
213: Element configurationPoint = getConfigurationPointElement(cpd);
214:
215: module.appendChild(configurationPoint);
216:
217: SchemaImpl s = (SchemaImpl) cpd
218: .getContributionsSchema();
219:
220: if (s != null && s.getId() != null)
221: addSchema(module, s, "schema");
222: }
223: }
224: }
225:
226: private void addContributions(Element module) {
227: List contributions = _md.getContributions();
228:
229: if (contributions != null) {
230: for (Iterator i = contributions.iterator(); i.hasNext();) {
231: ContributionDescriptor cd = (ContributionDescriptor) i
232: .next();
233:
234: Element contribution = getContributionElement(cd);
235:
236: module.appendChild(contribution);
237: }
238: }
239: }
240:
241: private void addImplementations(Element module) {
242: List implementations = _md.getImplementations();
243:
244: if (implementations != null) {
245: for (Iterator i = implementations.iterator(); i.hasNext();) {
246: ImplementationDescriptor id = (ImplementationDescriptor) i
247: .next();
248:
249: Element implementation = getImplementationElement(id);
250:
251: module.appendChild(implementation);
252: }
253: }
254: }
255:
256: private void addSchemas(Element module) {
257: Collection schemas = _md.getSchemas();
258:
259: for (Iterator i = schemas.iterator(); i.hasNext();) {
260: SchemaImpl s = (SchemaImpl) i.next();
261:
262: addSchema(module, s, "schema");
263: }
264: }
265:
266: private void addSubModules(Element module) {
267: List subModules = _md.getSubModules();
268:
269: if (subModules != null) {
270: for (Iterator i = subModules.iterator(); i.hasNext();) {
271: SubModuleDescriptor smd = (SubModuleDescriptor) i
272: .next();
273:
274: Element subModule = getSubModuleElement(smd);
275:
276: module.appendChild(subModule);
277: }
278: }
279: }
280:
281: private Element getDependencyElement(DependencyDescriptor dd) {
282: Element dependency = _document.createElement("dependency");
283:
284: dependency.setAttribute("module-id", dd.getModuleId());
285: dependency.setAttribute("version", dd.getVersion());
286:
287: return dependency;
288: }
289:
290: private Element getServicePointElement(ServicePointDescriptor spd) {
291: Element servicePoint = _document.createElement("service-point");
292:
293: servicePoint.setAttribute("id", qualify(spd.getId()));
294: servicePoint.setAttribute("interface", spd
295: .getInterfaceClassName());
296: if (spd.getVisibility() == Visibility.PRIVATE)
297: servicePoint.setAttribute("visibility", "private");
298: if (spd.getParametersCount() != Occurances.REQUIRED)
299: servicePoint.setAttribute("parameters-occurs", spd
300: .getParametersCount().getName().toLowerCase());
301:
302: servicePoint.appendChild(_document.createTextNode(spd
303: .getAnnotation()));
304:
305: if (spd.getParametersSchema() != null)
306: addSchema(servicePoint, (SchemaImpl) spd
307: .getParametersSchema(), "parameters-schema");
308: else if (spd.getParametersSchemaId() != null)
309: servicePoint.setAttribute("parameters-schema-id",
310: qualify(spd.getParametersSchemaId()));
311:
312: InstanceBuilder ib = spd.getInstanceBuilder();
313:
314: if (ib != null) {
315: Element instanceBuilder = getInstanceBuilderElement(ib);
316:
317: servicePoint.appendChild(instanceBuilder);
318: }
319:
320: List interceptors = spd.getInterceptors();
321:
322: if (interceptors != null) {
323: for (Iterator i = interceptors.iterator(); i.hasNext();) {
324: InterceptorDescriptor icd = (InterceptorDescriptor) i
325: .next();
326:
327: Element interceptor = getInterceptorElement(icd);
328:
329: servicePoint.appendChild(interceptor);
330: }
331: }
332:
333: return servicePoint;
334: }
335:
336: private Element getConfigurationPointElement(
337: ConfigurationPointDescriptor cpd) {
338: Element configurationPoint = _document
339: .createElement("configuration-point");
340:
341: configurationPoint.setAttribute("id", qualify(cpd.getId()));
342: if (cpd.getVisibility() == Visibility.PRIVATE)
343: configurationPoint.setAttribute("visibility", "private");
344:
345: configurationPoint.appendChild(_document.createTextNode(cpd
346: .getAnnotation()));
347:
348: if (cpd.getContributionsSchema() != null)
349: addSchema(configurationPoint, (SchemaImpl) cpd
350: .getContributionsSchema(), "schema");
351: else if (cpd.getContributionsSchemaId() != null)
352: configurationPoint.setAttribute("schema-id", qualify(cpd
353: .getContributionsSchemaId()));
354:
355: return configurationPoint;
356: }
357:
358: private Element getContributionElement(ContributionDescriptor cd) {
359: Element contribution = _document.createElement("contribution");
360:
361: contribution.setAttribute("configuration-id", qualify(cd
362: .getConfigurationId()));
363:
364: if (cd.getConditionalExpression() != null)
365: contribution.setAttribute("if", cd
366: .getConditionalExpression());
367:
368: List parameters = cd.getElements();
369:
370: if (parameters != null) {
371: for (Iterator i = parameters.iterator(); i.hasNext();) {
372: org.apache.hivemind.Element parameter = (org.apache.hivemind.Element) i
373: .next();
374:
375: Element element = getParamterElement(parameter);
376:
377: contribution.appendChild(element);
378: }
379: }
380:
381: contribution.appendChild(_document.createTextNode(cd
382: .getAnnotation()));
383:
384: return contribution;
385: }
386:
387: private Element getImplementationElement(ImplementationDescriptor id) {
388: Element implementation = _document
389: .createElement("implementation");
390:
391: implementation.setAttribute("service-id", qualify(id
392: .getServiceId()));
393:
394: if (id.getConditionalExpression() != null)
395: implementation.setAttribute("if", id
396: .getConditionalExpression());
397:
398: implementation.appendChild(_document.createTextNode(id
399: .getAnnotation()));
400:
401: InstanceBuilder ib = id.getInstanceBuilder();
402:
403: if (ib != null) {
404: Element instanceBuilder = getInstanceBuilderElement(ib);
405:
406: implementation.appendChild(instanceBuilder);
407: }
408:
409: List interceptors = id.getInterceptors();
410:
411: if (interceptors != null) {
412: for (Iterator i = interceptors.iterator(); i.hasNext();) {
413: InterceptorDescriptor icd = (InterceptorDescriptor) i
414: .next();
415:
416: Element interceptor = getInterceptorElement(icd);
417:
418: implementation.appendChild(interceptor);
419: }
420: }
421:
422: return implementation;
423: }
424:
425: private Element getSubModuleElement(SubModuleDescriptor smd) {
426: Element subModule = _document.createElement("sub-module");
427:
428: subModule.setAttribute("descriptor", smd.getDescriptor()
429: .getPath());
430:
431: return subModule;
432: }
433:
434: private Element getInstanceBuilderElement(InstanceBuilder ib) {
435: Element instanceBuilder;
436:
437: if (ib instanceof CreateInstanceDescriptor) {
438: CreateInstanceDescriptor cid = (CreateInstanceDescriptor) ib;
439: instanceBuilder = _document
440: .createElement("create-instance");
441:
442: instanceBuilder.setAttribute("class", cid
443: .getInstanceClassName());
444: if (!cid.getServiceModel().equals("singleton"))
445: instanceBuilder.setAttribute("model", cid
446: .getServiceModel());
447: } else {
448: InvokeFactoryDescriptor ifd = (InvokeFactoryDescriptor) ib;
449: instanceBuilder = _document.createElement("invoke-factory");
450:
451: if (!ifd.getFactoryServiceId().equals(
452: "hivemind.BuilderFactory"))
453: instanceBuilder.setAttribute("service-id", qualify(ifd
454: .getFactoryServiceId()));
455: if (ifd.getServiceModel() != null)
456: instanceBuilder.setAttribute("model", ifd
457: .getServiceModel());
458:
459: List parameters = ifd.getParameters();
460:
461: if (parameters != null) {
462: for (Iterator i = parameters.iterator(); i.hasNext();) {
463: org.apache.hivemind.Element parameter = (org.apache.hivemind.Element) i
464: .next();
465:
466: Element element = getParamterElement(parameter);
467:
468: instanceBuilder.appendChild(element);
469: }
470: }
471: }
472:
473: return instanceBuilder;
474: }
475:
476: private Element getInterceptorElement(InterceptorDescriptor icd) {
477: Element interceptor = _document.createElement("interceptor");
478:
479: interceptor.setAttribute("service-id", qualify(icd
480: .getFactoryServiceId()));
481: if (icd.getBefore() != null)
482: interceptor.setAttribute("before", icd.getBefore());
483: if (icd.getAfter() != null)
484: interceptor.setAttribute("after", icd.getAfter());
485: return interceptor;
486: }
487:
488: private Element getParamterElement(
489: org.apache.hivemind.Element parameter) {
490: Element element = _document.createElement(parameter
491: .getElementName());
492:
493: List attributes = parameter.getAttributes();
494:
495: for (Iterator i = attributes.iterator(); i.hasNext();) {
496: Attribute attribute = (Attribute) i.next();
497:
498: element.setAttribute(attribute.getName(), attribute
499: .getValue());
500: }
501:
502: List elements = parameter.getElements();
503:
504: for (Iterator i = elements.iterator(); i.hasNext();) {
505: org.apache.hivemind.Element nestedParameter = (org.apache.hivemind.Element) i
506: .next();
507:
508: element.appendChild(getParamterElement(nestedParameter));
509: }
510:
511: return element;
512: }
513:
514: private void addSchema(Element container, SchemaImpl s,
515: String elementName) {
516: if (_processedSchemas.contains(s))
517: return;
518:
519: Element schema = _document.createElement(elementName);
520:
521: if (s.getId() != null)
522: schema.setAttribute("id", qualify(s.getId()));
523:
524: if (s.getVisibility() == Visibility.PRIVATE)
525: schema.setAttribute("visibility", "private");
526:
527: schema.appendChild(_document.createTextNode(s.getAnnotation()));
528:
529: for (Iterator j = s.getElementModel().iterator(); j.hasNext();) {
530: ElementModel em = (ElementModel) j.next();
531:
532: Element element = getElementElement(em);
533:
534: schema.appendChild(element);
535: }
536:
537: container.appendChild(schema);
538:
539: _processedSchemas.add(s);
540: }
541:
542: private Element getRulesElement(ElementModel em) {
543: Element rules = _document.createElement("rules");
544:
545: for (Iterator i = em.getRules().iterator(); i.hasNext();) {
546: Rule r = (Rule) i.next();
547:
548: Element rule = null;
549:
550: if (r instanceof CreateObjectRule) {
551: CreateObjectRule cor = (CreateObjectRule) r;
552: rule = _document.createElement("create-object");
553:
554: rule.setAttribute("class", cor.getClassName());
555: } else if (r instanceof InvokeParentRule) {
556: InvokeParentRule ipr = (InvokeParentRule) r;
557: rule = _document.createElement("invoke-parent");
558:
559: rule.setAttribute("method", ipr.getMethodName());
560: if (ipr.getDepth() != 1)
561: rule.setAttribute("depth", Integer.toString(ipr
562: .getDepth()));
563: } else if (r instanceof PushAttributeRule) {
564: PushAttributeRule par = (PushAttributeRule) r;
565: rule = _document.createElement("push-attribute");
566:
567: rule.setAttribute("attribute", par.getAttributeName());
568: } else if (r instanceof PushContentRule) {
569: rule = _document.createElement("push-content");
570: } else if (r instanceof ReadAttributeRule) {
571: ReadAttributeRule rar = (ReadAttributeRule) r;
572: rule = _document.createElement("read-attribute");
573:
574: rule.setAttribute("property", rar.getPropertyName());
575: rule.setAttribute("attribute", rar.getAttributeName());
576: if (!rar.getSkipIfNull())
577: rule.setAttribute("skip-if-null", "false");
578: if (rar.getTranslator() != null)
579: rule
580: .setAttribute("translator", rar
581: .getTranslator());
582: } else if (r instanceof ReadContentRule) {
583: ReadContentRule rcr = (ReadContentRule) r;
584: rule = _document.createElement("read-content");
585:
586: rule.setAttribute("property", rcr.getPropertyName());
587: } else if (r instanceof SetModuleRule) {
588: SetModuleRule smr = (SetModuleRule) r;
589: rule = _document.createElement("set-module");
590:
591: rule.setAttribute("property", smr.getPropertyName());
592: } else if (r instanceof SetParentRule) {
593: SetParentRule spr = (SetParentRule) r;
594: rule = _document.createElement("set-parent");
595:
596: rule.setAttribute("property", spr.getPropertyName());
597: } else if (r instanceof SetPropertyRule) {
598: SetPropertyRule spr = (SetPropertyRule) r;
599: rule = _document.createElement("set-property");
600:
601: rule.setAttribute("property", spr.getPropertyName());
602: rule.setAttribute("value", spr.getValue());
603: } else if (r instanceof ConversionDescriptor) {
604: ConversionDescriptor cd = (ConversionDescriptor) r;
605: rule = _document.createElement("conversion");
606:
607: rule.setAttribute("class", cd.getClassName());
608: if (!cd.getParentMethodName().equals("addElement"))
609: rule.setAttribute("parent-method", cd
610: .getParentMethodName());
611:
612: for (Iterator j = cd.getAttributeMappings().iterator(); j
613: .hasNext();) {
614: AttributeMappingDescriptor amd = (AttributeMappingDescriptor) j
615: .next();
616:
617: Element map = _document.createElement("map");
618:
619: map.setAttribute("attribute", amd
620: .getAttributeName());
621: map.setAttribute("property", amd.getPropertyName());
622:
623: rule.appendChild(map);
624: }
625: } else {
626: rule = _document.createElement("custom");
627:
628: rule.setAttribute("class", r.getClass().getName());
629: }
630:
631: if (rule != null)
632: rules.appendChild(rule);
633: }
634: return rules;
635: }
636:
637: private Element getElementElement(ElementModel em) {
638: Element element = _document.createElement("element");
639: element.setAttribute("name", em.getElementName());
640:
641: element.appendChild(_document
642: .createTextNode(em.getAnnotation()));
643:
644: for (Iterator i = em.getAttributeModels().iterator(); i
645: .hasNext();) {
646: AttributeModel am = (AttributeModel) i.next();
647:
648: Element attribute = getAttributeElement(am);
649:
650: element.appendChild(attribute);
651: }
652:
653: for (Iterator i = em.getElementModel().iterator(); i.hasNext();) {
654: ElementModel nestedEm = (ElementModel) i.next();
655:
656: Element nestedElement = getElementElement(nestedEm);
657:
658: element.appendChild(nestedElement);
659: }
660:
661: if (!em.getRules().isEmpty()) {
662: Element rules = getRulesElement(em);
663:
664: element.appendChild(rules);
665: }
666:
667: return element;
668: }
669:
670: private Element getAttributeElement(AttributeModel am) {
671: Element attribute = _document.createElement("attribute");
672:
673: attribute.setAttribute("name", am.getName());
674: if (am.isRequired())
675: attribute.setAttribute("required", "true");
676: if (am.isUnique())
677: attribute.setAttribute("unique", "true");
678: if (!am.getTranslator().equals("smart"))
679: attribute.setAttribute("translator", am.getTranslator());
680:
681: attribute.appendChild(_document.createTextNode(am
682: .getAnnotation()));
683:
684: return attribute;
685: }
686:
687: private String qualify(String id) {
688: return IdUtils.qualify(_md.getModuleId(), id);
689: }
690:
691: private DocumentBuilder getBuilder() {
692: DocumentBuilderFactory factory = DocumentBuilderFactory
693: .newInstance();
694:
695: factory.setIgnoringComments(true);
696:
697: try {
698: return factory.newDocumentBuilder();
699: } catch (ParserConfigurationException e) {
700: throw new ApplicationRuntimeException(e);
701: }
702: }
703:
704: public static Document createDefaultRegistryDocument() {
705: ClassResolver resolver = new DefaultClassResolver();
706: ModuleDescriptorProvider provider = new XmlModuleDescriptorProvider(
707: resolver);
708:
709: RegistrySerializer serializer = new RegistrySerializer();
710:
711: serializer.addModuleDescriptorProvider(provider);
712:
713: return serializer.createRegistryDocument();
714: }
715: }
|