package org.jvnet.jaxb2_commons.plugin.simplify; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import javax.xml.namespace.QName; import org.jvnet.jaxb2_commons.plugin.AbstractParameterizablePlugin; import org.jvnet.jaxb2_commons.plugin.Customizations; import org.jvnet.jaxb2_commons.plugin.CustomizedIgnoring; import org.jvnet.jaxb2_commons.plugin.Ignoring; import org.jvnet.jaxb2_commons.util.CustomizationUtils; import org.xml.sax.ErrorHandler; import com.sun.tools.xjc.model.CAttributePropertyInfo; import com.sun.tools.xjc.model.CClassInfo; import com.sun.tools.xjc.model.CClassRef; import com.sun.tools.xjc.model.CElement; import com.sun.tools.xjc.model.CElementInfo; import com.sun.tools.xjc.model.CElementPropertyInfo; import com.sun.tools.xjc.model.CElementPropertyInfo.CollectionMode; import com.sun.tools.xjc.model.CPropertyInfo; import com.sun.tools.xjc.model.CPropertyVisitor; import com.sun.tools.xjc.model.CReferencePropertyInfo; import com.sun.tools.xjc.model.CTypeRef; import com.sun.tools.xjc.model.CValuePropertyInfo; import com.sun.tools.xjc.model.Model; import com.sun.xml.bind.v2.model.core.ID; public class SimplifyPlugin extends AbstractParameterizablePlugin { @Override public String getOptionName() { return "Xsimplify"; } @Override public String getUsage() { return "This plugin allows simplifying \"complex\" properties" + " (ex. aOrBOrC generated from repeatable choices)" + " into several \"simple\" properties (ex. a, b, c).\n" + " Please visit http://confluence.highsource.org/display/J2B/Simplify+Plugin" + " for plugin documentation."; } private Ignoring ignoring = new CustomizedIgnoring( org.jvnet.jaxb2_commons.plugin.simplify.Customizations.IGNORED_ELEMENT_NAME, Customizations.IGNORED_ELEMENT_NAME, Customizations.GENERATED_ELEMENT_NAME); public Ignoring getIgnoring() { return ignoring; } public void setIgnoring(Ignoring ignoring) { this.ignoring = ignoring; } @Override public Collection<QName> getCustomizationElementNames() { return Arrays .asList(org.jvnet.jaxb2_commons.plugin.simplify.Customizations.AS_ELEMENT_PROPERTY_ELEMENT_NAME, org.jvnet.jaxb2_commons.plugin.simplify.Customizations.AS_REFERENCE_PROPERTY_ELEMENT_NAME, org.jvnet.jaxb2_commons.plugin.simplify.Customizations.IGNORED_ELEMENT_NAME, Customizations.IGNORED_ELEMENT_NAME, Customizations.GENERATED_ELEMENT_NAME); } @Override public void postProcessModel(final Model model, ErrorHandler errorHandler) { for (final CClassInfo classInfo : model.beans().values()) { postProcessClassInfo(model, classInfo); } } private void postProcessClassInfo(final Model model, final CClassInfo classInfo) { final List<CPropertyInfo> properties = new ArrayList<CPropertyInfo>( classInfo.getProperties()); for (CPropertyInfo property : properties) { property.accept(new CPropertyVisitor<Void>() { public Void onElement(CElementPropertyInfo elementProperty) { postProcessElementPropertyInfo(model, classInfo, elementProperty); return null; } public Void onAttribute(CAttributePropertyInfo attributeProperty) { // TODO Auto-generated method stub return null; } public Void onValue(CValuePropertyInfo valueProperty) { // TODO Auto-generated method stub return null; } public Void onReference(CReferencePropertyInfo p) { postProcessReferencePropertyInfo(model, classInfo, p); return null; } }); } } private void postProcessElementPropertyInfo(final Model model, final CClassInfo classInfo, CElementPropertyInfo property) { if (property.isCollection() && property.getTypes().size() > 1) { if (CustomizationUtils .containsCustomization( property, org.jvnet.jaxb2_commons.plugin.simplify.Customizations.AS_ELEMENT_PROPERTY_ELEMENT_NAME)) { simplifyElementPropertyInfoAsElementPropertyInfo(model, classInfo, property); } } } private void postProcessReferencePropertyInfo(final Model model, final CClassInfo classInfo, CReferencePropertyInfo property) { if (property.isCollection() && property.getElements().size() > 1) { if (CustomizationUtils .containsCustomization( property, org.jvnet.jaxb2_commons.plugin.simplify.Customizations.AS_ELEMENT_PROPERTY_ELEMENT_NAME)) { simplifyReferencePropertyInfoAsElementPropertyInfo(model, classInfo, property); } else if (CustomizationUtils .containsCustomization( property, org.jvnet.jaxb2_commons.plugin.simplify.Customizations.AS_REFERENCE_PROPERTY_ELEMENT_NAME)) { simplifyReferencePropertyInfoAsReferencePropertyInfo(model, classInfo, property); } } } private void simplifyElementPropertyInfoAsElementPropertyInfo( final Model model, final CClassInfo classInfo, CElementPropertyInfo property) { int index = classInfo.getProperties().indexOf(property); for (CTypeRef typeRef : property.getTypes()) { final CElementPropertyInfo elementPropertyInfo = createElementPropertyInfo( model, property, typeRef); classInfo.getProperties().add(index++, elementPropertyInfo); } classInfo.getProperties().remove(property); } private void simplifyReferencePropertyInfoAsReferencePropertyInfo( final Model model, final CClassInfo classInfo, CReferencePropertyInfo property) { int index = classInfo.getProperties().indexOf(property); for (CElement element : property.getElements()) { final CReferencePropertyInfo referencePropertyInfo = createReferencePropertyInfo( model, property, element); classInfo.getProperties().add(index++, referencePropertyInfo); } classInfo.getProperties().remove(property); } private void simplifyReferencePropertyInfoAsElementPropertyInfo( final Model model, final CClassInfo classInfo, CReferencePropertyInfo property) { int index = classInfo.getProperties().indexOf(property); for (CElement element : property.getElements()) { final CElementPropertyInfo elementPropertyInfo; if (element instanceof CElementInfo) { elementPropertyInfo = createElementPropertyInfo(model, element, (CElementInfo) element); } else if (element instanceof CClassInfo) { elementPropertyInfo = createElementPropertyInfo(model, element, (CClassInfo) element); } else if (element instanceof CClassRef) { // elementPropertyInfo = createElementPropertyInfo(model, // element, // (CClassRef) element); elementPropertyInfo = null; // TODO WARN } else { // TODO WARN elementPropertyInfo = null; } if (elementPropertyInfo != null) { classInfo.getProperties().add(index++, elementPropertyInfo); } } classInfo.getProperties().remove(property); } private CElementPropertyInfo createElementPropertyInfo(final Model model, CElement element, final CElementInfo elementInfo) { final CElementPropertyInfo elementPropertyInfo; final String propertyName = createPropertyName(model, element); elementPropertyInfo = new CElementPropertyInfo(propertyName, CollectionMode.REPEATED_ELEMENT, ID.NONE, null, element.getSchemaComponent(), element.getCustomizations(), element.getLocator(), false); elementPropertyInfo.getTypes().add( new CTypeRef(elementInfo.getContentType(), element .getElementName(), elementInfo.getContentType() .getTypeName(), false, null)); return elementPropertyInfo; } private CElementPropertyInfo createElementPropertyInfo(final Model model, CElement element, final CClassInfo classInfo) { final CElementPropertyInfo elementPropertyInfo; final String propertyName = createPropertyName(model, element); elementPropertyInfo = new CElementPropertyInfo(propertyName, CollectionMode.REPEATED_ELEMENT, ID.NONE, null, element.getSchemaComponent(), element.getCustomizations(), element.getLocator(), false); elementPropertyInfo.getTypes().add( new CTypeRef(classInfo, element.getElementName(), classInfo .getTypeName(), false, null)); return elementPropertyInfo; } // private CElementPropertyInfo createElementPropertyInfo(final Model model, // CElement element, final CClassRef cr) { // final CElementPropertyInfo elementPropertyInfo; // final String propertyName = createPropertyName(model, element); // elementPropertyInfo = new CElementPropertyInfo(propertyName, // CollectionMode.REPEATED_ELEMENT, ID.NONE, null, // element.getSchemaComponent(), element.getCustomizations(), // element.getLocator(), false); // elementPropertyInfo.getTypes().add( // new CTypeRef(cr, element.getElementName(), cr.getTypeName(), // false, null)); // return elementPropertyInfo; // } private CReferencePropertyInfo createReferencePropertyInfo( final Model model, CReferencePropertyInfo property, CElement element) { final String propertyName = createPropertyName(model, element); final CReferencePropertyInfo referencePropertyInfo = new CReferencePropertyInfo( propertyName, true, false, property.isMixed(), element.getSchemaComponent(), element.getCustomizations(), element.getLocator(), property.isDummy(), property.isContent(), property.isMixedExtendedCust()); referencePropertyInfo.getElements().add(element); return referencePropertyInfo; } private CElementPropertyInfo createElementPropertyInfo(final Model model, CElementPropertyInfo property, CTypeRef typeRef) { final String propertyName = createPropertyName(model, typeRef); boolean required = false; final CElementPropertyInfo elementPropertyInfo = new CElementPropertyInfo( propertyName, CollectionMode.REPEATED_ELEMENT, typeRef .getTarget().idUse(), typeRef.getTarget() .getExpectedMimeType(), property.getSchemaComponent(), property.getCustomizations(), property.getLocator(), required); elementPropertyInfo.getTypes().add(typeRef); return elementPropertyInfo; } private String createPropertyName(final Model model, CElement element) { final String propertyName = model.getNameConverter().toPropertyName( element.getElementName().getLocalPart()); return propertyName; } private String createPropertyName(final Model model, CTypeRef element) { final String propertyName = model.getNameConverter().toPropertyName( element.getTagName().getLocalPart()); return propertyName; } }