/* * Distributed as part of mchange-commons-java 0.2.11 * * Copyright (C) 2015 Machinery For Change, Inc. * * Author: Steve Waldman <swaldman@mchange.com> * * This library is free software; you can redistribute it and/or modify * it under the terms of EITHER: * * 1) The GNU Lesser General Public License (LGPL), version 2.1, as * published by the Free Software Foundation * * OR * * 2) The Eclipse Public License (EPL), version 1.0 * * You may choose which license to accept if you wish to redistribute * or modify this work. You may offer derivatives of this work * under the license you have chosen, or you may provide the same * choice of license which you have been offered here. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * You should have received copies of both LGPL v2.1 and EPL v1.0 * along with this software; see the files LICENSE-EPL and LICENSE-LGPL. * If not, the text of these licenses are currently available at * * LGPL v2.1: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * EPL v1.0: http://www.eclipse.org/org/documents/epl-v10.php * */ package com.mchange.v2.codegen.bean; import org.w3c.dom.*; import java.lang.reflect.Modifier; import com.mchange.v1.xml.DomParseUtils; public class ParsedPropertyBeanDocument { final static String[] EMPTY_SA = new String[0]; String packageName; int class_modifiers; String className; String superclassName; String[] interfaceNames = EMPTY_SA; String[] generalImports = EMPTY_SA; String[] specificImports = EMPTY_SA; Property[] properties; public ParsedPropertyBeanDocument(Document doc) { Element rootElem = doc.getDocumentElement(); this.packageName = DomParseUtils.allTextFromUniqueChild( rootElem, "package" ); Element modifiersElem = DomParseUtils.uniqueImmediateChild( rootElem, "modifiers" ); if (modifiersElem != null) class_modifiers = parseModifiers( modifiersElem ); else class_modifiers = Modifier.PUBLIC; Element importsElem = DomParseUtils.uniqueChild( rootElem, "imports" ); if (importsElem != null) { this.generalImports = DomParseUtils.allTextFromImmediateChildElements( importsElem, "general" ); this.specificImports = DomParseUtils.allTextFromImmediateChildElements( importsElem, "specific" ); } this.className = DomParseUtils.allTextFromUniqueChild( rootElem, "output-class" ); this.superclassName = DomParseUtils.allTextFromUniqueChild( rootElem, "extends" ); Element implementsElem = DomParseUtils.uniqueChild( rootElem, "implements" ); if (implementsElem != null) this.interfaceNames = DomParseUtils.allTextFromImmediateChildElements( implementsElem, "interface" ); Element propertiesElem = DomParseUtils.uniqueChild( rootElem, "properties" ); this.properties = findProperties( propertiesElem ); } public ClassInfo getClassInfo() { return new ClassInfo() { public String getPackageName() { return packageName; } public int getModifiers() { return class_modifiers; } public String getClassName() { return className; } public String getSuperclassName() { return superclassName; } public String[] getInterfaceNames() { return interfaceNames; } public String[] getGeneralImports() { return generalImports; } public String[] getSpecificImports() { return specificImports; } }; } public Property[] getProperties() { return (Property[]) properties.clone(); } private Property[] findProperties( Element propertiesElem ) { NodeList nl = DomParseUtils.immediateChildElementsByTagName( propertiesElem, "property" ); int len = nl.getLength(); Property[] out = new Property[ len ]; for( int i = 0; i < len; ++i) { Element propertyElem = (Element) nl.item( i ); int variable_modifiers; String name; String simpleTypeName; String defensiveCopyExpression; String defaultValueExpression; int getter_modifiers; int setter_modifiers; boolean is_read_only; boolean is_bound; boolean is_constrained; variable_modifiers = modifiersThroughParentElem( propertyElem, "variable", Modifier.PRIVATE ); name = DomParseUtils.allTextFromUniqueChild( propertyElem, "name", true ); simpleTypeName = DomParseUtils.allTextFromUniqueChild( propertyElem, "type", true ); defensiveCopyExpression = DomParseUtils.allTextFromUniqueChild( propertyElem, "defensive-copy", true ); defaultValueExpression = DomParseUtils.allTextFromUniqueChild( propertyElem, "default-value", true ); getter_modifiers = modifiersThroughParentElem( propertyElem, "getter", Modifier.PUBLIC ); setter_modifiers = modifiersThroughParentElem( propertyElem, "setter", Modifier.PUBLIC ); Element readOnlyElem = DomParseUtils.uniqueChild( propertyElem, "read-only" ); is_read_only = (readOnlyElem != null); Element isBoundElem = DomParseUtils.uniqueChild( propertyElem, "bound" ); is_bound = (isBoundElem != null); Element isConstrainedElem = DomParseUtils.uniqueChild( propertyElem, "constrained" ); is_constrained = (isConstrainedElem != null); out[i] = new SimpleProperty( variable_modifiers, name, simpleTypeName, defensiveCopyExpression, defaultValueExpression, getter_modifiers, setter_modifiers, is_read_only, is_bound, is_constrained ); } return out; } private static int modifiersThroughParentElem( Element grandparentElem, String parentElemName, int default_mods ) { Element parentElem = DomParseUtils.uniqueChild( grandparentElem, parentElemName ); if (parentElem != null ) { Element modifiersElem = DomParseUtils.uniqueChild( parentElem, "modifiers" ); if (modifiersElem != null) return parseModifiers( modifiersElem ); else return default_mods; } else return default_mods; } private static int parseModifiers( Element modifiersElem ) { int out = 0; String[] all_modifiers = DomParseUtils.allTextFromImmediateChildElements( modifiersElem, "modifier", true ); for ( int i = 0, len = all_modifiers.length; i < len; ++i) { String modifier = all_modifiers[i]; if ("public".equals( modifier )) out |= Modifier.PUBLIC; else if ("protected".equals( modifier )) out |= Modifier.PROTECTED; else if ("private".equals( modifier )) out |= Modifier.PRIVATE; else if ("final".equals( modifier )) out |= Modifier.FINAL; else if ("abstract".equals( modifier )) out |= Modifier.ABSTRACT; else if ("static".equals( modifier )) out |= Modifier.STATIC; else if ("synchronized".equals( modifier )) out |= Modifier.SYNCHRONIZED; else if ("volatile".equals( modifier )) out |= Modifier.VOLATILE; else if ("transient".equals( modifier )) out |= Modifier.TRANSIENT; else if ("strictfp".equals( modifier )) out |= Modifier.STRICT; else if ("native".equals( modifier )) out |= Modifier.NATIVE; else if ("interface".equals( modifier )) out |= Modifier.INTERFACE; // ???? else throw new IllegalArgumentException("Bad modifier: " + modifier); } return out; } }