Author: bleny Date: 2010-09-28 12:05:55 +0200 (Tue, 28 Sep 2010) New Revision: 351 Url: http://nuiton.org/repositories/revision/wikitty/351 Log: merge branch migration to transformers (r350), updating version to 2.2.0-SNAPSHOT Added: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyImplementationGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaTransformer.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTransformerUtil.java trunk/wikitty-solr-impl/src/test/resources/solrconfig.xml Removed: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityAbstractGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityImplGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityInterfaceGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EnumGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EugengoConstants.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EugengoUtils.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/InterfaceGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikengoCommonGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaGenerator.java trunk/wikitty-solr-impl/src/test/resources/META-INF/ Modified: trunk/pom.xml trunk/src/site/rst/Spec.rst trunk/wikitty-api/pom.xml trunk/wikitty-generators/ trunk/wikitty-generators/pom.xml trunk/wikitty-hbase-impl/pom.xml trunk/wikitty-hessian-client/pom.xml trunk/wikitty-hessian-server/pom.xml trunk/wikitty-jdbc-impl/pom.xml trunk/wikitty-jms-impl/pom.xml trunk/wikitty-jpa-impl/pom.xml trunk/wikitty-multistorage-impl/pom.xml trunk/wikitty-solr-impl/ trunk/wikitty-solr-impl/pom.xml trunk/wikitty-solr-impl/src/main/java/org/nuiton/wikitty/solr/WikittySearchEnginSolr.java trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/AbstractTestSolr.java trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/SolrSearchTest.java trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/SolrServerTest.java trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/TreeTest.java trunk/wikitty-solr-impl/src/test/resources/log4j.properties trunk/wikitty-ui-zk/pom.xml Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -15,7 +15,7 @@ <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> <modules> <module>wikitty-generators</module> @@ -332,7 +332,7 @@ <projectId>wikitty</projectId> <!-- common versions used in sub-poms --> - <eugene.version>2.1.1</eugene.version> + <eugene.version>2.2-SNAPSHOT</eugene.version> <spring.version>3.0.1.RELEASE</spring.version> <jetty.version>6.1.22</jetty.version> Modified: trunk/src/site/rst/Spec.rst =================================================================== --- trunk/src/site/rst/Spec.rst 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/src/site/rst/Spec.rst 2010-09-28 10:05:55 UTC (rev 351) @@ -5,10 +5,17 @@ Les identifiants sont de la forme UUID[_<specifique extension>]. Donc tous les identifiants commence par un UUID et peut être séparé d'une extension -spécifique pour certain besoin par un '_' (underscore) +spécifique pour certain besoin par un '_' (underscore). -Un wikitty a toujours un identifiant. +C'est le mécanisme de base de génération des wikitty-id. Il y a toutefois +des exceptions : +* Pour les méta-extensions : chacun des wikitties aura pour +identifiant par exemple « WikittySecurity:MonExtension ». +Cela permet de court-cuircuiter la recherche solR, et un passage par +le réseau à chaque store/restore. +Un wikitty en base a toujours un identifiant, dès instanciation. + Gestion des droits ================== @@ -108,20 +115,24 @@ Ces droits sont stockés sous le forme d'un Wikitty. Pour chaque extension connue, il y aura donc un wikitty dont la seule extension sera WikittySecurity. -À VALIDER : Chacun de ces wikitty aura pour identifiant « WikittySecurity'ExtensionName' ». +Chacun de ces wikitty aura pour identifiant « WikittySecurity:ExtensionName ». +permet de court-cuircuiter la recherche solR, et un passage par le réseau à +chaque store/restore. Localisation ============ -On rajoute une pseudo extension WikittyI18n aux extensions du wikitty. +Il s'agit de traduire les noms de champs et pas les valeurs.On rajoute une méta-extension WikittyI18n aux extensions du wikitty. -Cette pseudo-extension a deux champs : langue et translation +Cette pseudo-extension a deux champs : +* language String +* translation String -personne:wikittyI18n.langue=fr,en,es +personne:wikittyI18n.language=fr,en,es personne:wikittyI18n.translation=[fr:name=prénom,surname=nom],[en:name=name,surname=surname] personne.name=value -ton extension : security dezs champs de sécurité +ton extension : security des champs de sécurité ton extension : i18n des champs i18n ton extension.champs=valeur dans la langue @@ -140,11 +151,15 @@ dans les restore il faut ajouter (extensions, id, + préchargement d'extensions) - - attention au moment de la migration au moment du chargement + + + +On ajoute WikittyService#allowTranslation(token, extension, boolean) + + Pseudo extension ================ Modified: trunk/wikitty-api/pom.xml =================================================================== --- trunk/wikitty-api/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-api/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -6,7 +6,7 @@ <parent> <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </parent> <!-- ************************************************************* --> @@ -110,6 +110,19 @@ <build> + <resources> + <resource> + <directory>${project.basedir}/src/main/resources</directory> + </resource> + <resource> + <directory>${project.build.directory}/generated-sources/models</directory> + <includes> + <include>*.objectmodel</include> + <include>*.properties</include> + </includes> + </resource> + </resources> + <pluginManagement> <plugins> <!-- eugene plugin --> Property changes on: trunk/wikitty-generators ___________________________________________________________________ Added: svn:mergeinfo + /branches/2.0-eugene2/wikitty-generators:164-179 /branches/wikitty-eugene-migration/wikitty-generators:239-347 Modified: trunk/wikitty-generators/pom.xml =================================================================== --- trunk/wikitty-generators/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-generators/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -1,12 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </parent> <!-- ************************************************************* --> @@ -21,6 +22,10 @@ <artifactId>eugene</artifactId> <scope>provided</scope> </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> </dependencies> <!-- ************************************************************* --> @@ -60,6 +65,19 @@ </filters> </configuration> </plugin> + + <!-- expose new plexus components --> + <plugin> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-component-metadata</artifactId> + <executions> + <execution> + <goals> + <goal>generate-metadata</goal> + </goals> + </execution> + </executions> + </plugin> </plugins> </build> Deleted: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityAbstractGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityAbstractGenerator.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityAbstractGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -1,476 +0,0 @@ -package org.nuiton.wikitty.generator; - -import java.io.File; -import java.io.IOException; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.eugene.GeneratorUtil; -import org.nuiton.eugene.models.object.ObjectModelAttribute; -import org.nuiton.eugene.models.object.ObjectModelClass; - -/** - * Possible enhancement: - * - generateParentMethod can generate attribut method access that call - * the same method on parent instance class. For that we must have one attribut - * instance by parent. This attribut we must be created in setWikitty method - * and used same wikitty object. - * - * @author poussin - */ -public class BusinessEntityAbstractGenerator extends WikengoCommonGenerator { - - private static final Log log = LogFactory.getLog(BusinessEntityAbstractGenerator.class); - - static protected Pattern extractTypeOnCollection = Pattern.compile("\\w*<(\\w+)>"); - - protected String EXT_NAME; - - @Override - public String getFilenameForClass(ObjectModelClass clazz) { - String fqn = clazz.getQualifiedName(); - log.info( "Filename for " + clazz.getName() + " is " + fqn.replace('.', File.separatorChar) + ".java"); - return fqn.replace('.', File.separatorChar) + "Abstract.java"; - } - - public void generateFromClass(Writer output, ObjectModelClass clazz) - throws IOException { - if (!EugengoUtils.isBusinessEntity(clazz)) { - log.info( clazz.getName() + " is not a business entity"); - return; - } - - log.info("Generate Business entity abstract" + clazz.getName() + "... "); - generateCopyright(output); - - EXT_NAME = "EXT_" + clazz.getName().toUpperCase(); - - String packageName = clazz.getPackageName(); - String name = clazz.getName() + "Abstract"; -/*{package <%=packageName%>; - -}*/ - ObjectModelClass superClass = findSuperClass(clazz); - - clearImports(); - addImport(clazz); - addImport(superClass); - addImport("org.nuiton.wikitty.WikittyUtil"); - addImport("org.nuiton.wikitty.Wikitty"); - addImport("org.nuiton.wikitty.BusinessEntityWikitty"); - addImport("org.nuiton.wikitty.WikittyExtension"); - addImport(Collection.class); - addImport(Collections.class); - addImport(List.class); - addImport(ArrayList.class); - String parentImpl = null; - for (ObjectModelClass parent : clazz.getSuperclasses()) { - if (EugengoUtils.isBusinessEntity(parent)) { - addImport(parent); - parentImpl = parent.getQualifiedName() + "Impl"; - addImport(parentImpl); - addImport(parent.getQualifiedName() + "Abstract"); - } - } - lookForAttributeImports(clazz); - generateImports(output, packageName); - - generateClazzDocumentation(output, clazz); - String extendsString = " extends " + getType( parentImpl != null ? parentImpl : "org.nuiton.wikitty.BusinessEntityWikitty" ); - - String implementsString = "implements " + getType(clazz.getQualifiedName()); - for (ObjectModelClass parent : clazz.getSuperclasses()) { - if (EugengoUtils.isBusinessEntity(parent)) { - implementsString += ", " + getType(parent.getQualifiedName()); - } - } - -/*{public abstract class <%=name%><%=extendsString%> <%=implementsString%> { - -}*/ - - String svUID = GeneratorUtil.computeSerialVersionUID(clazz); -/*{ private static final long serialVersionUID = <%=svUID%>; - -}*/ - - generateWikittyExtension(output, clazz); - - generateStaticAttributes(output, clazz); - -/*{ - public <%=name%>() { - super(); - } - - public <%=name%>(BusinessEntityWikitty wi) { - super(wi.getWikitty()); - } - - public <%=name%>(Wikitty wi) { - super(wi); - } - -}*/ - - generateAttributeAccessMethod(output, clazz); - - for (ObjectModelClass parent : clazz.getSuperclasses()) { - if (EugengoUtils.isBusinessEntity(parent)) { - generateParentMethod(output, parent); - } - } - -/*{ @Override - public Collection<WikittyExtension> getStaticExtensions() { - return extensions; - } - - /** - * Check equality on all field of this extension, and only those. - *) - static public boolean equals(Wikitty w1, Wikitty w2) { - boolean result = true; -}*/ - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && !attr.isStatic() && - (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { -/*{ if (result) { - Object f1 = w1.getFieldAsObject(<%=EXT_NAME%>, FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>); - Object f2 = w2.getFieldAsObject(<%=EXT_NAME%>, FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>); - result = f1 == f2 || (f1 != null && f1.equals(f2)); - } -}*/ - } - } -/*{ - return result; - } - -} //<%=name%> -}*/ - - } - - - - // Utilitarian methods - - public void generateAttributeAccessMethod(Writer output, ObjectModelClass clazz) throws IOException { - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && !attr.isStatic() - && (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { - if ((attr.getMaxMultiplicity() != 0 && attr.getMaxMultiplicity() != 1)) { - //TODO ymartel 20090812: when dataType "List", "Set" or "Collection" in model, must be here! - generateCollectionAttributeAccessors(output, clazz, attr); - } else { - generateWikittyAttributeAccessors(output, clazz, attr); - } - } - } - } - - private void generateWikittyExtension(Writer output, - ObjectModelClass clazz) throws IOException { - String version = clazz.getTagValue("version"); - - // Since wikitty 1.3, version need to be dotted - if ( version == null ) { - version = "1.0"; - } - - // get requires from parent - String requires = null; - String separator = ""; - for (ObjectModelClass parent : clazz.getSuperclasses()) { - if (EugengoUtils.isBusinessEntity(parent)) { - String parentExtName = "EXT_" + parent.getName().toUpperCase(); - - if (requires == null) { - requires = ""; - } - - requires += separator + parent.getName() + "." + parentExtName; - // dans le cas où on aurait un heritage multiple :) - // FIXME EC-20100420 gerer les extensions multiples - separator = " + \",\" /* FIXME Multiples extentions are not yet supported */ + "; - } - } - -/*{ static final public List<WikittyExtension> extensions; - static final public WikittyExtension extension<%=clazz.getName()%> = - new WikittyExtension(<%=EXT_NAME%>, "<%=version%>", <%=requires%>, - WikittyUtil.buildFieldMapExtension(}*/ - - separator = ""; - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && !attr.isStatic() && - (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { -/*{<%=separator%> - }*/ - generateAttribute(output, attr); - separator = ","; - } - } -/*{)); - static { - List<WikittyExtension> exts = new ArrayList<WikittyExtension>(); -}*/ - for (ObjectModelClass parent : clazz.getSuperclasses()) { - if (EugengoUtils.isBusinessEntity(parent)) { -/*{ - exts.addAll(<%=parent.getName()%>Abstract.extensions); -}*/ - } - } - - // EC-20100420 add current extension after parent ones - // if current is loaded before required extension - // load failed because required extension is missing -/*{ // current after requires ones - exts.add(extension<%=clazz.getName()%>); - - extensions = Collections.unmodifiableList(exts); - } -}*/ - } - - private void generateAttribute(Writer output, ObjectModelAttribute attr) - throws IOException { - String attrType = computeType(attr); - // temp fix, si le type est Wikitty, il doit rester Wikitty dans - // la définition de l'extension - if ("org.nuiton.wikitty.Wikitty".equals(attr.getType()) || "Wikitty".equals(attr.getType())) { - attrType = "Wikitty"; - } else if (EugengoUtils.notEmpty(attrType)) { - attrType = getType(attrType); - } else { - return; - } - - String attrName = attr.getName(); - String card = ""; - - //TODO ymartel 20090812: a better way to manage those DataTypes in the model? - if (attrType.contains("Collection") || attrType.contains("List") || attrType.contains("Set")) { - card = "[0-*]"; - // List<String> - Matcher match = extractTypeOnCollection.matcher(attrType); - if (match.matches()) { - attrType = match.group(1); - } - } - - if (!commonTypes.contains(attrType)) { - attrType = "Wikitty"; - } else if(commonNumerics.contains(attrType)) { - attrType = "Numeric"; - } else if(commonStrings.contains(attrType)) { - attrType = "String"; - } - - - int maxMultiplicity = attr.getMaxMultiplicity(); - if ((maxMultiplicity != 0 && maxMultiplicity != 1)){ - card = "[" + attr.getMinMultiplicity() + "-"; - if (maxMultiplicity == -1) { - card += "*]"; - } else { - card += maxMultiplicity + "]"; - } - } - - // FIXME EC-20100420 attr.isUnique() always return true for - // attributes (maybe use tagValue instead) - String unique = ""; - boolean isCollection = (attr.getMaxMultiplicity() != 0 - && attr.getMaxMultiplicity() != 1); - if (isCollection && attr.isUnique()) { - unique = " unique=true"; - } - - String tagValues = ""; - for (String tag : attr.getTagValues().keySet()) { - String value = attr.getTagValue(tag); - value = value.replaceAll("\n", "\\n"); - value = value.replaceAll("\"", "\\\""); - - tagValues += " " + tag + "=\\\"" + value + "\\\""; - } - -/*{"<%=attrType%> <%=attrName%><%=card%><%=unique%><%=tagValues%>"}*/ - } - - private void generateParentMethod(Writer output, - ObjectModelClass clazz) throws IOException { - - // we must generate method for parent of parent - for (ObjectModelClass parent : clazz.getSuperclasses()) { - if (EugengoUtils.isBusinessEntity(parent)) { - generateParentMethod(output, parent); - } - } - - // generate method acces for parent attribut - generateAttributeAccessMethod(output, clazz); - } - - protected void generateWikittyAttributeAccessors(Writer output, - ObjectModelClass clazz, ObjectModelAttribute attr) throws IOException { - - EXT_NAME = "EXT_" + attr.getDeclaringElement().getName().toUpperCase(); - - String attrType = computeType(attr); - if (EugengoUtils.notEmpty(attrType)) { - attrType = getType(attrType, true); - } else { - return; - } - - // FIXME EC-20100421 cette methode peut retourner List<String> - // et generer la methode getWikitty().getFieldAsList<String>() - // qui ne peut pas compiler - String methodAccessName = getFieldAccessMethodName(attr); - - String attrName = attr.getName(); - String attrNameCapitalized = EugengoUtils.toUpperCaseFirstLetter(attrName); - -/*{ - public void set<%=attrNameCapitalized%>(<%=attrType%> <%=attrName%>) { - Object oldValue = getField(<%=EXT_NAME%>, FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>); - getWikitty().setField(<%=EXT_NAME%>, FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, <%=attrName%>); - getPropertyChangeSupport().firePropertyChange(FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, oldValue, <%=attrName%>); - } - - public <%=attrType%> get<%=attrNameCapitalized%>() { - <%=attrType%> result = getWikitty().getFieldAs<%=methodAccessName%>(<%=EXT_NAME%>, FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>); - return result; - } - -}*/ - } - - /** - * Give the string to put after getFieldAs???, only some type is accepted - * and we must convert BusinessEntity to Wikitty string - * @param type - * @return - */ - protected String getFieldAccessMethodName(ObjectModelAttribute attr) { - String result = computeType(attr); - result = getType(result, true); - - boolean isCollection = (attr.getMaxMultiplicity() != 0 - && attr.getMaxMultiplicity() != 1); - if (isCollection) { - if (attr.isUnique()) { - result = "Set"; - } else { - result = "List"; - } - } else { - // test for Date - if ("java.util.Date".equals(result) || "Date".equals(result)) { - result = "Date"; - } else if (getModel().hasClass(result)) { // test for Wikitty object - ObjectModelClass fieldClass = getModel().getClass(result); - if (EugengoUtils.isBusinessEntity(fieldClass)) { - // for wikittyDto we use String for Id - result = "Wikitty"; - } - } else if (null != getModel().getEnumeration(result)) { - result = "String"; - } - } - result = EugengoUtils.toUpperCaseFirstLetter(result); - - return result; - } - - protected void generateCollectionAttributeAccessors(Writer output, - ObjectModelClass clazz, ObjectModelAttribute attr) throws IOException { - - EXT_NAME = "EXT_" + attr.getDeclaringElement().getName().toUpperCase(); - - String attrType = computeType(attr); - if (EugengoUtils.notEmpty(attrType)) { - attrType = getType(attrType, true); - } else { - return; - } - - // get collection element type for add and remove method arguement type - String elementType = getType(attr.getType(), true); - - String methodAccessName = getFieldAccessMethodName(attr); - - String attrName = attr.getName(); - String attrNameCapitalized = EugengoUtils.toUpperCaseFirstLetter(attrName); -/*{ public <%=attrType%> get<%=attrNameCapitalized%>() { - <%=attrType%> result = getWikitty().getFieldAs<%=methodAccessName%>(<%=EXT_NAME%>, FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, <%=getClassAndGeneric(attrType)[1]%>.class); - return result; - } - - public void add<%=attrNameCapitalized%>(<%=elementType%> element) { - getWikitty().addToField(<%=EXT_NAME%>, FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, element); - getPropertyChangeSupport().firePropertyChange(FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, null, get<%=attrNameCapitalized%>()); - } - - public void remove<%=attrNameCapitalized%>(<%=elementType%> element) { - getWikitty().removeFromField(<%=EXT_NAME%>, FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, element); - getPropertyChangeSupport().firePropertyChange(FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, null, get<%=attrNameCapitalized%>()); - } - - public void clear<%=attrNameCapitalized%>() { - getWikitty().clearField(<%=EXT_NAME%>, FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>); - getPropertyChangeSupport().firePropertyChange(FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, null, get<%=attrNameCapitalized%>()); - } - -}*/ - } - - private static Set<String> commonNumerics; - static { - commonNumerics = new HashSet<String>(); - commonNumerics.add("byte"); - commonNumerics.add("Byte"); - commonNumerics.add("short"); - commonNumerics.add("Short"); - commonNumerics.add("int"); - commonNumerics.add("Integer"); - commonNumerics.add("long"); - commonNumerics.add("Long"); - commonNumerics.add("float"); - commonNumerics.add("Float"); - commonNumerics.add("double"); - commonNumerics.add("Double"); - } - - private static Set<String> commonStrings; - static { - commonStrings = new HashSet<String>(); - commonStrings.add("char"); - commonStrings.add("Char"); - commonStrings.add("String"); - } - - private static Set<String> commonTypes; - static { - commonTypes = new HashSet<String>(); - commonTypes.addAll(commonNumerics); - commonTypes.addAll(commonStrings); - commonTypes.add("boolean"); - commonTypes.add("Boolean"); - commonTypes.add("Date"); - } - -} Deleted: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityImplGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityImplGenerator.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityImplGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -1,147 +0,0 @@ -package org.nuiton.wikitty.generator; - -import java.io.File; -import java.io.IOException; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.eugene.GeneratorUtil; -import org.nuiton.eugene.models.object.ObjectModelClass; - -/** - * Possible enhancement: - * - generateParentMethod can generate attribut method access that call - * the same method on parent instance class. For that we must have one attribut - * instance by parent. This attribut we must be created in setWikitty method - * and used same wikitty object. - * - * @author poussin - */ -public class BusinessEntityImplGenerator extends WikengoCommonGenerator { - - private static final Log log = LogFactory.getLog(BusinessEntityImplGenerator.class); - - @Override - public String getFilenameForClass(ObjectModelClass clazz) { - String fqn = clazz.getQualifiedName(); - log.info( "Filename for " + clazz.getName() + " is " + fqn.replace('.', File.separatorChar) + ".java"); - return fqn.replace('.', File.separatorChar) + "Impl.java"; - } - - public void generateFromClass(Writer output, ObjectModelClass clazz) - throws IOException { - if (!EugengoUtils.isBusinessEntity(clazz)) { - log.info( clazz.getName() + " is not a business entity"); - return; - } - - // On ne génère pas le impl si l'entité a des opérations - if (clazz.getOperations().size() > 0) { - return; - } - - log.info("Generate Business entity impl" + clazz.getName() + "... "); - generateCopyright(output); - - String packageName = clazz.getPackageName(); - String className = clazz.getName(); - String name = className + "Impl"; -/*{package <%=packageName%>; - -}*/ - ObjectModelClass superClass = findSuperClass(clazz); - - clearImports(); - addImport(clazz); - addImport(superClass); - addImport("org.nuiton.wikitty.WikittyUtil"); - addImport("org.nuiton.wikitty.Wikitty"); - addImport("org.nuiton.wikitty.BusinessEntityWikitty"); - addImport("org.nuiton.wikitty.WikittyExtension"); - addImport(Collection.class); - addImport(Collections.class); - addImport(List.class); - addImport(ArrayList.class); - String parentImpl = null; - for (ObjectModelClass parent : clazz.getSuperclasses()) { - if (EugengoUtils.isBusinessEntity(parent)) { - addImport(parent); - parentImpl = parent.getQualifiedName() + "Impl"; - addImport( parentImpl ); - } - } - lookForAttributeImports(clazz); - generateImports(output, packageName); - - generateClazzDocumentation(output, clazz); - String abstractString = ""; - if (clazz.isAbstract()) { - abstractString += "abstract "; - } - -/*{public <%=abstractString%>class <%=className%>Impl extends <%=className%>Abstract { - -}*/ - - String svUID = GeneratorUtil.computeSerialVersionUID(clazz); -/*{ private static final long serialVersionUID = <%=svUID%>; - - public <%=name%>() { - super(); - } - - public <%=name%>(BusinessEntityWikitty wi) { - super(wi.getWikitty()); - } - - public <%=name%>(Wikitty wi) { - super(wi); - } - -} //<%=name%> -}*/ - } - - private static Set<String> commonNumerics; - static { - commonNumerics = new HashSet<String>(); - commonNumerics.add("byte"); - commonNumerics.add("Byte"); - commonNumerics.add("short"); - commonNumerics.add("Short"); - commonNumerics.add("int"); - commonNumerics.add("Integer"); - commonNumerics.add("long"); - commonNumerics.add("Long"); - commonNumerics.add("float"); - commonNumerics.add("Float"); - commonNumerics.add("double"); - commonNumerics.add("Double"); - } - - private static Set<String> commonStrings; - static { - commonStrings = new HashSet<String>(); - commonStrings.add("char"); - commonStrings.add("Char"); - commonStrings.add("String"); - } - - private static Set<String> commonTypes; - static { - commonTypes = new HashSet<String>(); - commonTypes.addAll(commonNumerics); - commonTypes.addAll(commonStrings); - commonTypes.add("boolean"); - commonTypes.add("Boolean"); - commonTypes.add("Date"); - } - -} Deleted: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityInterfaceGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityInterfaceGenerator.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/BusinessEntityInterfaceGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -1,202 +0,0 @@ -package org.nuiton.wikitty.generator; - -import java.io.File; -import java.io.IOException; -import java.io.Writer; -import java.util.Collection; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.eugene.models.object.ObjectModelAttribute; -import org.nuiton.eugene.models.object.ObjectModelClass; -import org.nuiton.eugene.models.object.ObjectModelClassifier; -import org.nuiton.eugene.models.object.ObjectModelOperation; -import org.nuiton.eugene.models.object.ObjectModelParameter; - -/** - * Interface for BusinessEntity, interfaces are needed for multiple inheritance - * - * @author poussin - */ -public class BusinessEntityInterfaceGenerator extends WikengoCommonGenerator { - - private static final Log log = LogFactory.getLog(BusinessEntityInterfaceGenerator.class); - - protected String EXT_NAME; - - @Override - public String getFilenameForClass(ObjectModelClass clazz) { - String fqn = clazz.getQualifiedName(); - log.info( "Filename for " + clazz.getName() + " is " + fqn.replace('.', File.separatorChar) + ".java"); - return fqn.replace('.', File.separatorChar) + ".java"; - } - - public void generateFromClass(Writer output, ObjectModelClass clazz) - throws IOException { - if (!EugengoUtils.isBusinessEntity(clazz)) { - log.info( clazz.getName() + " is not a business entity"); - return; - } - - log.info("Generate Business entity " + clazz.getName() + "... "); - generateCopyright(output); - - EXT_NAME = "EXT_" + clazz.getName().toUpperCase(); - String packageName = clazz.getPackageName(); - String name = clazz.getName(); -/*{package <%=packageName%>; - -}*/ - ObjectModelClass superClass = findSuperClass(clazz); - - clearImports(); - addImport(superClass); - addImport("org.nuiton.wikitty.BusinessEntity"); - - for (ObjectModelClass parent : clazz.getSuperclasses()) { - if (EugengoUtils.isBusinessEntity(parent)) { - addImport(parent); - } - } - lookForAttributeImports(clazz); - generateImports(output, packageName); - - generateClazzDocumentation(output, clazz); - - String extendsString = "extends " + getType("org.nuiton.wikitty.BusinessEntity"); - for (ObjectModelClass parent : clazz.getSuperclasses()) { - if (EugengoUtils.isBusinessEntity(parent)) { - extendsString += ", " + getType(parent.getName()); - } - } - -/*{public interface <%=name%> <%=extendsString%> { - - static final public String <%=EXT_NAME%> = "<%=clazz.getName()%>"; - -}*/ - generateFieldNameConstant(output, clazz); - - generateStaticAttributes(output, clazz); - - generateAttributeAccessMethod(output, clazz); - - generateInterfaceOperations(output, clazz); - -/*{ -} //<%=name%> -}*/ - - } - - // Utilitarian methods - private void generateFieldNameConstant(Writer output, - ObjectModelClass clazz) throws IOException { - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && !attr.isStatic() && - (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { -/*{ static final public String FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%> = "<%=attr.getName()%>"; - static final public String FQ_FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%> = <%=EXT_NAME%> + ".<%=attr.getName()%>"; -}*/ - } - } - } - - public void generateAttributeAccessMethod(Writer output, ObjectModelClass clazz) throws IOException { - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && !attr.isStatic() - && (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { - if ((attr.getMaxMultiplicity() != 0 && attr.getMaxMultiplicity() != 1)) { - //TODO ymartel 20090812: when dataType "List", "Set" or "Collection" in model, must be here! - generateCollectionAttributeAccessors(output, attr); - } else { - generateWikittyAttributeAccessors(output, attr); - } - } - } - } - - protected void generateWikittyAttributeAccessors(Writer output, - ObjectModelAttribute attr) throws IOException { - String attrType = computeType(attr); - if (EugengoUtils.notEmpty(attrType)) { - attrType = getType(attrType, true); - } else { - return; - } - - String attrName = attr.getName(); - String attrNameCapitalized = EugengoUtils.toUpperCaseFirstLetter(attrName); - -/*{ - public void set<%=attrNameCapitalized%>(<%=attrType%> <%=attrName%>); - public <%=attrType%> get<%=attrNameCapitalized%>(); - -}*/ - } - - protected void generateCollectionAttributeAccessors(Writer output, - ObjectModelAttribute attr) throws IOException { - String attrType = computeType(attr); - if (EugengoUtils.notEmpty(attrType)) { - attrType = getType(attrType, true); - } else { - return; - } - - // get collection element type for add and remove method arguement type - String elementType = getType(attr.getType(), true); - - String attrName = attr.getName(); - String attrNameCapitalized = EugengoUtils.toUpperCaseFirstLetter(attrName); -/*{ public <%=attrType%> get<%=attrNameCapitalized%>(); - public void add<%=attrNameCapitalized%>(<%=elementType%> element); - public void remove<%=attrNameCapitalized%>(<%=elementType%> element); - public void clear<%=attrNameCapitalized%>(); - -}*/ - } - - private void generateInterfaceOperations(Writer output, ObjectModelClassifier classifier) throws IOException { - for (ObjectModelOperation op : classifier.getOperations()) { - String opName = op.getName(); -/*{ /** -}*/ - if (EugengoUtils.hasDocumentation(op)) { - String opDocumentation = op.getDocumentation(); -/*{ * <%=opName%> : <%=opDocumentation%> -}*/ - } - Collection<ObjectModelParameter> params = op.getParameters(); - for (ObjectModelParameter param : params) { - String paramName = param.getName(); - String paramDocumentation = param.getDocumentation(); -/*{ * @param <%=paramName%> <%=paramDocumentation%> - }*/ - } - String opVisibility = op.getVisibility(); - String opType = op.getReturnType(); -/*{ *) - <%=opVisibility%> <%=opType%> <%=opName%>(}*/ - String comma = ""; - for (ObjectModelParameter param : params) { - String paramName = param.getName(); - String paramType = param.getType(); -/*{<%=comma%><%=paramType%> <%=paramName%>}*/ - comma = ", "; - } -/*{)}*/ - Set<String> exceptions = op.getExceptions(); - comma = " throws "; - for (String exception : exceptions) { -/*{<%=comma%><%=exception%>}*/ - comma = ", "; - } -/*{; - -}*/ - } - } - -} Deleted: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EnumGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EnumGenerator.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EnumGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -1,53 +0,0 @@ -package org.nuiton.wikitty.generator; - -import java.io.File; -import java.io.IOException; -import java.io.Writer; - -import org.nuiton.eugene.models.object.ObjectModelEnumeration; - -public class EnumGenerator extends WikengoCommonGenerator { - - @Override - public String getFilenameForEnumeration(ObjectModelEnumeration enumeration) { - String fqn = enumeration.getQualifiedName(); - return fqn.replace('.', File.separatorChar) + ".java"; - } - - @Override - public void generateFromEnumeration(Writer output, - ObjectModelEnumeration enumeration) throws IOException { - - generateCopyright(output); - - String packageName = enumeration.getPackageName(); - String enumName = enumeration.getName(); - -/*{package <%=packageName%>; - -}*/ - generateDocumentation(output, enumeration, ""); -/*{public enum <%=enumName%> { - -}*/ - - boolean isFirst = true; - for (String literal: enumeration.getLiterals()) { - if (isFirst) { -/*{ }*/ - } else { -/*{, }*/ - } - isFirst = false; -/*{<%=literal%>}*/ - } - -/*{ - -}*/ - -/*{} //<%=enumName%> -}*/ - } - -} Deleted: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EugengoConstants.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EugengoConstants.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EugengoConstants.java 2010-09-28 10:05:55 UTC (rev 351) @@ -1,21 +0,0 @@ -package org.nuiton.wikitty.generator; - -public class EugengoConstants { - - public final static String STEREOTYPE_SERVICE = "Service"; - public final static String STEREOTYPE_CRUD_SERVICE = "CrudService"; - public final static String STEREOTYPE_DTO = "Dto"; - public final static String STEREOTYPE_BUSINESS_ENTITY = "BusinessEntity"; - public final static String STEREOTYPE_DAO = "Dao"; - public final static String STEREOTYPE_ENTITY = "Entity"; - public final static String STEREOTYPE_EXCEPTION = "Exception"; - public final static String STEREOTYPE_BUSINESS_EXCEPTION = "BusinessException"; - public final static String STEREOTYPE_REMOTE = "Remote"; - - public final static String TAG_COPYRIGHT = "copyright"; - public final static String TAG_LENGTH = "length"; - public static final String TAG_LAZY = "lazy"; - - public final static String PREFIX_DATATYPE = "dataType-"; - -} // EugengoConstants Deleted: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EugengoUtils.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EugengoUtils.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/EugengoUtils.java 2010-09-28 10:05:55 UTC (rev 351) @@ -1,157 +0,0 @@ -package org.nuiton.wikitty.generator; - -import java.util.HashSet; -import java.util.Set; - -import org.nuiton.eugene.GeneratorUtil; -import org.nuiton.eugene.models.Model; -import org.nuiton.eugene.models.object.ObjectModelAttribute; -import org.nuiton.eugene.models.object.ObjectModelClassifier; -import org.nuiton.eugene.models.object.ObjectModelOperation; - -public class EugengoUtils extends GeneratorUtil { - - /** - * Cherches et renvoie le copyright a utiliser sur le model. - * - * @param model le modele utilise - * @return le texte du copyright ou null - */ - public static String getCopyright(Model model) { - return GeneratorUtil.findTagValue(EugengoConstants.TAG_COPYRIGHT, null, model); - } - - public static boolean isService(ObjectModelClassifier classifier) { - return hasStereotype(classifier, EugengoConstants.STEREOTYPE_SERVICE) || isCrudService(classifier); - } - - public static boolean isCrudService(ObjectModelClassifier classifier) { - return hasStereotype(classifier, EugengoConstants.STEREOTYPE_CRUD_SERVICE); - } - - public static boolean isWebService(ObjectModelClassifier classifier) { - // any crud service is remote - if (isCrudService(classifier)) { - return true; - } - // cannot be a webservice if class is not a service - if (!isService(classifier)) { - return false; - } - // Look for an operation that has the stereotype remote - for (ObjectModelOperation op : classifier.getOperations()) { - if (isRemote(op)) { - return true; - } - } - return false; - } - - public static boolean isDto(ObjectModelClassifier classifier) { - return hasStereotype(classifier, EugengoConstants.STEREOTYPE_DTO); - } - - public static boolean isBusinessEntity(ObjectModelClassifier classifier) { - return hasStereotype(classifier, EugengoConstants.STEREOTYPE_BUSINESS_ENTITY); - } - - public static boolean isDao(ObjectModelClassifier classifier) { - return hasStereotype(classifier, EugengoConstants.STEREOTYPE_DAO); - } - - public static boolean isEntity(ObjectModelClassifier classifier) { - return hasStereotype(classifier, EugengoConstants.STEREOTYPE_ENTITY); - } - - public static boolean isException(ObjectModelClassifier classifier) { - return hasStereotype(classifier, EugengoConstants.STEREOTYPE_EXCEPTION) || isBusinessException(classifier); - } - - public static boolean isBusinessException(ObjectModelClassifier classifier) { - return hasStereotype(classifier, EugengoConstants.STEREOTYPE_BUSINESS_EXCEPTION); - } - - public static boolean isRemote(ObjectModelOperation op) { - return hasStereotype(op, EugengoConstants.STEREOTYPE_REMOTE); - } - - private static Set<String> simpleTypes; - static { - simpleTypes = new HashSet<String>(); - simpleTypes.add("void"); - simpleTypes.add("boolean"); - simpleTypes.add("byte"); - simpleTypes.add("short"); - simpleTypes.add("int"); - simpleTypes.add("long"); - simpleTypes.add("float"); - simpleTypes.add("double"); - } - - - private static Set<String> primitiveTypes; - static { - primitiveTypes = new HashSet<String>(); - primitiveTypes.add("byte"); - primitiveTypes.add("Byte"); - primitiveTypes.add("short"); - primitiveTypes.add("Short"); - primitiveTypes.add("int"); - primitiveTypes.add("Integer"); - primitiveTypes.add("long"); - primitiveTypes.add("Long"); - primitiveTypes.add("float"); - primitiveTypes.add("Float"); - primitiveTypes.add("double"); - primitiveTypes.add("Double"); - - primitiveTypes.add("char"); - primitiveTypes.add("Char"); - - primitiveTypes.add("boolean"); - primitiveTypes.add("Boolean"); - } - - public static String extractModelName(Model model) { - String result = model.getName(); - if (result.contains("::")) { - result = result.replaceAll("::", "."); - } - if (result.endsWith(".")) { - result = result.substring(0, result.length() - 1); - } - return result; - } - - public static String normalizeCapitalName(String name) { - String result = ""; - for (int idx = 0; idx < name.length(); idx++) { - char c = name.charAt(idx); - if (Character.isUpperCase(c)) { - result += "_"; - } - result += Character.toUpperCase(c); - } - if (result.startsWith("_")) { - result = result.substring(1); - } - return result; - } - - public static String getTagValue(ObjectModelAttribute attr, String tagName, String defaultValue) { - String value = attr.getTagValue(tagName); - if (value == null) { - value = defaultValue; - } - return value; - } - - public static boolean isPrimitiveType(ObjectModelAttribute attr) { - String type = attr.getType(); - if (type.startsWith("java.lang.")) { - type = type.substring(11); - } - return primitiveTypes.contains(type); - } - -} //EugengoUtils Deleted: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/InterfaceGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/InterfaceGenerator.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/InterfaceGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -1,52 +0,0 @@ -package org.nuiton.wikitty.generator; - -import java.io.File; -import java.io.IOException; -import java.io.Writer; - -import org.nuiton.eugene.models.object.ObjectModelInterface; -import org.nuiton.eugene.models.object.ObjectModelOperation; - -public class InterfaceGenerator extends WikengoCommonGenerator { - - @Override - public String getFilenameForInterface(ObjectModelInterface interfacez) { - String fqn = interfacez.getQualifiedName(); - return fqn.replace('.', File.separatorChar) + ".java"; - } - - @Override - public void generateFromInterface(Writer output, - ObjectModelInterface interfacez) throws IOException { - // Generate only is not stereotype is specified - if (!interfacez.getStereotypes().isEmpty()) { - return; - } - - generateCopyright(output); - - String packageName = interfacez.getPackageName(); - String name = interfacez.getName(); -/*{package <%=packageName%>; - -}*/ - - clearImports(); - lookForOperationImports(interfacez); - generateImports(output, packageName); - - generateClazzDocumentation(output, interfacez); -/*{public interface <%=name%> { - -}*/ - - for (ObjectModelOperation op : interfacez.getOperations()) { - generateOperationHeader(output, op, true); - } - -/*{} //<%=name%> -}*/ - - } - -} Deleted: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikengoCommonGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikengoCommonGenerator.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikengoCommonGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -1,727 +0,0 @@ -package org.nuiton.wikitty.generator; - -import java.io.IOException; -import java.io.Writer; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.eugene.GeneratorUtil; -import org.nuiton.eugene.java.ImportsManager; -import org.nuiton.eugene.models.object.ObjectModel; -import org.nuiton.eugene.models.object.ObjectModelAttribute; -import org.nuiton.eugene.models.object.ObjectModelClass; -import org.nuiton.eugene.models.object.ObjectModelClassifier; -import org.nuiton.eugene.models.object.ObjectModelDependency; -import org.nuiton.eugene.models.object.ObjectModelElement; -import org.nuiton.eugene.models.object.ObjectModelGenerator; -import org.nuiton.eugene.models.object.ObjectModelOperation; -import org.nuiton.eugene.models.object.ObjectModelParameter; - -public class WikengoCommonGenerator extends ObjectModelGenerator { - - private static final Log log = LogFactory.getLog(WikengoCommonGenerator.class); - - protected ImportsManager imports; - - protected void clearImports() { - if (imports == null) { - imports = new ImportsManager(); - } else { - imports.clearImports(); - } - } - - @Override - protected boolean canGenerateElement(Object element) { - - boolean canGenerate = true; - - if (element instanceof ObjectModel) { - // fail with no model name - canGenerate = false; - } - else { - canGenerate = super.canGenerateElement(element); - } - return canGenerate; - } - - protected void addImport(String fqn) { - if (containsClassAndGeneric(fqn)) { - String[] type = getClassAndGeneric(fqn); - imports.addImport(checkForDatatype(type[0])); - addImport(checkForDatatype(type[1])); - } else if (isArray(fqn)) { - imports.addImport(checkForDatatype(fqn.substring(0, fqn.length() - 2))); - } else if (containsComma(fqn)) { - String[] fqnCommaSeparated = splitByComma(fqn); - for (String str : fqnCommaSeparated) { - if (str != null && !str.isEmpty()) { - addImport(str.trim()); - } - } - } else { - fqn = checkForDatatype(fqn); - imports.addImport(fqn); - } - } - - private String[] splitByComma(String fqn) { - return fqn.split(","); - } - - private boolean containsComma(String fqn) { - return fqn != null && fqn.indexOf(",") != -1; - } - - protected void addImport(Class<?> clazz) { - imports.addImport(clazz); - } - - protected void addImport(ObjectModelClass clazz) { - if (clazz != null) { - addImport(clazz.getQualifiedName()); - } - } - - /** - * Return the minimum syntax for the type. The result depend of import added - * by addImport. - * - * @param fqn the fully qualified name of type - * @return minimum needed type - */ - protected String getType(String fqn) { - String result = getType(fqn, false); - return result; - } - - /** - * Return the minimum syntax for the type. The result depend of import added - * by addImport. - * - * @param fqn the fully qualified name of type - * @param convert if true try to convert some type to other - * (ex: enum to string, dto to string) - * @return minimum needed type - */ - protected String getType(String fqn, boolean convert) { - // if type is Wikitty then we used String - if ("org.nuiton.wikitty.Wikitty".equals(fqn) - || "Wikitty".equals(fqn)) { - fqn = "String"; - } else if (convert && null != getModel().getEnumeration(fqn)) { - // if type is Wikitty then we used String - fqn = "String"; - } else if (convert && getModel().hasClass(fqn) - && EugengoUtils.isBusinessEntity(getModel().getClass(fqn))) { - // for wikittyDto we use String for Id - fqn = "String"; - } - - if (containsClassAndGeneric(fqn)) { - String[] type = getClassAndGeneric(fqn); - return imports.getType(checkForDatatype(type[0])) + "<" + getType(type[1], convert) + ">"; - } else if (containsComma(fqn)) { - String result = ""; - for (String str : splitByComma(fqn)) { - if (str != null && !str.isEmpty()) { - if (!result.isEmpty()) { - result += ", "; - } - result += str.trim(); - } - } - return result; - } else { - return imports.getType(checkForDatatype(fqn)); - } - } - - protected boolean isArray(String fqn) { - return fqn != null && fqn.trim().endsWith("[]"); - } - - protected boolean containsClassAndGeneric(String fqn) { - return fqn != null && fqn.indexOf("<") != -1; - } - - protected String[] getClassAndGeneric(String fqn) { - int idx = fqn.indexOf("<"); - String[] result = new String[2]; - result[0] = fqn.substring(0, idx); - result[1] = fqn.substring(idx+1, fqn.length() - 1); - return result; - } - - protected void generateImports(Writer output, String currentPackage) throws IOException { - List<String> imports = this.imports.getImports(currentPackage); - if (!imports.isEmpty()) { - for (String importLine : imports) { -/*{import <%=importLine%>; -}*/ - } -/*{ -}*/ - } - } - - protected void generateCopyright(Writer output) throws IOException { - String copyright = EugengoUtils.getCopyright(model); - if (GeneratorUtil.notEmpty(copyright)) { -/*{<%=copyright%> -}*/ - } - } - - protected void generateClazzDocumentation(Writer output, ObjectModelClassifier classifier, String ... defaultDoc) - throws IOException { - generateDocumentation(output, classifier, "", defaultDoc); - } - - protected void generateDocumentation(Writer output, ObjectModelElement element, String prefix, String ... defaultDoc) - throws IOException { - String doc = null; - if (GeneratorUtil.hasDocumentation(element)) { - doc = element.getDocumentation(); - } /*else { - TODO Manage defaultDoc - }*/ - - if (doc != null) { - // Manage RC in the doc - Pattern p = Pattern.compile("(\n)"); - Matcher m = p.matcher(doc); - String docOk = m.replaceAll("\n"+prefix+" * "); - -/*{<%=prefix%>/** -<%=prefix%> * <%=docOk%> -<%=prefix%> *) -}*/ - } - } - - /** - * Generates a header for the given operation. - * @param output The stream to write inside - * @param op the operation which header is to generate - * @param hasBody need to generate a body ? - * <li>true (for classes) : generates ' {' at the end</li> - * <li>false (for interfaces) : generates ';' at the end</li> - * @param hasBody - * @throws IOException - */ - protected void generateOperationHeader(Writer output, ObjectModelOperation op, - boolean generateForInterface, String ... additionalExceptions) throws IOException { - String opVisibility = op.getVisibility(); - //If generate for interface, only public methods are allowed - if (generateForInterface && !"".equals(opVisibility) && !"public".equals(opVisibility)) { - return; - } - String opName = op.getName(); -/*{ // Operation "<%=opName%>" -}*/ - generateDocumentation(output, op, " "); - if (generateForInterface || "package".equals(opVisibility)) { - opVisibility = ""; - } else { - opVisibility += " "; - } - String opType = computeType(op.getReturnParameter()); - opType = getType(opType); - String opAbstract = ""; - if (!generateForInterface && op.isAbstract()) { - opAbstract = "abstract "; - } -/*{ <%=opVisibility%><%=opAbstract%><%=opType%> <%=opName%>(}*/ - boolean isFirst = true; - for (ObjectModelParameter opParam : op.getParameters()) { - String paramName = opParam.getName(); - String paramType = computeType(opParam); - paramType = getType(paramType); - if (!isFirst) { -/*{, }*/ - } - isFirst = false; -/*{<%=paramType%> <%=paramName%>}*/ - } -/*{)}*/ - if ((op.getExceptions() != null && !op.getExceptions().isEmpty()) || (additionalExceptions != null && additionalExceptions.length > 0)) { -/*{ throws}*/ - isFirst = true; - Set<String> exceptions = new LinkedHashSet<String>(); - - if (additionalExceptions != null) { - for (String exception : additionalExceptions) { - exceptions.add(exception); - } - } - if (op.getExceptions() != null) { - for (String exception : op.getExceptions()) { - exceptions.add(exception); - } - } - for (String exception : exceptions) { - exception = getType(exception); - if (!isFirst) { -/*{,}*/ - } - isFirst = false; -/*{ <%=exception%>}*/ - } - } - if (generateForInterface || op.isAbstract()) { -/*{; - -}*/ - } else { -/*{ { -}*/ - } - } - - /** - * Generates a ioc name and injection. Will generate the class attribute - * and getter/setter. - * The name used is the name specified in the dependency class name. - * @param output The stream to write inside - * @param dep the dependency to generate. - * @throws IOException - */ - protected void generateIocDependency(Writer output, ObjectModelDependency dep) - throws IOException { - ObjectModelClassifier supplier = dep.getSupplier(); - if (supplier == null || EugengoUtils.isDao(supplier)) { - return; - } - String supplierType = getType(supplier.getQualifiedName()); - String supplierVarName = EugengoUtils.toLowerCaseFirstLetter(supplier.getName()); - String supplierMethodSuffix = EugengoUtils.toUpperCaseFirstLetter(supplier.getName()); -/*{ // Dependency injection for "<%=supplierVarName%>" - private <%=supplierType%> <%=supplierVarName%>; - - public <%=supplierType%> get<%=supplierMethodSuffix%>() { - return <%=supplierVarName%>; - } - - public void set<%=supplierMethodSuffix%>(<%=supplierType%> <%=supplierVarName%>) { - this.<%=supplierVarName%> = <%=supplierVarName%>; - } - -}*/ - } - - protected void generateAttributesDeclaration(Writer output, - ObjectModelClass clazz) throws IOException { - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && !attr.isStatic() && (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { - generateAttributeDeclaration(output, attr); - } - } - } - - protected void generateAttributeDeclaration(Writer output, ObjectModelAttribute attr) - throws IOException { - String attrType = computeType(attr); - if (EugengoUtils.notEmpty(attrType)) { - attrType = getType(attrType); - } else { - return; - } - String attrVisibility = attr.getVisibility(); - String attrName = attr.getName(); -/*{ // Declaration of attribute "<%=attrName%>" -}*/ - generateDocumentation(output, attr, " "); - String value = computeDefaultValue(attr); -/*{ <%=attrVisibility%> <%=attrType%> <%=attrName%><%=value%>; - -}*/ - } - - /** - * Compute correct type of param. If param is - * <li> null : void - * <li> cardinality > 1 : Collection of type - * <li> cardinality > 1 and ordered: List of type - * <li> cardinality > 1 and unique: Set of type - * <li> other : the type - * @param param - * @return - */ - protected String computeType(ObjectModelParameter param) { - if (param == null) { - return "void"; - } - String result = param.getType(); - - // if type is Wikitty then we used String - if ("org.nuiton.wikitty.Wikitty".equals(result) - || "Wikitty".equals(result)) { - result = "String"; - } - - boolean isCollection = (param.getMaxMultiplicity() != 0 - && param.getMaxMultiplicity() != 1); - if (isCollection) { - Class<?> type = Collection.class; - if (param.isOrdered()) { - type = List.class; - } - if (param.isUnique()) { - type = Set.class; - } - result = type.getName() + "<" + result + ">"; - } - return result; - } - - protected void generateAttributesAccessors(Writer output, - ObjectModelClass clazz) throws IOException { - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && !attr.isStatic() && (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { - generateAttributeAccessors(output, attr); - } - } - } - - protected void generateAttributeAccessors(Writer output, ObjectModelAttribute attr) - throws IOException { - String attrType = computeType(attr); - if (EugengoUtils.notEmpty(attrType)) { - attrType = getType(attrType); - } else { - return; - } - String attrName = attr.getName(); - String attrNameCapitalized = EugengoUtils.toUpperCaseFirstLetter(attrName); -/*{ // Accessors for attribute "<%=attrName%>" - public void set<%=attrNameCapitalized%>(<%=attrType%> <%=attrName%>) { - this.<%=attrName%> = <%=attrName%>; - } - - public <%=attrType%> get<%=attrNameCapitalized%>() { - return this.<%=attrName%>; - } - -}*/ - } - - protected void generateStaticAttributes(Writer output, ObjectModelClass clazz) - throws IOException { - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isStatic() && "public".equals(attr.getVisibility())) { - String type = computeType(attr); - type = getType(type); - String name = attr.getName(); - String value = computeDefaultValue(attr); -/*{ // static attribute "<%=name%>" - public static <%=type%> <%=name%><%=value%>; - -}*/ - } - } - } - - protected String computeDefaultValue(ObjectModelAttribute attr) { - String result = ""; - String value = attr.getDefaultValue(); - if (value != null) { - String type = computeType(attr); - type = getType(type); - if ("String".equals(type)) { - result = "\"" + value + "\""; - } else if ("boolean".equalsIgnoreCase(type)) { - result = "Boolean." + ("true".equalsIgnoreCase(value) + "").toUpperCase(); - } else if ("byte".equalsIgnoreCase(type) || "short".equalsIgnoreCase(type) || "int".equalsIgnoreCase(type) || "integer".equalsIgnoreCase(type)) { - result = value; - } else if ("long".equalsIgnoreCase(type)) { - result = value + "L"; - } else if ("float".equalsIgnoreCase(type)) { - result = value + "F"; - } else if ("double".equalsIgnoreCase(type)) { - result = value + "D"; - } else if ("Date".equals(type)) { - try { - Date d = new SimpleDateFormat().parse(value); - result = "new Date(" + d.getTime() + "l)"; - } catch (ParseException pe) { - log.warn("Unable to parse date", pe); - // Nothing else to do - } - } else { - result = value; - } - result = " = " + result; - } - return result; - } - - protected void generateDefaultConstructor(Writer output, String name) - throws IOException { -/*{ /** - * Default constructor - *) - public <%=name%>() { - super(); - } - -}*/ - } - - protected void generateExceptionConstructors(Writer output, ObjectModelClass clazz) - throws IOException { - String name = clazz.getName(); - generateDefaultConstructor(output, name); - -/*{ public <%=name%>(Throwable cause) { - super(); - initCause(cause); - } - -}*/ - } - - protected void generateFullConstructor(Writer output, - String name, Collection<ObjectModelAttribute> attrs) throws IOException { - int nb = 0; - int total = 0; - if (hasNavigableAndNonStaticAttributes(attrs)) { -/*{ /** - * Constructor with all parameters initialized - * -}*/ - for (ObjectModelAttribute attr : attrs) { - if (attr.isNavigable() && !attr.isStatic() && (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { - total ++; - String attName = attr.getName(); -/*{ * @param <%=attName%> -}*/ - } - } - -/*{ *) - public <%=name%>(}*/ - for (ObjectModelAttribute attr : attrs) { - if (attr.isNavigable() && !attr.isStatic() && (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { - String attrName = attr.getName(); - String attrType = getType(computeType(attr)); - if (EugengoUtils.notEmpty(attrType)) { - attrType = getType(attrType); - } else { - return; - } -/*{<%=attrType%> <%=attrName%>}*/ - nb ++; - if (nb < total){ -/*{, }*/ - } - } - } -/*{) { - super(); -}*/ - for (ObjectModelAttribute attr : attrs) { - if (attr.isNavigable() && !attr.isStatic() && (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { - String attrName = attr.getName(); -/*{ this.<%=attrName%> = <%=attrName%>; -}*/ - } - } - -/*{ } - -}*/ - } - } - - protected boolean hasNavigableAndNonStaticAttributes(ObjectModelClass clazz) { - return hasNavigableAndNonStaticAttributes(clazz.getAttributes()); - } - - protected boolean hasNavigableAndNonStaticAttributes(Collection<ObjectModelAttribute> attrs) { - if (attrs != null && !attrs.isEmpty()) { - for (ObjectModelAttribute attr : attrs) { - if (attr.isNavigable() && !attr.isStatic()) { - return true; - } - } - } - return false; - } - - /** - * Run throw the given ObjectModelClass and declare as an import each found - * attribute type - * @param clazz the class to run throw - */ - protected void lookForAttributeImports(ObjectModelClass clazz) { - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { - String type = computeType(attr); - addImport(type); - } - } - } - - /** - * Run throw the given ObjectModelClass and declare as an import each found - * static attribute type - * @param clazz the class to run throw - */ - protected void lookForStaticAttributeImports(ObjectModelClass clazz) { - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && attr.isStatic() && (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { - String type = computeType(attr); - addImport(type); - } - } - } - - /** - * Run throw the given ObjectModelClassifier and declare each type found on - * the operation declaration (return type, parameters type, exception - * thrown) - * @param classifier the classifier to run throw - */ - protected void lookForOperationImports(ObjectModelClassifier classifier) { - for (ObjectModelOperation op : classifier.getOperations()) { - String returnType = computeType(op.getReturnParameter()); - addImport(returnType); - for (ObjectModelParameter param : op.getParameters()) { - String paramType = computeType(param); - addImport(paramType); - } - for (String exceptionType : op.getExceptions()) { - addImport(exceptionType); - } - } - } - - /** - * Run throw the given ObjectModelClassifier and declare as an import each - * dependency's type found. The import is added only if the dependency's - * supplier is a service or a dao - * @param classifier the classifier to run throw - */ - protected void lookForIocImports(ObjectModelClassifier classifier) { - for (ObjectModelDependency dep : classifier.getDependencies()) { - ObjectModelClassifier supplier = dep.getSupplier(); - if (supplier != null && EugengoUtils.isService(supplier)) { - addImport(supplier.getQualifiedName()); - } - } - } - - /** - * Look on the model for a tag value that indicates an implementation for - * a specific datatype - * @param type the type to look for a declared implementation - * @return the found type or the original type - */ - protected String checkForDatatype(String type) { - if (type != null) { - // Look for simple dataType - String tag = model.getTagValue(EugengoConstants.PREFIX_DATATYPE + type); - if (tag != null) { - return tag; - } - // Look for generic dataType - int idx = type.indexOf("<"); - if (idx != -1) { - tag = model.getTagValue(EugengoConstants.PREFIX_DATATYPE + type.substring(0, idx)); - } - if (tag != null) { - return tag; - } - } - // No dataType found, return type - return type; - } - - /** - * Run throw the superclasses to get the first one. - * - * @param clazz the class to run throw - * @return the first found superClass or null - */ - protected ObjectModelClass findSuperClass(ObjectModelClass clazz) { - if (clazz.getSuperclasses() != null && !clazz.getSuperclasses().isEmpty()) { - return clazz.getSuperclasses().iterator().next(); - } - return null; - } - - protected Collection<ObjectModelClass> findSubClasses(ObjectModelClass clazz) { - Collection<ObjectModelClass> result = new ArrayList<ObjectModelClass>(); - for (ObjectModelClass potentialSubClass : model.getClasses()) { - if (clazz.equals(findSuperClass(potentialSubClass))) { - result.add(potentialSubClass); - } - } - return result; - } - - protected void generateHashCode(Writer output, ObjectModelClass clazz) throws IOException { -/*{ public int hashCode() { - int result = 0; -}*/ - String prefix = ""; - if (EugengoUtils.isEntity(clazz)) { -/*{ if (id != null) { - result = id.hashCode(); - } else { -}*/ - prefix = " "; - } - generateHashCodeFromAttributes(output, clazz, prefix); - if (EugengoUtils.isEntity(clazz)) { -/*{ } -}*/ - } -/*{ return result; - } - -}*/ - } - - private void generateHashCodeFromAttributes(Writer output, ObjectModelClass clazz, String prefix) throws IOException { - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { - String attrName = attr.getName(); - String attrType = getType(attr.getType()); - if (EugengoUtils.isPrimitiveType(attr)) { - // If the leading character is an uppercased letter... - if (attrType.charAt(0) == attrType.toUpperCase().charAt(0)) { -/*{<%=prefix%> if (<%=attrName%> != null) { -<%=prefix%> result = 29 * result + <%=attrName%>.hashCode(); -<%=prefix%> } -}*/ - } else { - attrType = EugengoUtils.toUpperCaseFirstLetter(attrType); - if ("Int".equals(attrType)) { - attrType = "Integer"; - } -/*{<%=prefix%> result = 29 * result + new <%=attrType%>(<%=attrName%>).hashCode(); -}*/ - } - } else { -/*{<%=prefix%> if (<%=attrName%> != null) { -<%=prefix%> result = 29 * result + <%=attrName%>.hashCode(); -<%=prefix%> } -}*/ - } - } - } - } -} Copied: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java (from rev 347, branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java) =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java (rev 0) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyAbstractGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -0,0 +1,497 @@ +package org.nuiton.wikitty.generator; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.Transformer; +import org.nuiton.eugene.java.ObjectModelTransformerToJava; +import org.nuiton.eugene.models.object.ObjectModel; +import org.nuiton.eugene.models.object.ObjectModelAttribute; +import org.nuiton.eugene.models.object.ObjectModelClass; +import org.nuiton.eugene.models.object.ObjectModelInterface; +import org.nuiton.eugene.models.object.ObjectModelModifier; +import org.nuiton.eugene.models.object.ObjectModelOperation; + +/*{generator option: writeString = }*/ +/*{generator option: parentheses = false}*/ +/*{generator option: writeString = +}*/ + +/** + * @plexus.component role="org.nuiton.eugene.Template" role-hint="org.nuiton.wikitty.generator.WikittyAbstractGenerator" + */ +public class WikittyAbstractGenerator extends ObjectModelTransformerToJava { + + private static final Log log = LogFactory.getLog(WikittyAbstractGenerator.class); + + /** map busines entity from source model to generated abstract class */ + protected Map<ObjectModelClass, ObjectModelClass> processedClasses = + new HashMap<ObjectModelClass, ObjectModelClass>(); + + /** pattern to parse toString tagValue + * for the string "abc{foo|bar}defrzeg{uvw|xyz}oeira" + * will match {foo|bar} and {uvw|xyz} with groups for foo, bar, uvw and xyz + */ + protected Pattern p = Pattern.compile("\\{(([^|}])*)(?:\\|([^}]*))?\\}"); + + /** map "Client.name" to "getName()" or any getter to read this attribute */ + protected Map<String, String> attributeToGetterName = new HashMap<String, String>(); + + @Override + protected Transformer<ObjectModel, ObjectModel> initPreviousTransformer() { + return new WikittyPurifierTransformer(); + } + + @Override + public void transformFromModel(ObjectModel model) { + + List<ObjectModelClass> modelBusinessEntities = new ArrayList<ObjectModelClass>(); + + // fill modelBusinessEntities with entities found in model + for (ObjectModelClass clazz : model.getClasses()) { + if (WikittyTransformerUtil.isBusinessEntity(clazz)) { + modelBusinessEntities.add(clazz); + } + } + + for (ObjectModelClass businessEntity : modelBusinessEntities) { + ObjectModelClass abstractClass = createAbstractClass(WikittyTransformerUtil.businessEntityToAbstractName(businessEntity), + businessEntity.getPackageName()); + processedClasses.put(businessEntity, abstractClass); + setSuperClass(abstractClass, "BusinessEntityWikitty"); + addInterface(abstractClass, businessEntity.getQualifiedName()); + } + + for (ObjectModelClass businessEntity : modelBusinessEntities) { + addOperations(businessEntity, processedClasses.get(businessEntity)); + } + + // at this time, all operations in generated abstracts are just the operations + // like get/set etc. we will copy all operations of a given class to all children + // that's why constructors and others operations are not yet added + for (ObjectModelClass businessEntity : modelBusinessEntities) { + addInheritedOperations(businessEntity, processedClasses.get(businessEntity)); + } + + for (ObjectModelClass businessEntity : modelBusinessEntities) { + ObjectModelClass abstractClassForThisEntity = processedClasses.get(businessEntity); + addImports(abstractClassForThisEntity); + addConstructors(abstractClassForThisEntity); + addConstants(businessEntity, abstractClassForThisEntity); + addToString(businessEntity, abstractClassForThisEntity); + } + + // for all classes of model, check if steroptyped with "meta" + for (ObjectModelClass clazz : model.getClasses()) { + if (WikittyTransformerUtil.isMetaExtension(clazz)) { + // if so, add operations + addMetaExtensionOperations(clazz, processedClasses.get(clazz)); + } + } + + processedClasses.clear(); + } + + protected void addImports(ObjectModelClass clazz) { + // TODO 20100811 bleny remove unused imports + addImport(clazz, WikittyTransformerUtil.BUSINESS_ENTITY_CLASS_FQN); + addImport(clazz, WikittyTransformerUtil.BUSINESS_ENTITY_WIKITTY_CLASS_FQN); + addImport(clazz, WikittyTransformerUtil.WIKITTY_CLASS_FQN); + addImport(clazz, "org.nuiton.wikitty.WikittyExtension"); + addImport(clazz, "org.nuiton.wikitty.WikittyUtil"); + addImport(clazz, "org.nuiton.wikitty.WikittyUser"); + addImport(clazz, "org.nuiton.wikitty.WikittyUserAbstract"); + addImport(clazz, "org.nuiton.wikitty.WikittyUserImpl"); + addImport(clazz, "org.nuiton.wikitty.TreeNode"); + addImport(clazz, "org.nuiton.wikitty.TreeNodeAbstract"); + addImport(clazz, "org.nuiton.wikitty.TreeNodeImpl"); + addImport(clazz, java.util.List.class); + addImport(clazz, java.util.ArrayList.class); + addImport(clazz, java.util.Collection.class); + addImport(clazz, java.util.Collections.class); + addImport(clazz, java.util.Set.class); + addImport(clazz, java.util.Date.class); + addImport(clazz, java.util.LinkedHashSet.class); + } + + protected void addSerialVersionUID(ObjectModelClass clazz) { + // adding a generated serialVersionUID + Random random = new Random(); + Long serialVersionUIDs = random.nextLong(); + addConstant(clazz, + "serialVersionUID", + "long", + serialVersionUIDs.toString() + "L", + ObjectModelModifier.PRIVATE); + } + + protected void addConstructors(ObjectModelClass clazz) { + + ObjectModelOperation constructor = addConstructor(clazz, ObjectModelModifier.PUBLIC); + setOperationBody(constructor, "" +/*{ + super(); +}*/); + + constructor = addConstructor(clazz, ObjectModelModifier.PUBLIC); + addParameter(constructor, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "wikitty"); + setOperationBody(constructor, "" +/*{ + super(wikitty); +}*/); + + constructor = addConstructor(clazz, ObjectModelModifier.PUBLIC); + addParameter(constructor, WikittyTransformerUtil.BUSINESS_ENTITY_WIKITTY_CLASS_FQN, "businessEntityWikitty"); + setOperationBody(constructor, "" +/*{ + super(businessEntityWikitty.getWikitty()); +}*/); + + } + + protected void addConstants(ObjectModelClass businessEntity, ObjectModelClass abstractClass) { + // adding some constants about extension to abstract + addConstant(abstractClass, "extensions", "List<WikittyExtension>", null, ObjectModelModifier.PUBLIC); + addConstant(abstractClass, "extension" + businessEntity.getName(), "WikittyExtension", null, ObjectModelModifier.PUBLIC); + + // ... and a getter + ObjectModelOperation getStaticExtensions = addOperation(abstractClass, "getStaticExtensions", "Collection<WikittyExtension>", ObjectModelModifier.PUBLIC); + addAnnotation(abstractClass, getStaticExtensions, "Override"); + setOperationBody(getStaticExtensions, "" +/*{ + return extensions; +}*/); + + //// preparing a static block to initialize those constants + ObjectModelOperation staticInitialization = addBlock(abstractClass, ObjectModelModifier.STATIC); + + // generating constructor call for extensionClient + // we will build a string to write a call + List<String> buildFieldMapExtensionParameters = new ArrayList<String>(); + + + + // now process attributes + for(ObjectModelAttribute attribute : businessEntity.getAttributes()) { + if (attribute.isNavigable()) { + // now add the attribute to the piece of code that build the extension + String wikittyType = WikittyTransformerUtil.typeToWikittyColumn(attribute.getType()); + String multiplicity = ""; + if (attribute.getMinMultiplicity() != 1 || + attribute.getMaxMultiplicity() != 1) { + // generate a string like [1-10] or [0-*] etc. + multiplicity = "[" + + attribute.getMinMultiplicity() + + "-" + + (attribute.getMaxMultiplicity() == -1 ? "*" : attribute.getMaxMultiplicity()) + + "]"; + } + + // generate a string line like " unique=true" or "" + String unique = attribute.isUnique() ? " unique=true" : ""; + // generate a string line like " deprecated=true" or "" + String deprecated = attribute.hasTagValue("deprecated") ? " deprecated=" + attribute.getTagValue("deprecated") : ""; + // generate a string line like ' documentation="my documentation"' or "" + String attributeDocumentation = attribute.hasTagValue("documentation") ? " documentation=\\\"" + attribute.getTagValue("documentation") + "\\\"": ""; + // generate a string like " notNull=true" or "" + String notNull = attribute.hasTagValue("notNull") ? " notNull=" + attribute.getTagValue("notNull") : ""; + buildFieldMapExtensionParameters.add("" // generate a line like '"Wikitty attributName[0-*] unique=true deprecated=true documentation=\"my documentation\""' +/*{ "<%=wikittyType%> <%=attribute.getName()%><%=multiplicity%><%=unique%><%=deprecated%><%=notNull%><%=attributeDocumentation%>"}*/); + } + } + + // finishing static block + String extensionVersion = businessEntity.getTagValue("version"); + if (extensionVersion == null || "".equals(extensionVersion)) { + extensionVersion = "1.0"; + log.warn("no version specified in model for " + businessEntity.getQualifiedName() + " using " + extensionVersion); + } + + // a piece of code used in the static block + String requires = null; + for (ObjectModelClass superClass : businessEntity.getSuperclasses()) { + // using "for" but there will be 0 or 1 iteration + requires = WikittyTransformerUtil.classToExtensionVariableName(superClass, true); + } + + String buildFieldMapExtensionParametersInLine = StringUtils.join(buildFieldMapExtensionParameters, ", \n"); + String extensionVariableName = WikittyTransformerUtil.classToExtensionVariableName(businessEntity, false); + String staticInitializationBody = "" +/*{ + extension<%=businessEntity.getName()%> = + new WikittyExtension(<%=extensionVariableName%>, + "<%=extensionVersion%>", // version + <%= requires %>, + WikittyUtil.buildFieldMapExtension( // building field map +<%=buildFieldMapExtensionParametersInLine%>)); + + // init extensions + List<WikittyExtension> exts = new ArrayList<WikittyExtension>(); +}*/; + + for (ObjectModelClass superClass : businessEntity.getSuperclasses()) { + // using "for" but there will be 0 or 1 iteration + staticInitializationBody += "" +/*{ + exts.addAll(<%=superClass.getName()%>Abstract.extensions); + // current after requires ones +}*/; + } + + staticInitializationBody += "" +/*{ + exts.add(extension<%=businessEntity.getName()%>); + extensions = Collections.unmodifiableList(exts); +}*/; + setOperationBody(staticInitialization, staticInitializationBody); + + } + + protected void addOperations(ObjectModelClass businessEntity, ObjectModelClass abstractClass) { + String extensionVariableName = WikittyTransformerUtil.classToExtensionVariableName(businessEntity, true); + String helperClassName = WikittyTransformerUtil.businessEntityToHelperName(businessEntity); + + boolean isMetaExtension = WikittyTransformerUtil.isMetaExtension(businessEntity); + + + // generating operations with bodies to realize contract + for (ObjectModelAttribute attribute : businessEntity.getAttributes()) { + if (attribute.isNavigable()) { + // needed below, in templates + String fieldVariableName = WikittyTransformerUtil.attributeToFielVariableName(attribute, true); + String attributeType = WikittyTransformerUtil.generateResultType(attribute, false); + + String attributeName = attribute.getName(); + if (attribute.hasTagValue(WikittyTransformerUtil.TAG_ALTERNATIVE_NAME)) { + // there is a conflict, purifier transformer give as the right name to use + attributeName = attribute.getTagValue(WikittyTransformerUtil.TAG_ALTERNATIVE_NAME); + } + + String getterName = null; + + if (WikittyTransformerUtil.isAttributeCollection(attribute)) { + // attributed is a collection, we will generate operations get, add, remove and clear + + String attributeTypeSimpleNameInSet = WikittyTransformerUtil.generateResultType(attribute, true); + String getFieldMethodName = WikittyTransformerUtil.generateGetFieldAsCall(attribute); + + // now, for this attribute, we will generate add, remove and clear methods + // adding operations to contract + getterName = "get" + StringUtils.capitalize(attributeName); + ObjectModelOperation getter = addOperation(abstractClass, getterName, attributeTypeSimpleNameInSet); + addAnnotation(abstractClass, getter, "Override"); + String getterBody; + if (isMetaExtension) { + getterBody = "" +/*{ + <%=attributeTypeSimpleNameInSet%> result; + if (extensionForMetaExtension == null) { + result = <%=helperClassName%>.<%=getterName%>(getWikitty()); + } else { + result = <%=helperClassName%>.<%=getterName%>(extensionForMetaExtension, getWikitty()); + } + return result; +}*/; + } else { + getterBody = "" +/*{ + <%=attributeTypeSimpleNameInSet%> result = <%=helperClassName%>.<%=getterName%>(getWikitty()); + return result; +}*/; + } + setOperationBody(getter, getterBody); + + String addName = "add" + StringUtils.capitalize(attributeName); + ObjectModelOperation adder = addOperation(abstractClass, addName, "void"); + addAnnotation(abstractClass, adder, "Override"); + addParameter(adder, "String", "element"); + String adderBody; + if (isMetaExtension) { + adderBody = "" +/*{ + if (extensionForMetaExtension == null) { + <%=helperClassName%>.<%=addName%>(getWikitty(), element); + getPropertyChangeSupport().firePropertyChange(<%=fieldVariableName%>, null, <%= getter.getName() %>()); + } else { + <%=helperClassName%>.<%=addName%>(extensionForMetaExtension, getWikitty(), element); + String fieldName = <%=helperClassName%>.getMetaFieldName(extensionForMetaExtension, "<%=attributeName%>"); + getPropertyChangeSupport().firePropertyChange(fieldName, null, <%= getter.getName() %>()); + } +}*/; + } else { + adderBody = "" +/*{ + <%=helperClassName%>.<%=addName%>(getWikitty(), element); + getPropertyChangeSupport().firePropertyChange(<%=fieldVariableName%>, null, <%= getter.getName() %>()); +}*/; + } + setOperationBody(adder, adderBody); + + String removeName = "remove" + StringUtils.capitalize(attributeName); + ObjectModelOperation remover = addOperation(abstractClass, removeName, "void"); + addAnnotation(abstractClass, remover, "Override"); + addParameter(remover, "String", "element"); + String removerBody = "" +/*{ + <%=helperClassName%>.<%=removeName%>(getWikitty(), element); + getPropertyChangeSupport().firePropertyChange(<%=fieldVariableName%>, null, <%=getter.getName()%>()); +}*/; + setOperationBody(remover, removerBody); + + String clearName = "clear" + StringUtils.capitalize(attributeName); + ObjectModelOperation clear = addOperation(abstractClass, clearName, "void"); + addAnnotation(abstractClass, clear, "Override"); + String clearBody = "" +/*{ + <%=helperClassName%>.<%=clearName%>(getWikitty()); + getPropertyChangeSupport().firePropertyChange(<%=fieldVariableName%>, null, <%=getter.getName()%>()); +}*/; + setOperationBody(clear, clearBody); + + + } else { + String getFieldMethodName = WikittyTransformerUtil.generateGetFieldAsCall(attribute); + + // adding getter and setter to contract + getterName = "get" + StringUtils.capitalize(attributeName); + ObjectModelOperation getter = addOperation(abstractClass, getterName, attributeType); + addAnnotation(abstractClass, getter, "Override"); + setOperationBody(getter, "" +/*{ + <%=attributeType%> value = <%=helperClassName%>.<%=getterName%>(getWikitty()); + return value; +}*/); + + String setterName = "set" + StringUtils.capitalize(attributeName); + ObjectModelOperation setter = addOperation(abstractClass, setterName, attributeType); + addAnnotation(abstractClass, setter, "Override"); + addParameter(setter, attributeType, attributeName); + setOperationBody(setter, "" +/*{ + <%=attributeType%> oldValue = <%=helperClassName%>.<%=setterName%>(getWikitty(), <%=attributeName%>); + getPropertyChangeSupport().firePropertyChange(<%=fieldVariableName%>, oldValue, <%=getter.getName()%>()); + return oldValue; +}*/); + } + + // save the getter name for this attribute + attributeToGetterName.put(businessEntity.getName() + "." + attributeName, getterName); + } + } + } + + protected void addInheritedOperations(ObjectModelClass businessEntity, ObjectModelClass abstractClass) { + // now, add to this abstract all operation due to inheritence from + // other business entities + + for (ObjectModelClass superClass : businessEntity.getSuperclasses()) { + + // if super class is not in the same package, import it Helper + if (! businessEntity.getPackageName().equals(superClass.getPackageName())) { + addImport(abstractClass, superClass.getPackageName() + "." + + WikittyTransformerUtil.businessEntityToHelperName(superClass)); + } + + if (WikittyTransformerUtil.isBusinessEntity(superClass)) { + addInterface(abstractClass, WikittyTransformerUtil.businessEntityToContractName(superClass)); // extends + // getting the signatures and bodies of those operations + for (ObjectModelOperation operation : processedClasses.get(superClass).getOperations()) { + + ObjectModelOperation operationClone = cloneOperationSignature(operation, abstractClass, true); + setOperationBody(operationClone, operation.getBodyCode()); + + // XXX 20100816 bleny should be a call to cloneOperation(operation, abstractClass, true); + } + } else { + addInterface(abstractClass, superClass.getQualifiedName()); // extends + } + } + } + + /** add a toString method + * if a toString is tagValue is attached to businessEntity, it will be used + * to generate a toString as this : + * + * given "hello {Person.name|unknow}" + * + * will try to replace first {...} by name field value for extension Person. + * if this information is not available, will do unknow. + */ + protected void addToString(ObjectModelClass businessEntity, ObjectModelClass abstractClass) { + + String toStringOperationBody = null; + + if (businessEntity.hasTagValue(WikittyTransformerUtil.TAG_TO_STRING)) { + String toStringPattern = businessEntity.getTagValue(WikittyTransformerUtil.TAG_TO_STRING); + + // toStringPattern is something like + // "hello {Person.name|unknow} employe of {Company.name|unknow}" + // + + Matcher matcher = p.matcher(toStringPattern); + + while (matcher.find()) { + String wholeMatch = matcher.group(0); // "{foo|bar}" + String variableName = matcher.group(1); // "foo" + String defaultValue = matcher.group(3); // "bar", may be null + + if (defaultValue == null) { + defaultValue = ""; + } + + if (attributeToGetterName.containsKey(variableName)) { + String getterName = attributeToGetterName.get(variableName); + toStringPattern = toStringPattern.replace(wholeMatch, "" +/*{" + + <%=getterName%>().toString() + + "}*/); + } else { + log.warn("no field " + variableName + " in " + businessEntity.getQualifiedName()); + toStringPattern = toStringPattern.replace(wholeMatch, defaultValue); + } + } + + toStringOperationBody = "" +/*{ + return "<%=toStringPattern%>"; +}*/; + } else { + // no toString tagValue provided, generating a default toString + toStringOperationBody = "" +/*{ + return getWikitty().toString(); +}*/; + } + + ObjectModelOperation toString = addOperation(abstractClass, "toString", "String"); + addAnnotation(abstractClass, toString, "Override"); + setOperationBody(toString, toStringOperationBody); + } + + protected void addMetaExtensionOperations(ObjectModelClass metaExtension, + ObjectModelClass abstractClassForThisMetaExtension) { + + ObjectModelAttribute extension = addAttribute(abstractClassForThisMetaExtension, "extensionForMetaExtension", WikittyTransformerUtil.WIKITTY_EXTENSION_CLASS_FQN); + setDocumentation(extension, "the metaExtension operations target this extension, may be null"); + + ObjectModelOperation addMetaExtension = addOperation(abstractClassForThisMetaExtension, "addMetaExtension", "void"); + addAnnotation(abstractClassForThisMetaExtension, addMetaExtension, "Override"); + addParameter(addMetaExtension, WikittyTransformerUtil.WIKITTY_EXTENSION_CLASS_FQN, "extension"); + setDocumentation(addMetaExtension, String.format( + "add %s meta-extension on given extension to this entity", + metaExtension.getName())); + String helperName = WikittyTransformerUtil.businessEntityToHelperName(metaExtension); + setOperationBody(addMetaExtension, "" +/*{ + extensionForMetaExtension = extension; + <%=helperName%>.addMetaExtension(extension, getWikitty()); +}*/); + } +} Copied: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java (from rev 347, branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java) =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java (rev 0) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyContractGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -0,0 +1,252 @@ +package org.nuiton.wikitty.generator; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.Transformer; +import org.nuiton.eugene.java.ObjectModelTransformerToJava; +import org.nuiton.eugene.models.object.ObjectModel; +import org.nuiton.eugene.models.object.ObjectModelAttribute; +import org.nuiton.eugene.models.object.ObjectModelClass; +import org.nuiton.eugene.models.object.ObjectModelInterface; +import org.nuiton.eugene.models.object.ObjectModelModifier; +import org.nuiton.eugene.models.object.ObjectModelOperation; + +/*{generator option: writeString = }*/ +/*{generator option: parentheses = false}*/ +/*{generator option: writeString = +}*/ + +/** + * @plexus.component role="org.nuiton.eugene.Template" role-hint="org.nuiton.wikitty.generator.WikittyContractGenerator" + */ +public class WikittyContractGenerator extends ObjectModelTransformerToJava { + + private static final Log log = LogFactory.getLog(WikittyContractGenerator.class); + + @Override + protected Transformer<ObjectModel, ObjectModel> initPreviousTransformer() { + return new WikittyPurifierTransformer(); + } + + /** will permet to get the result of a processed class + * it is useful for dealing with inheritence : when an extension depend + * of another. In this case the child can find the processed class of the parent + * and then look into it to find methods and data to copy + */ + protected Map<ObjectModelClass, ObjectModelInterface> processedClasses = + new HashMap<ObjectModelClass, ObjectModelInterface>(); + + protected Set<ObjectModelClass> processedEntities = new HashSet<ObjectModelClass>(); + + @Override + public void transformFromModel(ObjectModel model) { + + log.info(model.getClasses().size() + " classes to process"); + + for (ObjectModelClass clazz : model.getClasses()) { + if (WikittyTransformerUtil.isBusinessEntity(clazz)) { + processEntity(clazz); + } + } + + for (ObjectModelClass clazz : model.getClasses()) { + if (WikittyTransformerUtil.isMetaExtension(clazz)) { + processMetaExtension(clazz); + } + } + + processedClasses.clear(); + processedEntities.clear(); + } + + /** contains code commons to entities and meta-extensions */ + protected ObjectModelInterface prepareOutputClass(ObjectModelClass businessEntity) { + + ObjectModelInterface contract = processedClasses.get(businessEntity); + + if (contract == null) { + + log.debug("preparing " + businessEntity.getPackageName() + + "." + businessEntity.getName()); + + contract = createInterface(WikittyTransformerUtil.businessEntityToContractName(businessEntity), + businessEntity.getPackageName()); + addInterface(contract, WikittyTransformerUtil.BUSINESS_ENTITY_CLASS_FQN); + + // TODO 20100811 bleny remove unused imports + addImport(contract, WikittyTransformerUtil.BUSINESS_ENTITY_CLASS_FQN); + addImport(contract, WikittyTransformerUtil.BUSINESS_ENTITY_WIKITTY_CLASS_FQN); + addImport(contract, WikittyTransformerUtil.WIKITTY_CLASS_FQN); + addImport(contract, "org.nuiton.wikitty.WikittyExtension"); + addImport(contract, "org.nuiton.wikitty.WikittyUtil"); + addImport(contract, "org.nuiton.wikitty.WikittyUser"); + addImport(contract, "org.nuiton.wikitty.WikittyUserAbstract"); + addImport(contract, "org.nuiton.wikitty.WikittyUserImpl"); + addImport(contract, "org.nuiton.wikitty.TreeNode"); + addImport(contract, "org.nuiton.wikitty.TreeNodeAbstract"); + addImport(contract, "org.nuiton.wikitty.TreeNodeImpl"); + addImport(contract, java.util.List.class); + addImport(contract, java.util.ArrayList.class); + addImport(contract, java.util.Collection.class); + addImport(contract, java.util.Collections.class); + addImport(contract, java.util.Set.class); + addImport(contract, java.util.Date.class); + addImport(contract, java.util.LinkedHashSet.class); + + String documentation = businessEntity.getDocumentation(); + if (businessEntity.hasTagValue(WikittyTransformerUtil.TAG_DOCUMENTATION)) { + documentation += "\n\n"; + documentation += businessEntity.getTagValue(WikittyTransformerUtil.TAG_DOCUMENTATION); + } + + setDocumentation(contract, documentation); + + processedClasses.put(businessEntity, contract); + + } else { + log.debug("already prepared : " + businessEntity.getPackageName() + + "." + businessEntity.getName()); + } + + return contract; + } + + protected void processEntity(ObjectModelClass businessEntity) { + + if ( processedEntities.contains(businessEntity) ) { + log.debug("entity already processed : " + businessEntity.getPackageName() + + "." + businessEntity.getName()); + // already processed + return ; + } + + log.debug("processing entity : " + businessEntity.getPackageName() + + "." + businessEntity.getName()); + + ObjectModelInterface contract = prepareOutputClass(businessEntity); + + + // adding public static final String EXT_CLIENT = "Client"; + addConstant(contract, + "EXT_" + businessEntity.getName().toUpperCase(), + "String", + "\"" + businessEntity.getName() + "\"", + ObjectModelModifier.PUBLIC); + + String extensionVariableName = WikittyTransformerUtil.classToExtensionVariableName(businessEntity, false); + + for(ObjectModelAttribute attribute : businessEntity.getAttributes()) { + if (attribute.isNavigable()) { + // two variables needed below + String fieldVariableName = WikittyTransformerUtil.attributeToFielVariableName(attribute, false); + + // adding constants to contract + addConstant(contract, + fieldVariableName, + "String", + "\"" + attribute.getName() + "\"", + ObjectModelModifier.PUBLIC); + // adding public static final String FQ_FIELD_CLIENT_NAME = EXT_CLIENT + ".name"; + addConstant(contract, + "FQ_" + fieldVariableName, + "String", + extensionVariableName + " + \"." + attribute.getName() + "\"", + ObjectModelModifier.PUBLIC); + } + } + + for (ObjectModelAttribute attribute : businessEntity.getAttributes()) { + if (attribute.isNavigable()) { + // needed below, in templates + String fieldVariableName = WikittyTransformerUtil.attributeToFielVariableName(attribute, true); + String attributeType = WikittyTransformerUtil.generateResultType(attribute, false); + + String attributeName = attribute.getName(); + if (attribute.hasTagValue(WikittyTransformerUtil.TAG_ALTERNATIVE_NAME)) { + // there is a conflict, purifier transformer give as the right name to use + attributeName = attribute.getTagValue(WikittyTransformerUtil.TAG_ALTERNATIVE_NAME); + } + + ObjectModelOperation getter; + + if (attribute.getMaxMultiplicity() > 1 || attribute.getMaxMultiplicity() == -1) { + // attributed is a collection, we will generate operations get, add, remove and clear + + String attributeTypeSimpleNameInSet = WikittyTransformerUtil.generateResultType(attribute, true); + + // now, for this attribute, we will generate add, remove and clear methods + // adding operations to contract + String getterName = "get" + StringUtils.capitalize(attributeName); + getter = addOperation(contract, getterName, attributeTypeSimpleNameInSet); + + String addName = "add" + StringUtils.capitalize(attributeName); + ObjectModelOperation adder = addOperation(contract, addName, "void"); + addParameter(adder, "String", "element"); + + String removeName = "remove" + StringUtils.capitalize(attributeName); + ObjectModelOperation remover = addOperation(contract, removeName, "void"); + addParameter(remover, "String", "element"); + + String clearName = "clear" + StringUtils.capitalize(attributeName); + addOperation(contract, clearName, "void"); + + } else { + // attribute is not a collection, we generate a getter and a setter + String getterName = "get" + StringUtils.capitalize(attributeName); + getter = addOperation(contract, getterName, attributeType); + + String setterName = "set" + StringUtils.capitalize(attributeName); + ObjectModelOperation setter = addOperation(contract, setterName, attributeType); + addParameter(setter, attributeType, attributeName); + } + + setDocumentation(getter, attribute.getDocumentation()); + } + } + + // now, add to this contract all operation due to inheritence from + // other business entities + Collection<ObjectModelClass> superClasses = businessEntity.getSuperclasses(); + for (ObjectModelClass superClass : superClasses) { + addInterface(contract, superClass.getQualifiedName()); // extends ? + if (WikittyTransformerUtil.isBusinessEntity(superClass)) { + // superclass must have been processed first to have its operations set + if ( ! processedEntities.contains(superClass)) { + log.debug(businessEntity.getName() + " require to process " + + superClass.getName() + " first"); + processEntity(superClass); + } + + // getting the signatures of those operations + for (ObjectModelOperation operation : processedClasses.get(superClass).getOperations()) { + cloneOperationSignature(operation, contract, true); + } + } + } + + processedEntities.add(businessEntity); + } + + /** add stuff if input model element is stereotyped as "meta" */ + protected void processMetaExtension(ObjectModelClass metaExtension) { + log.debug("processing meta-extension : " + metaExtension.getPackageName() + + "." + metaExtension.getName()); + + ObjectModelInterface contract = prepareOutputClass(metaExtension); + + ObjectModelOperation addMetaExtension = addOperation(contract, "addMetaExtension", "void"); + addParameter(addMetaExtension, WikittyTransformerUtil.WIKITTY_EXTENSION_CLASS_FQN, "extension"); + setDocumentation(addMetaExtension, String.format( + "add %s meta-extension on given extension to this entity", + metaExtension.getName())); + + } +} Deleted: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -1,328 +0,0 @@ -package org.nuiton.wikitty.generator; - -import java.io.File; -import java.io.IOException; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import java.util.regex.Pattern; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.eugene.GeneratorUtil; -import org.nuiton.eugene.models.object.ObjectModelAttribute; -import org.nuiton.eugene.models.object.ObjectModelClass; - -/** - * Possible enhancement: - * - generateParentMethod can generate attribut method access that call - * the same method on parent instance class. For that we must have one attribut - * instance by parent. This attribut we must be created in setWikitty method - * and used same wikitty object. - * - * @author poussin - */ -public class WikittyHelperGenerator extends WikengoCommonGenerator { - - private static final Log log = LogFactory.getLog(WikittyHelperGenerator.class); - - static protected Pattern extractTypeOnCollection = Pattern.compile("\\w*<(\\w+)>"); - - protected String EXT_NAME; - - @Override - public String getFilenameForClass(ObjectModelClass clazz) { - String fqn = clazz.getQualifiedName(); - log.info( "Filename for " + clazz.getName() + " is " + fqn.replace('.', File.separatorChar) + ".java"); - return fqn.replace('.', File.separatorChar) + "Helper.java"; - } - - public void generateFromClass(Writer output, ObjectModelClass clazz) - throws IOException { - if (!EugengoUtils.isBusinessEntity(clazz)) { - log.info( clazz.getName() + " is not a business entity"); - return; - } - - log.info("Generate Business entity abstract" + clazz.getName() + "... "); - generateCopyright(output); - - EXT_NAME = "EXT_" + clazz.getName().toUpperCase(); - - String packageName = clazz.getPackageName(); - String name = clazz.getName() + "Helper"; - String nameImpl = clazz.getName() + "Impl"; -/*{package <%=packageName%>; - -}*/ - ObjectModelClass superClass = findSuperClass(clazz); - - clearImports(); - addImport(clazz); - addImport(superClass); - addImport("org.nuiton.wikitty.WikittyUtil"); - addImport("org.nuiton.wikitty.Wikitty"); - addImport("org.nuiton.wikitty.BusinessEntityWikitty"); - addImport("org.nuiton.wikitty.WikittyExtension"); - addImport(Collection.class); - addImport(Collections.class); - addImport(List.class); - addImport(ArrayList.class); - - lookForAttributeImports(clazz); - generateImports(output, packageName); - - generateClazzDocumentation(output, clazz); - - // l'heritage sur le Impl n'est la que pour profiter des constantes deja definies -/*{public class <%=name%> extends <%=nameImpl%> { - -}*/ - - String svUID = GeneratorUtil.computeSerialVersionUID(clazz); -/*{ private static final long serialVersionUID = <%=svUID%>; - -}*/ - -/*{ - /** - * This class is not instanciable, it's just helper - *) - private <%=name%>() { - } - -}*/ - - generateAttributeAccessMethod(output, clazz); - - for (ObjectModelClass parent : clazz.getSuperclasses()) { - if (EugengoUtils.isBusinessEntity(parent)) { - generateParentMethod(output, parent); - } - } - -/*{ - /** - * Check if wikitty has current extension - *) - static public boolean isExtension(Wikitty w) { - boolean result = w.hasExtension(<%=EXT_NAME%>); - return result; - } - - /** - * ajout les extensions static de cette classe au wikitty en argument - *) - static public void addExtension(Wikitty w) { - for (WikittyExtension ext : extensions) { - w.addExtension(ext); - } - } - - /** - * Check equality on all field of this extension, and only those. - *) - static public boolean equals(Wikitty w1, Wikitty w2) { - boolean result = true; -}*/ - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && !attr.isStatic() && - (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { -/*{ if (result) { - Object f1 = w1.getFieldAsObject(<%=EXT_NAME%>, <%=clazz.getName()%>.FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>); - Object f2 = w2.getFieldAsObject(<%=EXT_NAME%>, <%=clazz.getName()%>.FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>); - result = f1 == f2 || (f1 != null && f1.equals(f2)); - } -}*/ - } - } -/*{ - return result; - } - -} //<%=name%> -}*/ - - } - - - - // Utilitarian methods - - public void generateAttributeAccessMethod(Writer output, ObjectModelClass clazz) throws IOException { - for (ObjectModelAttribute attr : clazz.getAttributes()) { - if (attr.isNavigable() && !attr.isStatic() - && (attr.getStereotypes() == null || attr.getStereotypes().isEmpty())) { - if ((attr.getMaxMultiplicity() != 0 && attr.getMaxMultiplicity() != 1)) { - //TODO ymartel 20090812: when dataType "List", "Set" or "Collection" in model, must be here! - generateCollectionAttributeAccessors(output, clazz, attr); - } else { - generateWikittyAttributeAccessors(output, clazz, attr); - } - } - } - } - - private void generateParentMethod(Writer output, - ObjectModelClass clazz) throws IOException { - - // we must generate method for parent of parent - for (ObjectModelClass parent : clazz.getSuperclasses()) { - if (EugengoUtils.isBusinessEntity(parent)) { - generateParentMethod(output, parent); - } - } - - // generate method acces for parent attribut - generateAttributeAccessMethod(output, clazz); - } - - protected void generateWikittyAttributeAccessors(Writer output, - ObjectModelClass clazz, ObjectModelAttribute attr) throws IOException { - - EXT_NAME = "EXT_" + attr.getDeclaringElement().getName().toUpperCase(); - - String attrType = computeType(attr); - if (EugengoUtils.notEmpty(attrType)) { - attrType = getType(attrType, true); - } else { - return; - } - - // FIXME EC-20100421 cette methode peut retourner List<String> - // et generer la methode getWikitty().getFieldAsList<String>() - // qui ne peut pas compiler - String methodAccessName = getFieldAccessMethodName(attr); - - String attrName = attr.getName(); - String attrNameCapitalized = EugengoUtils.toUpperCaseFirstLetter(attrName); - -/*{ - static public void set<%=attrNameCapitalized%>(Wikitty w, <%=attrType%> <%=attrName%>) { - w.setField(<%=EXT_NAME%>, <%=clazz.getName()%>.FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, <%=attrName%>); - } - - static public <%=attrType%> get<%=attrNameCapitalized%>(Wikitty w) { - <%=attrType%> result = w.getFieldAs<%=methodAccessName%>(<%=EXT_NAME%>, <%=clazz.getName()%>.FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>); - return result; - } - -}*/ - } - - /** - * Give the string to put after getFieldAs???, only some type is accepted - * and we must convert BusinessEntity to Wikitty string - * @param type - * @return - */ - protected String getFieldAccessMethodName(ObjectModelAttribute attr) { - String result = computeType(attr); - result = getType(result, true); - - boolean isCollection = (attr.getMaxMultiplicity() != 0 - && attr.getMaxMultiplicity() != 1); - if (isCollection) { - if (attr.isUnique()) { - result = "Set"; - } else { - result = "List"; - } - } else { - // test for Date - if ("java.util.Date".equals(result) || "Date".equals(result)) { - result = "Date"; - } else if (getModel().hasClass(result)) { // test for Wikitty object - ObjectModelClass fieldClass = getModel().getClass(result); - if (EugengoUtils.isBusinessEntity(fieldClass)) { - // for wikittyDto we use String for Id - result = "Wikitty"; - } - } else if (null != getModel().getEnumeration(result)) { - result = "String"; - } - } - result = EugengoUtils.toUpperCaseFirstLetter(result); - - return result; - } - - protected void generateCollectionAttributeAccessors(Writer output, - ObjectModelClass clazz, ObjectModelAttribute attr) throws IOException { - - EXT_NAME = "EXT_" + attr.getDeclaringElement().getName().toUpperCase(); - - String attrType = computeType(attr); - if (EugengoUtils.notEmpty(attrType)) { - attrType = getType(attrType, true); - } else { - return; - } - - // get collection element type for add and remove method arguement type - String elementType = getType(attr.getType(), true); - - String methodAccessName = getFieldAccessMethodName(attr); - - String attrName = attr.getName(); - String attrNameCapitalized = EugengoUtils.toUpperCaseFirstLetter(attrName); -/*{ static public <%=attrType%> get<%=attrNameCapitalized%>(Wikitty w) { - <%=attrType%> result = w.getFieldAs<%=methodAccessName%>(<%=EXT_NAME%>, <%=clazz.getName()%>.FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, <%=getClassAndGeneric(attrType)[1]%>.class); - return result; - } - - static public void add<%=attrNameCapitalized%>(Wikitty w, <%=elementType%> element) { - w.addToField(<%=EXT_NAME%>, <%=clazz.getName()%>.FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, element); - } - - static public void remove<%=attrNameCapitalized%>(Wikitty w, <%=elementType%> element) { - w.removeFromField(<%=EXT_NAME%>, <%=clazz.getName()%>.FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>, element); - } - - static public void clear<%=attrNameCapitalized%>(Wikitty w) { - w.clearField(<%=EXT_NAME%>, <%=clazz.getName()%>.FIELD_<%=clazz.getName().toUpperCase()%>_<%=attr.getName().toUpperCase()%>); - } - -}*/ - } - - private static Set<String> commonNumerics; - static { - commonNumerics = new HashSet<String>(); - commonNumerics.add("byte"); - commonNumerics.add("Byte"); - commonNumerics.add("short"); - commonNumerics.add("Short"); - commonNumerics.add("int"); - commonNumerics.add("Integer"); - commonNumerics.add("long"); - commonNumerics.add("Long"); - commonNumerics.add("float"); - commonNumerics.add("Float"); - commonNumerics.add("double"); - commonNumerics.add("Double"); - } - - private static Set<String> commonStrings; - static { - commonStrings = new HashSet<String>(); - commonStrings.add("char"); - commonStrings.add("Char"); - commonStrings.add("String"); - } - - private static Set<String> commonTypes; - static { - commonTypes = new HashSet<String>(); - commonTypes.addAll(commonNumerics); - commonTypes.addAll(commonStrings); - commonTypes.add("boolean"); - commonTypes.add("Boolean"); - commonTypes.add("Date"); - } - -} Copied: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java (from rev 347, branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java) =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java (rev 0) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyHelperGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -0,0 +1,268 @@ +package org.nuiton.wikitty.generator; + +import org.apache.commons.lang.StringUtils; +import org.nuiton.eugene.java.ObjectModelTransformerToJava; +import org.nuiton.eugene.models.object.ObjectModelAttribute; +import org.nuiton.eugene.models.object.ObjectModelClass; +import org.nuiton.eugene.models.object.ObjectModelModifier; +import org.nuiton.eugene.models.object.ObjectModelOperation; + +/*{generator option: writeString = }*/ +/*{generator option: parentheses = false}*/ +/*{generator option: writeString = +}*/ + +/** + * @plexus.component role="org.nuiton.eugene.Template" role-hint="org.nuiton.wikitty.generator.WikittyHelperGenerator" + */ +public class WikittyHelperGenerator extends ObjectModelTransformerToJava { + + protected static final String META_EXTENSION_SEPARATOR = ":"; + + @Override + public void transformFromClass(ObjectModelClass clazz) { + + ObjectModelClass helper = createClass(WikittyTransformerUtil.businessEntityToHelperName(clazz), + clazz.getPackageName()); + + // TODO 20100811 bleny remove unused imports + addImport(helper, WikittyTransformerUtil.BUSINESS_ENTITY_CLASS_FQN); + addImport(helper, WikittyTransformerUtil.BUSINESS_ENTITY_WIKITTY_CLASS_FQN); + addImport(helper, WikittyTransformerUtil.WIKITTY_CLASS_FQN); + addImport(helper, "org.nuiton.wikitty.WikittyExtension"); + addImport(helper, "org.nuiton.wikitty.WikittyUtil"); + addImport(helper, "org.nuiton.wikitty.WikittyUser"); + addImport(helper, "org.nuiton.wikitty.WikittyUserAbstract"); + addImport(helper, "org.nuiton.wikitty.WikittyUserImpl"); + addImport(helper, "org.nuiton.wikitty.TreeNode"); + addImport(helper, "org.nuiton.wikitty.TreeNodeAbstract"); + addImport(helper, "org.nuiton.wikitty.TreeNodeImpl"); + addImport(helper, java.util.List.class); + addImport(helper, java.util.ArrayList.class); + addImport(helper, java.util.Collection.class); + addImport(helper, java.util.Collections.class); + addImport(helper, java.util.Set.class); + addImport(helper, java.util.Date.class); + addImport(helper, java.util.LinkedHashSet.class); + + // making constructor for helper class (empty and private) + ObjectModelOperation constructor = addConstructor(helper, ObjectModelModifier.PRIVATE); + setDocumentation(constructor, "utility class all provided methods are accessible the static way"); + setOperationBody(constructor, "// empty\n"); // empty implementation + + if ( WikittyTransformerUtil.isBusinessEntity(clazz) ) { + createOperationsForBusinessEntity(clazz, helper); + } + + if ( WikittyTransformerUtil.isMetaExtension(clazz)) { + createOperationForMetaExtension(clazz, helper); + } + } + + /** add operation if input model element has stereotype "entity" */ + protected void createOperationsForBusinessEntity(ObjectModelClass entity, + ObjectModelClass helper) { + + String extensionVariableName = WikittyTransformerUtil.classToExtensionVariableName(entity, true); + + // generating operations with bodies + for (ObjectModelAttribute attribute : entity.getAttributes()) { + if (attribute.isNavigable()) { + // needed below, in templates + String fieldVariableName = WikittyTransformerUtil.attributeToFielVariableName(attribute, true); + String attributeType = WikittyTransformerUtil.generateResultType(attribute, false); + + String attributeName = attribute.getName(); + if (attribute.hasTagValue(WikittyTransformerUtil.TAG_ALTERNATIVE_NAME)) { + // there is a conflict, purifier transformer give as the right name to use + attributeName = attribute.getTagValue(WikittyTransformerUtil.TAG_ALTERNATIVE_NAME); + } + + if (WikittyTransformerUtil.isAttributeCollection(attribute)) { + // attributed is a collection, we will generate operations get, add, remove and clear + + String attributeTypeSimpleNameInSet = WikittyTransformerUtil.generateResultType(attribute, true); + String getFieldMethodName = WikittyTransformerUtil.generateGetFieldAsCall(attribute); + + // now, for this attribute, we will generate add, remove and clear methods + // adding operations to contract + String getterName = "get" + StringUtils.capitalize(attributeName); + ObjectModelOperation getter = addOperation(helper, getterName, attributeTypeSimpleNameInSet, ObjectModelModifier.STATIC); + addParameter(getter, "Wikitty", "wikitty"); + String getterBody = "" +/*{ + <%=attributeTypeSimpleNameInSet%> result = wikitty.<%=getFieldMethodName%>(<%=extensionVariableName%>, <%=fieldVariableName%>, <%=attributeType%>.class); + return result; +}*/; + setOperationBody(getter, getterBody); + + String addName = "add" + StringUtils.capitalize(attributeName); + ObjectModelOperation adder = addOperation(helper, addName, "void", ObjectModelModifier.STATIC); + addParameter(adder, "Wikitty", "wikitty"); + addParameter(adder, attributeType, "element"); + String adderBody = "" +/*{ + wikitty.addToField(<%=extensionVariableName%>, <%=fieldVariableName%>, element); +}*/; + setOperationBody(adder, adderBody); + + String removeName = "remove" + StringUtils.capitalize(attributeName); + ObjectModelOperation remover = addOperation(helper, removeName, "void", ObjectModelModifier.STATIC); + addParameter(remover, "Wikitty", "wikitty"); + addParameter(remover, attributeType, "element"); + String removerBody = "" +/*{ + wikitty.removeFromField(<%=extensionVariableName%>, <%=fieldVariableName%>, element); +}*/; + setOperationBody(remover, removerBody); + + String clearName = "clear" + StringUtils.capitalize(attributeName); + ObjectModelOperation clear = addOperation(helper, clearName, "void", ObjectModelModifier.STATIC); + addParameter(clear, "Wikitty", "wikitty"); + String clearBody = "" +/*{ + wikitty.clearField(<%=extensionVariableName%>, <%=fieldVariableName%>); +}*/; + setOperationBody(clear, clearBody); + + + } else { + String getFieldMethodName = WikittyTransformerUtil.generateGetFieldAsCall(attribute); + + // adding getter and setter to contract + String getterName = "get" + StringUtils.capitalize(attributeName); + ObjectModelOperation getter = addOperation(helper, getterName, attributeType, ObjectModelModifier.STATIC); + addParameter(getter, "Wikitty", "wikitty"); + setOperationBody(getter, "" +/*{ + <%=attributeType%> value = wikitty.<%=getFieldMethodName%>(<%=extensionVariableName%>, <%=fieldVariableName%>); + return value; +}*/); + + String setterName = "set" + StringUtils.capitalize(attributeName); + ObjectModelOperation setter = addOperation(helper, setterName, attributeType, ObjectModelModifier.STATIC); + addParameter(setter, "Wikitty", "wikitty"); + addParameter(setter, attributeType, attributeName); + setOperationBody(setter, "" +/*{ + <%=attributeType%> oldValue = <%=getter.getName()%>(wikitty); + wikitty.setField(<%=extensionVariableName%>, <%=fieldVariableName%>, <%=attributeName%>); + return oldValue; +}*/); + } + } + } + + + + // now, adding the equals(w1, w2) + + ObjectModelOperation equals = addOperation(helper, "equals", "boolean", ObjectModelModifier.STATIC); + addParameter(equals, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "w1"); + addParameter(equals, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "w2"); + + // the body of the equals method, will be assembled while reading attributes + String equalsBody = "" +/*{ + boolean result = true; +}*/; + + for(ObjectModelAttribute attribute : entity.getAttributes()) { + if (attribute.isNavigable()) { + // two variables needed below + String fieldVariableName = WikittyTransformerUtil.attributeToFielVariableName(attribute, true); + + // considering field in equals body + equalsBody += "" +/*{ + if (result) { + Object f1 = w1.getFieldAsObject(<%= extensionVariableName %>, <%= fieldVariableName %>); + Object f2 = w2.getFieldAsObject(<%= extensionVariableName %>, <%= fieldVariableName %>); + result = f1 == f2 || (f1 != null && f1.equals(f2)); + }; +}*/; + } + } + + // finishing equals body + equalsBody += "" +/*{ + return result; +}*/; + setOperationBody(equals, equalsBody); + + + + + + // finally, adding isExtention and addExtension + + ObjectModelOperation isExtension = addOperation(helper, "isExtension", "boolean", ObjectModelModifier.STATIC); + addParameter(isExtension, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "wikitty"); + setDocumentation(isExtension, "Check if wikitty has current extension"); + setOperationBody(isExtension, "" +/*{ + return wikitty.hasExtension(<%=extensionVariableName%>); +}*/); + + ObjectModelOperation addExtension = addOperation(helper, "addExtension", "void", ObjectModelModifier.STATIC); + addParameter(addExtension, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "wikitty"); + setDocumentation(addExtension, "ajout les extensions static de cette classe au wikitty en argument"); + String contractName = WikittyTransformerUtil.businessEntityToAbstractName(entity); + setOperationBody(addExtension, "" +/*{ + for (WikittyExtension ext : <%=contractName%>.extensions) { + wikitty.addExtension(ext); + } +}*/); + } + + /** add needed operations if input model element has stereotype "meta" */ + protected void createOperationForMetaExtension(ObjectModelClass metaExtension, + ObjectModelClass helper) { + + ObjectModelOperation addMetaExtension = addOperation(helper, "addMetaExtension", "void", ObjectModelModifier.STATIC); + addParameter(addMetaExtension, WikittyTransformerUtil.WIKITTY_EXTENSION_CLASS_FQN, "extension"); + addParameter(addMetaExtension, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "wikitty"); + setDocumentation(addMetaExtension, String.format( + "add %s meta-extension on given extension to the given wikitty", + metaExtension.getName())); + String abstractName = WikittyTransformerUtil.businessEntityToAbstractName(metaExtension); + String contractName = WikittyTransformerUtil.businessEntityToContractName(metaExtension); + setOperationBody(addMetaExtension, "" +/*{ + wikitty.addMetaExtension(<%=abstractName%>.extension<%=contractName%>, extension); +}*/); + + + + // now adding getMetaFielName, both implementations + + ObjectModelOperation getMetaFieldNameFromExtension = addOperation(helper, "getMetaFieldName", "String", ObjectModelModifier.STATIC); + addParameter(getMetaFieldNameFromExtension, WikittyTransformerUtil.WIKITTY_EXTENSION_CLASS_FQN, "extension"); + addParameter(getMetaFieldNameFromExtension, "String", "fieldName"); + setDocumentation(getMetaFieldNameFromExtension, String.format( + "for extension 'Ext' and field 'f', return 'Ext:%s.f'", + metaExtension.getName())); + setOperationBody(getMetaFieldNameFromExtension, "" +/*{ + String metaFieldName = getMetaFieldName(extension.getName(), fieldName); + return metaFieldName; +}*/); + + ObjectModelOperation getMetaFieldNameFromExtensionName = addOperation(helper, "getMetaFieldName", "String", ObjectModelModifier.STATIC); + addParameter(getMetaFieldNameFromExtensionName, "String", "extensionName"); + addParameter(getMetaFieldNameFromExtensionName, "String", "fieldName"); + setDocumentation(getMetaFieldNameFromExtensionName, String.format( + "for extension 'Ext' and field 'f', return 'Ext:%s.f'", + metaExtension.getName())); + setOperationBody(getMetaFieldNameFromExtensionName, "" +/*{ + String metaFieldName = String.format("%s<%=META_EXTENSION_SEPARATOR%><%=metaExtension.getName()%>.%s", extensionName, fieldName); + return metaFieldName; +}*/); + + + + // now, adding all + } +} Copied: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyImplementationGenerator.java (from rev 347, branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyImplementationGenerator.java) =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyImplementationGenerator.java (rev 0) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyImplementationGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -0,0 +1,125 @@ +package org.nuiton.wikitty.generator; + +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +import org.nuiton.eugene.java.ObjectModelTransformerToJava; +import org.nuiton.eugene.models.object.ObjectModelClass; +import org.nuiton.eugene.models.object.ObjectModelModifier; +import org.nuiton.eugene.models.object.ObjectModelOperation; + +/*{generator option: writeString = }*/ +/*{generator option: parentheses = false}*/ +/*{generator option: writeString = +}*/ + +/** + * @plexus.component role="org.nuiton.eugene.Template" role-hint="org.nuiton.wikitty.generator.WikittyImplementationGenerator" + */ +public class WikittyImplementationGenerator extends ObjectModelTransformerToJava { + + protected Map<ObjectModelClass, ObjectModelClass> processedClasses = + new HashMap<ObjectModelClass, ObjectModelClass>(); + + @Override + public void transformFromClass(ObjectModelClass clazz) { + + if ( WikittyTransformerUtil.isBusinessEntity(clazz) ) { + ObjectModelClass implementation = prepareImplementation(clazz); + processBusinessEntity(clazz, implementation); + } + + if ( WikittyTransformerUtil.isBusinessEntity(clazz) ) { + ObjectModelClass implementation = prepareImplementation(clazz); + processMetaExtension(clazz, implementation); + } + } + + protected ObjectModelClass prepareImplementation(ObjectModelClass clazz) { + ObjectModelClass implementation; + + if (processedClasses.containsKey(clazz)) { + // class has been already processed, return the implementation + implementation = processedClasses.get(clazz); + } else { + implementation = createClass( + WikittyTransformerUtil.businessEntityToImplementationName(clazz), + clazz.getPackageName()); + + // TODO 20100811 bleny remove unused imports + addImport(implementation, WikittyTransformerUtil.BUSINESS_ENTITY_CLASS_FQN); + addImport(implementation, WikittyTransformerUtil.BUSINESS_ENTITY_WIKITTY_CLASS_FQN); + addImport(implementation, WikittyTransformerUtil.WIKITTY_CLASS_FQN); + addImport(implementation, "org.nuiton.wikitty.WikittyExtension"); + addImport(implementation, "org.nuiton.wikitty.WikittyUtil"); + addImport(implementation, "org.nuiton.wikitty.WikittyUser"); + addImport(implementation, "org.nuiton.wikitty.WikittyUserAbstract"); + addImport(implementation, "org.nuiton.wikitty.WikittyUserImpl"); + addImport(implementation, "org.nuiton.wikitty.TreeNode"); + addImport(implementation, "org.nuiton.wikitty.TreeNodeAbstract"); + addImport(implementation, "org.nuiton.wikitty.TreeNodeImpl"); + addImport(implementation, java.util.List.class); + addImport(implementation, java.util.ArrayList.class); + addImport(implementation, java.util.Collection.class); + addImport(implementation, java.util.Collections.class); + addImport(implementation, java.util.Set.class); + addImport(implementation, java.util.Date.class); + addImport(implementation, java.util.LinkedHashSet.class); + + setSuperClass(implementation, WikittyTransformerUtil.businessEntityToAbstractName(clazz)); + + // adding a generated serialVersionUID + Random random = new Random(); + Long serialVersionUIDs = random.nextLong(); + addConstant(implementation, + "serialVersionUID", + "long", + serialVersionUIDs.toString() + "L", + ObjectModelModifier.PRIVATE); + + } + + return implementation; + } + + protected void processBusinessEntity(ObjectModelClass clazz, + ObjectModelClass implementation) { + + // adding constructor + ObjectModelOperation constructor = addConstructor(implementation, ObjectModelModifier.PUBLIC); + setOperationBody(constructor, "" +/*{ + super(); +}*/); + + constructor = addConstructor(implementation, ObjectModelModifier.PUBLIC); + addParameter(constructor, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "wikitty"); + setOperationBody(constructor, "" +/*{ + super(wikitty); +}*/); + + constructor = addConstructor(implementation, ObjectModelModifier.PUBLIC); + addParameter(constructor, WikittyTransformerUtil.BUSINESS_ENTITY_WIKITTY_CLASS_FQN, "businessEntityWikitty"); + setOperationBody(constructor, "" +/*{ + super(businessEntityWikitty.getWikitty()); +}*/); + + } + + protected void processMetaExtension(ObjectModelClass metaExtension, + ObjectModelClass implementation) { + + + ObjectModelOperation constructor = addConstructor(implementation, ObjectModelModifier.PUBLIC); + addParameter(constructor, WikittyTransformerUtil.WIKITTY_EXTENSION_CLASS_FQN, "extension"); + addParameter(constructor, WikittyTransformerUtil.WIKITTY_CLASS_FQN, "wikitty"); + String contractName = WikittyTransformerUtil.businessEntityToContractName(metaExtension); + setOperationBody(constructor, "" +/*{ + this.wikitty = wikitty; + addMetaExtension(extension<%=contractName%>, extension); +}*/); + } +} Deleted: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaGenerator.java =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaGenerator.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaGenerator.java 2010-09-28 10:05:55 UTC (rev 351) @@ -1,136 +0,0 @@ -package org.nuiton.wikitty.generator; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.Properties; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.nuiton.eugene.models.object.ObjectModel; -import org.nuiton.eugene.models.object.ObjectModelGenerator; -import org.nuiton.util.Resource; - -public class WikittyMetaGenerator extends ObjectModelGenerator { - - protected static Log log = LogFactory.getLog(WikittyMetaGenerator.class); - - /** - * la liste des generateurs par defaut a utiliser - */ - protected static final List<Class<? extends WikengoCommonGenerator>> DEFAULT_GENERATORS = - Collections.unmodifiableList(Arrays.asList( - - // Enum - InterfaceGenerator.class, - EnumGenerator.class, - - // Wikitty (Interface, impl...) - BusinessEntityInterfaceGenerator.class, - BusinessEntityAbstractGenerator.class, - BusinessEntityImplGenerator.class, - WikittyHelperGenerator.class - - )); - - protected List<Class<? extends WikengoCommonGenerator>> getGenerators() { - List<Class<? extends WikengoCommonGenerator>> result = DEFAULT_GENERATORS; - Properties props = null; - try { - Properties tmpProperties = Resource.getConfigProperties("WikittyMetaGenerator.properties"); - - props = new Properties(); - - // Mise à plat du fichier (sans parent) - for (Enumeration<?> e = tmpProperties.propertyNames(); e.hasMoreElements();) { - String key = e.nextElement() + ""; - String value = tmpProperties.getProperty(key); - props.setProperty(key, value); - } - - } catch (IOException ioe) { - log.error("Unable to load file WikengoMetaGenerator.properties : " + ioe.getMessage()); - } - - if (props != null) { - List<Class<? extends WikengoCommonGenerator>> propsGenerators = new ArrayList<Class<? extends WikengoCommonGenerator>>(); - String basePackage = props.getProperty("basePackage"); - String suffix = props.getProperty("suffix"); - if (basePackage != null && !basePackage.endsWith(".")) { - basePackage += "."; - } - for (Object key : props.keySet()) { - String className = (String)key; - if ( suffix != null ) className += suffix; - - // Try with "className" - Class<? extends WikengoCommonGenerator> clazz = getClass(className); - - // Try with "baseName.className" - if (clazz == null && basePackage != null) { - clazz = getClass(basePackage + className); - } - - if (clazz != null) { - propsGenerators.add(clazz); - } else { - log.warn("No generator found for property '" + className + "'"); - } - } - if (!propsGenerators.isEmpty()) { - result = propsGenerators; - } - } - - log.warn("Enabled generators: " + result); - return result; - } - - protected Class<? extends WikengoCommonGenerator> getClass(String className) { - Class<? extends WikengoCommonGenerator> result = null; - try { - Class<?> clazz = Class.forName(className); - if (WikengoCommonGenerator.class.isAssignableFrom(clazz)) { - result = (Class<? extends WikengoCommonGenerator>)clazz; - } - } catch (ClassNotFoundException e) { - // Nothing to do - } - return result; - } - - @Override - public void applyTemplate(ObjectModel model, File destDir) throws IOException { - for (Class<? extends ObjectModelGenerator> generatorClass : getGenerators()) { - ObjectModelGenerator generator; - if (excludeTemplates != null && excludeTemplates.contains(generatorClass.getName())) { - // exclude generator - log.info("exclude generator " + generatorClass); - continue; - } - try { - - generator = generatorClass.newInstance(); - generator.setParent(this); - - } catch (Exception e) { - // should never happens - if (log.isErrorEnabled()) { - log.error("An error occurs when generating persistence", e); - } - throw new RuntimeException(e); - } - - // log - if (log.isDebugEnabled()) { - log.debug("call template : " + generatorClass.getSimpleName()); - } - generator.applyTemplate(model, destDir); - } - } - -} Copied: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaTransformer.java (from rev 347, branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaTransformer.java) =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaTransformer.java (rev 0) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyMetaTransformer.java 2010-09-28 10:05:55 UTC (rev 351) @@ -0,0 +1,76 @@ +package org.nuiton.wikitty.generator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.AbstractMetaTransformer; +import org.nuiton.eugene.models.object.ObjectModel; +import org.nuiton.eugene.models.object.ObjectModelClass; + +/** + * + * Wikitty generation steps : + * <ol> + * <li>transform user model to wikitty intermediate model</li> + * <li>generate from wikitty intermediate model : + * <ul> + * <li>a contract;</li> + * <li>an abstract class;</li> + * <li>an implementation;</li> + * <li>a helper</li> + * </ul> + * </li> + * </ol> + * + * @author bleny + * + * @plexus.component role="org.nuiton.eugene.Template" role-hint="org.nuiton.wikitty.generator.WikittyMetaGenerator" + */ + +// TODO 20100610 use filter with /*[]*/ +/*{generator option: writeString = }*/ +/*{generator option: parentheses = false}*/ +/*{generator option: writeString = +}*/ + +public class WikittyMetaTransformer extends AbstractMetaTransformer<ObjectModel> { + + private static final Log log = LogFactory.getLog(WikittyMetaTransformer.class); + + public WikittyMetaTransformer() { + + super(WikittyContractGenerator.class, + WikittyAbstractGenerator.class, + WikittyImplementationGenerator.class, + WikittyHelperGenerator.class + ); + + } + + /** */ + @Override + protected boolean validateModel(ObjectModel model) { + + if (model.getClasses().isEmpty()) { + log.warn("model doesn't contains any class"); + } + + for (ObjectModelClass clazz : model.getClasses()) { + + // warn user if deprecated stereotype is used + if (clazz.getStereotypes().contains(WikittyTransformerUtil.BUSINESS_ENTITY_STEREOTYPE_OLD_NAME)) { + log.warn(clazz.getQualifiedName() + " uses deprecated \"" + + WikittyTransformerUtil.BUSINESS_ENTITY_STEREOTYPE_OLD_NAME + + "\" stereotype. use \"" + + WikittyTransformerUtil.BUSINESS_ENTITY_STEREOTYPE_NAME + + "\" instead"); + } + + if (!clazz.hasTagValue(WikittyTransformerUtil.TAG_VERSION)) { + log.warn(clazz.getQualifiedName() + " misses a \"" + + WikittyTransformerUtil.TAG_VERSION + "\" tagValue"); + } + } + + return true; + } + +} Copied: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java (from rev 347, branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java) =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java (rev 0) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyPurifierTransformer.java 2010-09-28 10:05:55 UTC (rev 351) @@ -0,0 +1,130 @@ +package org.nuiton.wikitty.generator; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.java.ObjectModelTransformerToJava; +import org.nuiton.eugene.models.object.ObjectModel; +import org.nuiton.eugene.models.object.ObjectModelAttribute; +import org.nuiton.eugene.models.object.ObjectModelClass; + +/** + * this transformer read the original user model and generate the intermediate + * model needed by generators. + * + * + * + */ +public class WikittyPurifierTransformer extends ObjectModelTransformerToJava { + + private static final Log log = LogFactory.getLog(WikittyPurifierTransformer.class); + + /** for a given class, store all the names used by this class and subClasses */ + Map<ObjectModelClass, List<String>> namesUsedByClass = new HashMap<ObjectModelClass, List<String>>(); + + /** class of the original model that are already processed */ + List<ObjectModelClass> processedClasses = new ArrayList<ObjectModelClass>(); + + /** + * for a given, class read all attributes name and try to find conflicts + * with parent classes attributes names. + * + * If a conflict is found, we try to solve the conflict by adding an + * tagValue to the conflicting attribute for others transformers + * to consider it as a new name. To choose a new name, we look for + * an alternative name provided by the user through a tagValue on this + * attribute. If no alternative provided, we try to generate an alternative + * name by adding "From<className>" to the attribute name. + */ + protected void processClass(ObjectModelClass clazz) { + if (processedClasses.contains(clazz)) { + // clazz has already been processed, do nothing + } else { + // all attributes names that will be used by clazz + List<String> allUsedNames = new ArrayList<String>(); + + + // first, we have to get all names used by the super classes and + // its superclasses. So they must have been processed before + // current class. Thus, we recursively call processClass on + // superClass. + + // process superclass first + for (ObjectModelClass superClasses : clazz.getSuperclasses()) { + if (WikittyTransformerUtil.isBusinessEntity(superClasses)) { + if (!processedClasses.contains(superClasses)) { + processClass(superClasses); + allUsedNames.addAll(namesUsedByClass.get(superClasses)); + } + } + } + + // now, allUsedNames contains all names used by superClass, we + // have to check current class attributes names for conflict. + // allUsedNames contains name that we + // can't use without generating a conflict + for (ObjectModelAttribute attribute : clazz.getAttributes()) { + + // will be null as long as a non-conflicting name is found + String attributeName = null; + + if (attribute.hasTagValue(WikittyTransformerUtil.TAG_ALTERNATIVE_NAME)) { + attributeName = attribute.getTagValue(WikittyTransformerUtil.TAG_ALTERNATIVE_NAME); + if (allUsedNames.contains(attributeName)) { + // using alternative name lead to a conflict + attribute.getTagValues().remove(WikittyTransformerUtil.TAG_ALTERNATIVE_NAME); + attributeName = null; + } + } + + if (attributeName == null) { + attributeName = attribute.getName(); + if (allUsedNames.contains(attributeName)) { + // using alternative name lead to a conflict + attributeName = null; + } + } + + if (attributeName == null) { + attributeName = attribute.getName() + "From" + clazz.getName(); + if (allUsedNames.contains(attributeName)) { + // using alternative name lead to a conflict + attributeName = null; + } else { + addTagValue(attribute, WikittyTransformerUtil.TAG_ALTERNATIVE_NAME, attributeName); + } + } + + // finally + if (attributeName == null) { + // still no alternative :-( + log.error("no way to resolve conflict with attribute" + + attribute.getName() + " from class " + clazz + + ". You should add or change a tagValue \"" + + WikittyTransformerUtil.TAG_ALTERNATIVE_NAME + + "\" on this attribute"); + } else { + allUsedNames.add(attributeName); + } + } + + // saving all names we used in current class will permit to sub classes + // to know what names it must not use + namesUsedByClass.put(clazz, allUsedNames); + } + } + + @Override + public void transformFromModel(ObjectModel model) { + for (ObjectModelClass clazz : model.getClasses()) { + ObjectModelClass clone = cloneClass(clazz, true); + if (WikittyTransformerUtil.isBusinessEntity(clazz)) { + processClass(clone); + } + } + } +} Copied: trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTransformerUtil.java (from rev 347, branches/wikitty-eugene-migration/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTransformerUtil.java) =================================================================== --- trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTransformerUtil.java (rev 0) +++ trunk/wikitty-generators/src/main/java/org/nuiton/wikitty/generator/WikittyTransformerUtil.java 2010-09-28 10:05:55 UTC (rev 351) @@ -0,0 +1,200 @@ +package org.nuiton.wikitty.generator; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.nuiton.eugene.models.object.ObjectModelAttribute; +import org.nuiton.eugene.models.object.ObjectModelClass; + + +public class WikittyTransformerUtil { + + /** utility class should not be instanciated */ + private WikittyTransformerUtil() {} + + protected static final String BUSINESS_ENTITY_CLASS_FQN = "org.nuiton.wikitty.BusinessEntity"; + protected static final String BUSINESS_ENTITY_WIKITTY_CLASS_FQN = "org.nuiton.wikitty.BusinessEntityWikitty"; + protected static final String WIKITTY_CLASS_FQN = "org.nuiton.wikitty.Wikitty"; + protected static final String WIKITTY_EXTENSION_CLASS_FQN = "org.nuiton.wikitty.WikittyExtension"; + + protected static final String TAG_VERSION = "version"; + protected static final String TAG_ALTERNATIVE_NAME = "alternativeName"; + protected static final String TAG_TO_STRING = "toString"; + protected static final String TAG_DOCUMENTATION = "documentation"; + + /** @deprecated name change : see ticket #798. use BUSINESS_ENTITY_STEREOTYPE_NAME */ + @Deprecated + protected static final String BUSINESS_ENTITY_STEREOTYPE_OLD_NAME = "BusinessEntity"; + + /** user will use this stereotype in his model */ + protected static final String BUSINESS_ENTITY_STEREOTYPE_NAME = "entity"; + + /** user will use this stereotype to make an extension a meta-extension */ + protected static final String META_EXTENSION_STEREOTYPE_NAME = "meta"; + + /** given a class called Client will return "EXT_CLIENT" + * should be used as a variable name to store the extension name + * @param withClassNamePrefix add class name as prefix (will return "Client.EXT_CLIENT") + */ + protected static String classToExtensionVariableName(ObjectModelClass clazz, + boolean withClassNamePrefix) { + String extensionVariableName = ""; + if (withClassNamePrefix) { + extensionVariableName += clazz.getName() + "."; + } + extensionVariableName += "EXT_" + clazz.getName().toUpperCase(); + return extensionVariableName; + } + + /** given the field name of the class Client, will return "FIELD_CLIENT_NAME" + * @param withClassNamePrefix add class name as prefix (ie "Client.FIELD_CLIENT_NAME") + */ + protected static String attributeToFielVariableName(ObjectModelAttribute attribute, + boolean withClassNamePrefix) { + String fieldVariableName = ""; + if (withClassNamePrefix) { + fieldVariableName += attribute.getDeclaringElement().getName() + "."; + } + fieldVariableName += "FIELD_" + attribute.getDeclaringElement().getName().toUpperCase() + "_" + attribute.getName().toUpperCase(); + return fieldVariableName; + } + + /** given "my.java.package.MyClass" or "MyClass" return "MyClass" */ + protected static String FQNtoSimpleName(String fqn) { + // XXX should use GeneratorUtil#getSimpleName(String) + int lastDotIndex = fqn.lastIndexOf("."); + String simpleName = fqn; + if (lastDotIndex != -1) { + simpleName = fqn.substring(lastDotIndex + 1); + } + return simpleName; + } + + protected static boolean isBusinessEntity(ObjectModelClass clazz) { + boolean result = clazz.hasStereotype(BUSINESS_ENTITY_STEREOTYPE_NAME) + || clazz.hasStereotype(BUSINESS_ENTITY_STEREOTYPE_OLD_NAME); + return result; + } + + public static boolean isMetaExtension(ObjectModelClass clazz) { + boolean result = clazz.hasStereotype(META_EXTENSION_STEREOTYPE_NAME); + return result; + } + + /** + * wikitty interface provide getFieldAsString, getFieldAsDate etc. methods + * this method returns the good name of the method to call depending the + * type given as parameter + * @param typeName a name of a business entity or "String", "Integer" etc. + * @return the name of a method "getFieldAsInt" for example + */ + protected static String generateGetFieldAsCall(ObjectModelAttribute attribute) { + String asWhat = null; + if (isAttributeCollection(attribute)) { + asWhat = getCollectionTypeName(attribute); + } else { + String simpleTypeName = FQNtoSimpleName(attribute.getType()); + if (commonTypes.contains(simpleTypeName)) { + asWhat = StringUtils.capitalize(simpleTypeName); + } else { + asWhat = "Wikitty"; + } + } + return "getFieldAs" + asWhat; + } + + /** for a given type of attribute, the getter returned type must be... */ + protected static String generateResultType(ObjectModelAttribute attribute, + boolean considerMultiplicity) { + String simpleTypeName = FQNtoSimpleName(attribute.getType()); + if (! commonTypes.contains(simpleTypeName)) { + simpleTypeName = "String"; // return a wikitty Id + } + + if (considerMultiplicity && isAttributeCollection(attribute)) { + simpleTypeName = getCollectionTypeName(attribute) + "<" + simpleTypeName + ">"; + } + + return simpleTypeName; + } + + protected static String getCollectionTypeName(ObjectModelAttribute attribute) { + String result = null; + if (attribute.isUnique()) { + result = "Set"; + } else { + result = "List"; + } + return result; + } + + public static boolean isAttributeCollection(ObjectModelAttribute attribute) { + return attribute.getMaxMultiplicity() == -1 // -1 is infinity + || attribute.getMaxMultiplicity() > 1; + } + + protected static String typeToWikittyColumn(String type) { + String simpleType = FQNtoSimpleName(type); + String result = simpleType; + if (!commonTypes.contains(simpleType)) { + result = "Wikitty"; + } else if(commonNumerics.contains(simpleType)) { + result = "Numeric"; + } else if(commonStrings.contains(simpleType)) { + result = "String"; + } + return result; + } + + private static Set<String> commonNumerics; + static { + commonNumerics = new HashSet<String>(); + commonNumerics.add("byte"); + commonNumerics.add("Byte"); + commonNumerics.add("short"); + commonNumerics.add("Short"); + commonNumerics.add("int"); + commonNumerics.add("Integer"); + commonNumerics.add("long"); + commonNumerics.add("Long"); + commonNumerics.add("float"); + commonNumerics.add("Float"); + commonNumerics.add("double"); + commonNumerics.add("Double"); + } + + private static Set<String> commonStrings; + static { + commonStrings = new HashSet<String>(); + commonStrings.add("char"); + commonStrings.add("Char"); + commonStrings.add("String"); + } + + private static Set<String> commonTypes; + static { + commonTypes = new HashSet<String>(); + commonTypes.addAll(commonNumerics); + commonTypes.addAll(commonStrings); + commonTypes.add("boolean"); + commonTypes.add("Boolean"); + commonTypes.add("Date"); + } + + public static String businessEntityToContractName(ObjectModelClass clazz) { + return clazz.getName(); + } + + public static String businessEntityToAbstractName(ObjectModelClass clazz) { + return clazz.getName() + "Abstract"; + } + + public static String businessEntityToImplementationName(ObjectModelClass clazz) { + return clazz.getName() + "Impl"; + } + + public static String businessEntityToHelperName(ObjectModelClass clazz) { + return clazz.getName() + "Helper"; + } +} Modified: trunk/wikitty-hbase-impl/pom.xml =================================================================== --- trunk/wikitty-hbase-impl/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-hbase-impl/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -8,7 +8,7 @@ <parent> <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </parent> <!-- ************************************************************* --> Modified: trunk/wikitty-hessian-client/pom.xml =================================================================== --- trunk/wikitty-hessian-client/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-hessian-client/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -6,7 +6,7 @@ <parent> <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </parent> <!-- ************************************************************* --> Modified: trunk/wikitty-hessian-server/pom.xml =================================================================== --- trunk/wikitty-hessian-server/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-hessian-server/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -6,7 +6,7 @@ <parent> <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </parent> <!-- ************************************************************* --> Modified: trunk/wikitty-jdbc-impl/pom.xml =================================================================== --- trunk/wikitty-jdbc-impl/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-jdbc-impl/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -6,7 +6,7 @@ <parent> <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </parent> <groupId>org.nuiton.wikitty</groupId> Modified: trunk/wikitty-jms-impl/pom.xml =================================================================== --- trunk/wikitty-jms-impl/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-jms-impl/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -7,7 +7,7 @@ <parent> <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </parent> <groupId>org.nuiton.wikitty</groupId> Modified: trunk/wikitty-jpa-impl/pom.xml =================================================================== --- trunk/wikitty-jpa-impl/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-jpa-impl/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -8,7 +8,7 @@ <parent> <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </parent> <!-- ************************************************************* --> Modified: trunk/wikitty-multistorage-impl/pom.xml =================================================================== --- trunk/wikitty-multistorage-impl/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-multistorage-impl/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -7,7 +7,7 @@ <parent> <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </parent> <groupId>org.nuiton.wikitty</groupId> Property changes on: trunk/wikitty-solr-impl ___________________________________________________________________ Added: svn:mergeinfo + /branches/2.0-eugene2/wikitty-solr-impl:164-179 /branches/wikitty-eugene-migration/wikitty-solr-impl:239-347 Modified: trunk/wikitty-solr-impl/pom.xml =================================================================== --- trunk/wikitty-solr-impl/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-solr-impl/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -6,7 +6,7 @@ <parent> <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </parent> <!-- ************************************************************* --> @@ -60,21 +60,6 @@ <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-test</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-beans</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-context</artifactId> - <scope>test</scope> - </dependency> </dependencies> Modified: trunk/wikitty-solr-impl/src/main/java/org/nuiton/wikitty/solr/WikittySearchEnginSolr.java =================================================================== --- trunk/wikitty-solr-impl/src/main/java/org/nuiton/wikitty/solr/WikittySearchEnginSolr.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-solr-impl/src/main/java/org/nuiton/wikitty/solr/WikittySearchEnginSolr.java 2010-09-28 10:05:55 UTC (rev 351) @@ -133,7 +133,7 @@ if (searchField.length >= 3) { String fieldNameType = searchField[2]; - TYPE type = FieldType.TYPE.valueOf(fieldNameType); + TYPE type = FieldType.TYPE.valueOf(fieldNameType); result = WikittySearchEnginSolr.getSolrFieldName(fqfieldname, type); return result; } @@ -168,13 +168,18 @@ /** * Helper to get information nodes and elements for reindexation. */ - protected class ReindexChildTreeNode { + static protected class ReindexChildTreeNode { + protected SolrResource solrResource; + protected SolrServer solrServer; + protected Map<String, Collection<String>> includedNodeIds; protected Map<String, Collection<String>> excludedNodeIds; protected Map<String, String> parents; - public ReindexChildTreeNode() { + public ReindexChildTreeNode(SolrServer solrServer, SolrResource solrResource) { + this.solrServer = solrServer; + this.solrResource = solrResource; includedNodeIds = new HashMap<String, Collection<String>>(); excludedNodeIds = new HashMap<String, Collection<String>>(); parents = new HashMap<String, String>(); @@ -238,7 +243,7 @@ // If not found in map, search in index if(parentId == null) { - SolrDocument doc = WikittySearchEnginSolr.this.findById(nodeId); + SolrDocument doc = findById(solrServer, nodeId); if(doc == null) { // is root return null; @@ -283,22 +288,21 @@ doc = new SolrInputDocument(); // Copy old field value - SolrDocument found = findById(id); + SolrDocument found = findById(solrServer, id); if (found != null) { - Collection<String> fieldNames = found.getFieldNames(); - for (String fieldName : fieldNames) { - Collection<Object> fieldValues = found.getFieldValues(fieldName); - - if(!fieldName.startsWith(TREENODE_PREFIX)) { - for (Object fieldValue : fieldValues) { - doc.addField(fieldName, fieldValue); - } - } - } - - solrResource.addDoc(id, doc); - } - else { + Collection<String> fieldNames = found.getFieldNames(); + for (String fieldName : fieldNames) { + Collection<Object> fieldValues = found.getFieldValues(fieldName); + + if(!fieldName.startsWith(TREENODE_PREFIX)) { + for (Object fieldValue : fieldValues) { + doc.addField(fieldName, fieldValue); + } + } + } + + solrResource.addDoc(id, doc); + } else { if (log.isWarnEnabled()) { log.warn("Can't find wikitty id '" + id + "' in index. Skip this wikitty."); } @@ -358,12 +362,14 @@ /** * Use to plug solr indexation in JTA transaction. */ - protected class SolrResource implements OnePhaseResource { + static protected class SolrResource implements OnePhaseResource { + protected SolrServer solrServer; protected ThreadLocal<Map<String, SolrInputDocument>> addedDocs; protected ThreadLocal<List<String>> deletedDocs; - public SolrResource() { + public SolrResource(SolrServer solrServer) { + this.solrServer = solrServer; addedDocs = new ThreadLocal<Map<String, SolrInputDocument>>(); deletedDocs = new ThreadLocal<List<String>>(); @@ -494,7 +500,7 @@ solrServer = new EmbeddedSolrServer(coreContainer, ""); fieldModifier = new TypeFieldModifer(extensionStorage); - solrResource = new SolrResource(); + solrResource = new SolrResource(solrServer); } catch (Exception eee) { throw new WikittyException(eee); @@ -515,7 +521,8 @@ public UpdateResponse store(WikittyTransaction transaction, Collection<Wikitty> wikitties) { try { solrResource.init(); - ReindexChildTreeNode reindexChildTreeNode = new ReindexChildTreeNode(); + ReindexChildTreeNode reindexChildTreeNode = + new ReindexChildTreeNode(solrServer, solrResource); for (Wikitty w : wikitties) { String id = w.getId(); @@ -525,7 +532,7 @@ reindexChildTreeNode.putIncludedAttachments(id, attachments); // Search deleted children - SolrDocument treeNodeDoc = findById(id); + SolrDocument treeNodeDoc = findById(solrServer, id); if (treeNodeDoc != null) { Collection oldAttachments = treeNodeDoc.getFieldValues(TreeNode.FQ_FIELD_TREENODE_ATTACHMENT); if (oldAttachments != null) { @@ -569,7 +576,8 @@ public UpdateResponse delete(WikittyTransaction transaction, Collection<String> ids) throws WikittyException { try { solrResource.init(); - ReindexChildTreeNode reindexChildTreeNode = new ReindexChildTreeNode(); + ReindexChildTreeNode reindexChildTreeNode = + new ReindexChildTreeNode(solrServer, solrResource); for (String id : ids) { // Find child in node id @@ -877,7 +885,7 @@ /** * Find solr document by id */ - protected SolrDocument findById(String id) { + protected static SolrDocument findById(SolrServer solrServer, String id) { SolrQuery query = new SolrQuery(SOLR_ID + ":" + id); QueryResponse response; try { Modified: trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/AbstractTestSolr.java =================================================================== --- trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/AbstractTestSolr.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/AbstractTestSolr.java 2010-09-28 10:05:55 UTC (rev 351) @@ -1,31 +1,12 @@ package org.nuiton.wikitty.solr.test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - import org.junit.Before; -import org.nuiton.wikitty.WikittySearchEngin; import org.nuiton.wikitty.WikittyService; -import org.springframework.beans.factory.annotation.Autowired; -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="classpath:META-INF/spring/wikitty-test.xml") public abstract class AbstractTestSolr { - @Autowired - protected WikittyService ws; + protected WikittyService ws = new WikittyServiceSolr(); - public void setWikittyService(WikittyService service) { - ws = service; - } - - public WikittyService getWikittyService() { - return ws; - } - - WikittySearchEngin engine; - @Before public void deleteAll() throws Exception { WikittyServiceSolr hbaseService = ((WikittyServiceSolr) ws); Modified: trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/SolrSearchTest.java =================================================================== --- trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/SolrSearchTest.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/SolrSearchTest.java 2010-09-28 10:05:55 UTC (rev 351) @@ -28,7 +28,7 @@ public class SolrSearchTest extends AbstractTestSolr { - static private Log log = LogFactory.getLog(SolrSearchTest.class); + private static final Log log = LogFactory.getLog(SolrSearchTest.class); protected WikittyExtension extCategory; protected WikittyExtension extProduct; @@ -471,5 +471,4 @@ list = result.getAll(); assertEquals(2, list.size()); } - } Modified: trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/SolrServerTest.java =================================================================== --- trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/SolrServerTest.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/SolrServerTest.java 2010-09-28 10:05:55 UTC (rev 351) @@ -34,7 +34,6 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import org.springframework.test.annotation.ExpectedException; /** * Test behaviour SolrServer embedded. @@ -45,12 +44,12 @@ * Last update: $Date$ * by : $Author$ */ -public class SolrServerTest extends AbstractTestSolr { +public class SolrServerTest { /** to use log facility, just put in your code: log.info(\"...\"); */ - static private Log log = LogFactory.getLog(SolrServerTest.class); + private static final Log log = LogFactory.getLog(SolrServerTest.class); - public SolrServer getSolrServer() throws Exception { + public SolrServer newSolrServer() throws Exception { CoreContainer.Initializer initializer = new CoreContainer.Initializer(); CoreContainer coreContainer = initializer.initialize(); SolrServer solrServer = new EmbeddedSolrServer(coreContainer, ""); @@ -112,16 +111,15 @@ @Before public void clearIndex() throws Exception { - SolrServer solrServer = getSolrServer(); + SolrServer solrServer = newSolrServer(); solrServer.deleteByQuery("*:*"); solrServer.commit(); } - @Test - @ExpectedException(value=SolrServerException.class) + @Test(expected=SolrServerException.class) public void testLockObtainFailed() throws Exception { - SolrServer solrServer1 = getSolrServer(); - SolrServer solrServer2 = getSolrServer(); + SolrServer solrServer1 = newSolrServer(); + SolrServer solrServer2 = newSolrServer(); addDocument(solrServer1, "1", "1"); addDocument(solrServer2, "2", "2"); @@ -136,9 +134,10 @@ * De plus ce test est la seule cause des erreurs de build de ces derniers temps. * Et il y a un commentaire laissant planer le doute un peu plus bas. */ - //@Test + @Ignore + @Test public void test2Threads1SolrServer() throws Exception { - SolrServer solrServer = getSolrServer(); + SolrServer solrServer = newSolrServer(); ThreadAddDocument thread1 = new ThreadAddDocument(solrServer, "1", true); ThreadAddDocument thread2 = new ThreadAddDocument(solrServer, "2", false); @@ -158,8 +157,8 @@ @Test public void test2Threads1Writer2SolrServers() throws Exception { - SolrServer solrServer1 = getSolrServer(); - SolrServer solrServer2 = getSolrServer(); + SolrServer solrServer1 = newSolrServer(); + SolrServer solrServer2 = newSolrServer(); ThreadAddDocument thread1 = new ThreadAddDocument(solrServer1, "1", true); ThreadAddDocument thread2 = new ThreadAddDocument(solrServer2, "2", false); @@ -175,7 +174,7 @@ result = findById(solrServer2, "2"); assertNull(result); - SolrServer solrServer3 = getSolrServer(); + SolrServer solrServer3 = newSolrServer(); result = findById(solrServer3, "1"); assertNotNull(result); result = findById(solrServer3, "2"); @@ -186,8 +185,8 @@ @Ignore @Test public void test2Threads2Writers2SolrServers() throws Exception { - SolrServer solrServer1 = getSolrServer(); - SolrServer solrServer2 = getSolrServer(); + SolrServer solrServer1 = newSolrServer(); + SolrServer solrServer2 = newSolrServer(); ThreadAddDocument thread1 = new ThreadAddDocument(solrServer1, "1", true); ThreadAddDocument thread2 = new ThreadAddDocument(solrServer2, "2", true); @@ -205,7 +204,7 @@ result = findById(solrServer2, "2"); assertNotNull(result); - SolrServer solrServer3 = getSolrServer(); + SolrServer solrServer3 = newSolrServer(); result = findById(solrServer3, "1"); assertNotNull(result); result = findById(solrServer3, "2"); @@ -215,8 +214,8 @@ @Ignore // FIXME 20100806 bleny randomly fail @Test public void testReader() throws Exception { - SolrServer solrServer1 = getSolrServer(); - SolrServer solrServer2 = getSolrServer(); + SolrServer solrServer1 = newSolrServer(); + SolrServer solrServer2 = newSolrServer(); addDocument(solrServer1, "1", "1"); solrServer1.commit(); Modified: trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/TreeTest.java =================================================================== --- trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/TreeTest.java 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-solr-impl/src/test/java/org/nuiton/wikitty/solr/test/TreeTest.java 2010-09-28 10:05:55 UTC (rev 351) @@ -35,6 +35,7 @@ import org.nuiton.wikitty.FieldType.TYPE; import org.nuiton.wikitty.Tree; import org.nuiton.wikitty.TreeNode; +import org.nuiton.wikitty.TreeNodeHelper; import org.nuiton.wikitty.TreeNodeImpl; import org.nuiton.wikitty.Wikitty; import org.nuiton.wikitty.WikittyExtension; @@ -79,11 +80,12 @@ // Create tree as following : // root // |_ node 1 - // | |_ node 11 + // | |_ node 11 (2) + // | | |_ node 111 (1) // | |_ node 12 - // | | |_ node 121 + // | | |_ node 121 (2) // | |_ node 13 - // |_ node 2 + // |_ node 2 (1) createBranch("root/node1/node11/node111"); createBranch("root/node1/node12/node121"); @@ -172,9 +174,29 @@ String nodeId = node.getId(); Map<TreeNode, Integer> children = ws.restoreChildren(null, nodeId, null); + /* for (Integer count : children.values()) { sum += count; } + */ + + for (Map.Entry<TreeNode, Integer> e : children.entrySet()) { + log.debug("*treeNode = " + e.getKey().getName() + " " + e.getValue() + + " -> " + e.getKey().getAttachment()); + } + + for (TreeNode treeNode : children.keySet()) { + Set<String> treeNodeChildren = treeNode.getAttachment(); + log.debug("+treeNode = " + treeNode.getName() + " " + (treeNodeChildren==null?0:treeNodeChildren.size()) + + " -> " + treeNodeChildren); +// if (treeNodeChildren == null) { +// sum += 0; +// } else { +// sum += treeNodeChildren.size(); +// } + sum += sum(((TreeNodeImpl)treeNode).getWikitty()); + } + return sum; } @@ -341,18 +363,52 @@ Wikitty root = findNode("root"); int childInit = sum(root); - // Remove a value on node2 + // Remove a value on node11 Wikitty node = findNode("node11"); + List<String> leafs = node.getFieldAsList(TreeNode.EXT_TREENODE, TreeNode.FIELD_TREENODE_ATTACHMENT, String.class); node.removeFromField(TreeNode.EXT_TREENODE, TreeNode.FIELD_TREENODE_ATTACHMENT, leafs.get(0)); + + leafs = node.getFieldAsList(TreeNode.EXT_TREENODE, TreeNode.FIELD_TREENODE_ATTACHMENT, String.class); + log.info("leafs after remove = " + leafs); + ws.store(null, node); + + node = ws.restore(null, node.getId()); + leafs = node.getFieldAsList(TreeNode.EXT_TREENODE, TreeNode.FIELD_TREENODE_ATTACHMENT, String.class); + log.info("leafs after restore = " + leafs); // now, there is one more value for the root node int newSum = sum(root); assertEquals(childInit - 1, newSum); } + /** regression test, for unknown reason the child may not be removed in the index */ @Test + public void testSimpleDeleteChild() throws Exception { + + TreeNodeImpl parent = new TreeNodeImpl(); + ws.store(null, parent.getWikitty()); + + TreeNodeImpl child = new TreeNodeImpl(); + child.setParent(parent.getWikittyId()); + ws.store(null, child.getWikitty()); + + Map<TreeNode, Integer> children = ws.restoreChildren(null, parent.getWikittyId(), null); + + assertEquals(1, children.size()); + assertEquals(0, children.get(child).intValue()); + + child.setParent(null); + + ws.store(null, child.getWikitty()); + + children = ws.restoreChildren(null, parent.getWikittyId(), null); + + assertEquals(0, children.size()); + } + + @Test public void testDeleteValue() throws Exception { // Get the initial number of values for Root node Wikitty root = findNode("root"); Modified: trunk/wikitty-solr-impl/src/test/resources/log4j.properties =================================================================== --- trunk/wikitty-solr-impl/src/test/resources/log4j.properties 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-solr-impl/src/test/resources/log4j.properties 2010-09-28 10:05:55 UTC (rev 351) @@ -4,6 +4,6 @@ log4j.appender.logConsole.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n # Configuration by components -log4j.rootLogger=DEBUG, logConsole -log4j.category.org.nuiton.wikitty=DEBUG +log4j.rootLogger=WARN, logConsole +log4j.category.org.nuiton.wikitty=WARN #log4j.category.org.apache.solr=DEBUG Copied: trunk/wikitty-solr-impl/src/test/resources/solrconfig.xml (from rev 347, branches/wikitty-eugene-migration/wikitty-solr-impl/src/test/resources/solrconfig.xml) =================================================================== --- trunk/wikitty-solr-impl/src/test/resources/solrconfig.xml (rev 0) +++ trunk/wikitty-solr-impl/src/test/resources/solrconfig.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -0,0 +1,700 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<config> + <!-- Set this to 'false' if you want solr to continue working after it has + encountered an severe configuration error. In a production environment, + you may want solr to keep working even if one handler is mis-configured. + + You may also set this to false using by setting the system property: + -Dsolr.abortOnConfigurationError=false + --> + <abortOnConfigurationError>${solr.abortOnConfigurationError:true}</abortOnConfigurationError> + + <!-- Used to specify an alternate directory to hold all index data + other than the default ./data under the Solr home. + If replication is in use, this should match the replication configuration. --> + <dataDir>${solr.data.dir:./target/tests-temp-dir/solr/data}</dataDir> + + + <indexDefaults> + <!-- Values here affect all index writers and act as a default unless overridden. --> + <useCompoundFile>false</useCompoundFile> + + <mergeFactor>10</mergeFactor> + <!-- + If both ramBufferSizeMB and maxBufferedDocs is set, then Lucene will flush based on whichever limit is hit first. + + --> + <!--<maxBufferedDocs>1000</maxBufferedDocs>--> + <!-- Tell Lucene when to flush documents to disk. + Giving Lucene more memory for indexing means faster indexing at the cost of more RAM + + If both ramBufferSizeMB and maxBufferedDocs is set, then Lucene will flush based on whichever limit is hit first. + + --> + <ramBufferSizeMB>32</ramBufferSizeMB> + <maxMergeDocs>2147483647</maxMergeDocs> + <maxFieldLength>10000</maxFieldLength> + <writeLockTimeout>1000</writeLockTimeout> + <commitLockTimeout>10000</commitLockTimeout> + + <!-- + Expert: Turn on Lucene's auto commit capability. + This causes intermediate segment flushes to write a new lucene + index descriptor, enabling it to be opened by an external + IndexReader. + NOTE: Despite the name, this value does not have any relation to Solr's autoCommit functionality + --> + <!--<luceneAutoCommit>false</luceneAutoCommit>--> + <!-- + Expert: + The Merge Policy in Lucene controls how merging is handled by Lucene. The default in 2.3 is the LogByteSizeMergePolicy, previous + versions used LogDocMergePolicy. + + LogByteSizeMergePolicy chooses segments to merge based on their size. The Lucene 2.2 default, LogDocMergePolicy chose when + to merge based on number of documents + + Other implementations of MergePolicy must have a no-argument constructor + --> + <!--<mergePolicy>org.apache.lucene.index.LogByteSizeMergePolicy</mergePolicy>--> + + <!-- + Expert: + The Merge Scheduler in Lucene controls how merges are performed. The ConcurrentMergeScheduler (Lucene 2.3 default) + can perform merges in the background using separate threads. The SerialMergeScheduler (Lucene 2.2 default) does not. + --> + <!--<mergeScheduler>org.apache.lucene.index.ConcurrentMergeScheduler</mergeScheduler>--> + + <!-- + This option specifies which Lucene LockFactory implementation to use. + + single = SingleInstanceLockFactory - suggested for a read-only index + or when there is no possibility of another process trying + to modify the index. + native = NativeFSLockFactory + simple = SimpleFSLockFactory + + (For backwards compatibility with Solr 1.2, 'simple' is the default + if not specified.) + --> + <lockType>simple</lockType> + </indexDefaults> + + <mainIndex> + <!-- options specific to the main on-disk lucene index --> + <useCompoundFile>false</useCompoundFile> + <ramBufferSizeMB>32</ramBufferSizeMB> + <mergeFactor>10</mergeFactor> + <!-- Deprecated --> + <!--<maxBufferedDocs>1000</maxBufferedDocs>--> + <maxMergeDocs>2147483647</maxMergeDocs> + <maxFieldLength>10000</maxFieldLength> + + <!-- If true, unlock any held write or commit locks on startup. + This defeats the locking mechanism that allows multiple + processes to safely access a lucene index, and should be + used with care. + This is not needed if lock type is 'none' or 'single' + --> + <unlockOnStartup>true</unlockOnStartup> + </mainIndex> + + <!-- Enables JMX if and only if an existing MBeanServer is found, use + this if you want to configure JMX through JVM parameters. Remove + this to disable exposing Solr configuration and statistics to JMX. + + If you want to connect to a particular server, specify the agentId + e.g. <jmx agentId="myAgent" /> + + If you want to start a new MBeanServer, specify the serviceUrl + e.g <jmx serviceurl="service:jmx:rmi:///jndi/rmi://localhost:9999/solr" /> + + For more details see http://wiki.apache.org/solr/SolrJmx + --> + <jmx /> + + <!-- the default high-performance update handler --> + <updateHandler class="solr.DirectUpdateHandler2"> + + <!-- A prefix of "solr." for class names is an alias that + causes solr to search appropriate packages, including + org.apache.solr.(search|update|request|core|analysis) + --> + + <!-- Perform a <commit/> automatically under certain conditions: + maxDocs - number of updates since last commit is greater than this + maxTime - oldest uncommited update (in ms) is this long ago + <autoCommit> + <maxDocs>10000</maxDocs> + <maxTime>1000</maxTime> + </autoCommit> + --> + + <!-- The RunExecutableListener executes an external command. + exe - the name of the executable to run + dir - dir to use as the current working directory. default="." + wait - the calling thread waits until the executable returns. default="true" + args - the arguments to pass to the program. default=nothing + env - environment variables to set. default=nothing + --> + <!-- A postCommit event is fired after every commit or optimize command + <listener event="postCommit" class="solr.RunExecutableListener"> + <str name="exe">solr/bin/snapshooter</str> + <str name="dir">.</str> + <bool name="wait">true</bool> + <arr name="args"> <str>arg1</str> <str>arg2</str> </arr> + <arr name="env"> <str>MYVAR=val1</str> </arr> + </listener> + --> + <!-- A postOptimize event is fired only after every optimize command, useful + in conjunction with index distribution to only distribute optimized indicies + <listener event="postOptimize" class="solr.RunExecutableListener"> + <str name="exe">snapshooter</str> + <str name="dir">solr/bin</str> + <bool name="wait">true</bool> + </listener> + --> + + </updateHandler> + + + <query> + <!-- Maximum number of clauses in a boolean query... can affect + range or prefix queries that expand to big boolean + queries. An exception is thrown if exceeded. --> + <maxBooleanClauses>1024</maxBooleanClauses> + + + <!-- Cache used by SolrIndexSearcher for filters (DocSets), + unordered sets of *all* documents that match a query. + When a new searcher is opened, its caches may be prepopulated + or "autowarmed" using data from caches in the old searcher. + autowarmCount is the number of items to prepopulate. For LRUCache, + the autowarmed items will be the most recently accessed items. + Parameters: + class - the SolrCache implementation (currently only LRUCache) + size - the maximum number of entries in the cache + initialSize - the initial capacity (number of entries) of + the cache. (seel java.util.HashMap) + autowarmCount - the number of entries to prepopulate from + and old cache. + --> + <filterCache + class="solr.LRUCache" + size="512" + initialSize="512" + autowarmCount="128"/> + + <!-- queryResultCache caches results of searches - ordered lists of + document ids (DocList) based on a query, a sort, and the range + of documents requested. --> + <queryResultCache + class="solr.LRUCache" + size="512" + initialSize="512" + autowarmCount="32"/> + + <!-- documentCache caches Lucene Document objects (the stored fields for each document). + Since Lucene internal document ids are transient, this cache will not be autowarmed. --> + <documentCache + class="solr.LRUCache" + size="512" + initialSize="512" + autowarmCount="0"/> + + <!-- If true, stored fields that are not requested will be loaded lazily. + + This can result in a significant speed improvement if the usual case is to + not load all stored fields, especially if the skipped fields are large compressed + text fields. + --> + <enableLazyFieldLoading>true</enableLazyFieldLoading> + + <!-- Example of a generic cache. These caches may be accessed by name + through SolrIndexSearcher.getCache(),cacheLookup(), and cacheInsert(). + The purpose is to enable easy caching of user/application level data. + The regenerator argument should be specified as an implementation + of solr.search.CacheRegenerator if autowarming is desired. --> + <!-- + <cache name="myUserCache" + class="solr.LRUCache" + size="4096" + initialSize="1024" + autowarmCount="1024" + regenerator="org.mycompany.mypackage.MyRegenerator" + /> + --> + + <!-- An optimization that attempts to use a filter to satisfy a search. + If the requested sort does not include score, then the filterCache + will be checked for a filter matching the query. If found, the filter + will be used as the source of document ids, and then the sort will be + applied to that. + <useFilterForSortedQuery>true</useFilterForSortedQuery> + --> + + <!-- An optimization for use with the queryResultCache. When a search + is requested, a superset of the requested number of document ids + are collected. For example, if a search for a particular query + requests matching documents 10 through 19, and queryWindowSize is 50, + then documents 0 through 49 will be collected and cached. Any further + requests in that range can be satisfied via the cache. --> + <queryResultWindowSize>50</queryResultWindowSize> + + <!-- Maximum number of documents to cache for any entry in the + queryResultCache. --> + <queryResultMaxDocsCached>200</queryResultMaxDocsCached> + + <!-- This entry enables an int hash representation for filters (DocSets) + when the number of items in the set is less than maxSize. For smaller + sets, this representation is more memory efficient, more efficient to + iterate over, and faster to take intersections. --> + <HashDocSet maxSize="3000" loadFactor="0.75"/> + + <!-- a newSearcher event is fired whenever a new searcher is being prepared + and there is a current searcher handling requests (aka registered). --> + <!-- QuerySenderListener takes an array of NamedList and executes a + local query request for each NamedList in sequence. --> + <listener event="newSearcher" class="solr.QuerySenderListener"> + <arr name="queries"> + <lst> <str name="q">solr</str> <str name="start">0</str> <str name="rows">10</str> </lst> + <lst> <str name="q">rocks</str> <str name="start">0</str> <str name="rows">10</str> </lst> + <lst><str name="q">static newSearcher warming query from solrconfig.xml</str></lst> + </arr> + </listener> + + <!-- a firstSearcher event is fired whenever a new searcher is being + prepared but there is no current registered searcher to handle + requests or to gain autowarming data from. --> + <listener event="firstSearcher" class="solr.QuerySenderListener"> + <arr name="queries"> + <lst> <str name="q">fast_warm</str> <str name="start">0</str> <str name="rows">10</str> </lst> + <lst><str name="q">static firstSearcher warming query from solrconfig.xml</str></lst> + </arr> + </listener> + + <!-- If a search request comes in and there is no current registered searcher, + then immediately register the still warming searcher and use it. If + "false" then all requests will block until the first searcher is done + warming. --> + <useColdSearcher>false</useColdSearcher> + + <!-- Maximum number of searchers that may be warming in the background + concurrently. An error is returned if this limit is exceeded. Recommend + 1-2 for read-only slaves, higher for masters w/o cache warming. --> + <maxWarmingSearchers>2</maxWarmingSearchers> + + </query> + + <!-- + Let the dispatch filter handler /select?qt=XXX + handleSelect=true will use consistent error handling for /select and /update + handleSelect=false will use solr1.1 style error formatting + --> + <requestDispatcher handleSelect="true" > + <!--Make sure your system has some authentication before enabling remote streaming! --> + <requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="2048" /> + + <!-- Set HTTP caching related parameters (for proxy caches and clients). + + To get the behaviour of Solr 1.2 (ie: no caching related headers) + use the never304="true" option and do not specify a value for + <cacheControl> + --> + <!-- <httpCaching never304="true"> --> + <httpCaching lastModifiedFrom="openTime" + etagSeed="Solr"> + <!-- lastModFrom="openTime" is the default, the Last-Modified value + (and validation against If-Modified-Since requests) will all be + relative to when the current Searcher was opened. + You can change it to lastModFrom="dirLastMod" if you want the + value to exactly corrispond to when the physical index was last + modified. + + etagSeed="..." is an option you can change to force the ETag + header (and validation against If-None-Match requests) to be + differnet even if the index has not changed (ie: when making + significant changes to your config file) + + lastModifiedFrom and etagSeed are both ignored if you use the + never304="true" option. + --> + <!-- If you include a <cacheControl> directive, it will be used to + generate a Cache-Control header, as well as an Expires header + if the value contains "max-age=" + + By default, no Cache-Control header is generated. + + You can use the <cacheControl> option even if you have set + never304="true" + --> + <!-- <cacheControl>max-age=30, public</cacheControl> --> + </httpCaching> + </requestDispatcher> + + + <!-- requestHandler plugins... incoming queries will be dispatched to the + correct handler based on the path or the qt (query type) param. + Names starting with a '/' are accessed with the a path equal to the + registered name. Names without a leading '/' are accessed with: + http://host/app/select?qt=name + If no qt is defined, the requestHandler that declares default="true" + will be used. + --> + <requestHandler name="standard" class="solr.SearchHandler" default="true"> + <!-- default values for query parameters --> + <lst name="defaults"> + <str name="echoParams">explicit</str> + <!-- + <int name="rows">10</int> + <str name="fl">*</str> + <str name="version">2.1</str> + --> + </lst> + </requestHandler> + + + <!-- DisMaxRequestHandler allows easy searching across multiple fields + for simple user-entered phrases. It's implementation is now + just the standard SearchHandler with a default query type + of "dismax". + see http://wiki.apache.org/solr/DisMaxRequestHandler + --> + <requestHandler name="dismax" class="solr.SearchHandler" > + <lst name="defaults"> + <str name="defType">dismax</str> + <str name="echoParams">explicit</str> + <float name="tie">0.01</float> + <str name="qf"> + text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4 + </str> + <str name="pf"> + text^0.2 features^1.1 name^1.5 manu^1.4 manu_exact^1.9 + </str> + <str name="bf"> + ord(popularity)^0.5 recip(rord(price),1,1000,1000)^0.3 + </str> + <str name="fl"> + id,name,price,score + </str> + <str name="mm"> + 2<-1 5<-2 6<90% + </str> + <int name="ps">100</int> + <str name="q.alt">*:*</str> + <!-- example highlighter config, enable per-query with hl=true --> + <str name="hl.fl">text features name</str> + <!-- for this field, we want no fragmenting, just highlighting --> + <str name="f.name.hl.fragsize">0</str> + <!-- instructs Solr to return the field itself if no query terms are + found --> + <str name="f.name.hl.alternateField">name</str> + <str name="f.text.hl.fragmenter">regex</str> <!-- defined below --> + </lst> + </requestHandler> + + <!-- Note how you can register the same handler multiple times with + different names (and different init parameters) + --> + <requestHandler name="partitioned" class="solr.SearchHandler" > + <lst name="defaults"> + <str name="defType">dismax</str> + <str name="echoParams">explicit</str> + <str name="qf">text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0</str> + <str name="mm">2<-1 5<-2 6<90%</str> + <!-- This is an example of using Date Math to specify a constantly + moving date range in a config... + --> + <str name="bq">incubationdate_dt:[* TO NOW/DAY-1MONTH]^2.2</str> + </lst> + <!-- In addition to defaults, "appends" params can be specified + to identify values which should be appended to the list of + multi-val params from the query (or the existing "defaults"). + + In this example, the param "fq=instock:true" will be appended to + any query time fq params the user may specify, as a mechanism for + partitioning the index, independent of any user selected filtering + that may also be desired (perhaps as a result of faceted searching). + + NOTE: there is *absolutely* nothing a client can do to prevent these + "appends" values from being used, so don't use this mechanism + unless you are sure you always want it. + --> + <lst name="appends"> + <str name="fq">inStock:true</str> + </lst> + <!-- "invariants" are a way of letting the Solr maintainer lock down + the options available to Solr clients. Any params values + specified here are used regardless of what values may be specified + in either the query, the "defaults", or the "appends" params. + + In this example, the facet.field and facet.query params are fixed, + limiting the facets clients can use. Faceting is not turned on by + default - but if the client does specify facet=true in the request, + these are the only facets they will be able to see counts for; + regardless of what other facet.field or facet.query params they + may specify. + + NOTE: there is *absolutely* nothing a client can do to prevent these + "invariants" values from being used, so don't use this mechanism + unless you are sure you always want it. + --> + <lst name="invariants"> + <str name="facet.field">cat</str> + <str name="facet.field">manu_exact</str> + <str name="facet.query">price:[* TO 500]</str> + <str name="facet.query">price:[500 TO *]</str> + </lst> + </requestHandler> + + + <!-- + Search components are registered to SolrCore and used by Search Handlers + + By default, the following components are avaliable: + + <searchComponent name="query" class="org.apache.solr.handler.component.QueryComponent" /> + <searchComponent name="facet" class="org.apache.solr.handler.component.FacetComponent" /> + <searchComponent name="mlt" class="org.apache.solr.handler.component.MoreLikeThisComponent" /> + <searchComponent name="highlight" class="org.apache.solr.handler.component.HighlightComponent" /> + <searchComponent name="debug" class="org.apache.solr.handler.component.DebugComponent" /> + + Default configuration in a requestHandler would look like: + <arr name="components"> + <str>query</str> + <str>facet</str> + <str>mlt</str> + <str>highlight</str> + <str>debug</str> + </arr> + + If you register a searchComponent to one of the standard names, that will be used instead. + To insert handlers before or after the 'standard' components, use: + + <arr name="first-components"> + <str>myFirstComponentName</str> + </arr> + + <arr name="last-components"> + <str>myLastComponentName</str> + </arr> + --> + + <!-- The spell check component can return a list of alternative spelling + suggestions. --> + <searchComponent name="spellcheck" class="solr.SpellCheckComponent"> + + <str name="queryAnalyzerFieldType">textSpell</str> + + <lst name="spellchecker"> + <str name="name">default</str> + <str name="field">spell</str> + <str name="spellcheckIndexDir">./spellchecker1</str> + + </lst> + <lst name="spellchecker"> + <str name="name">jarowinkler</str> + <str name="field">spell</str> + <!-- Use a different Distance Measure --> + <str name="distanceMeasure">org.apache.lucene.search.spell.JaroWinklerDistance</str> + <str name="spellcheckIndexDir">./spellchecker2</str> + + </lst> + + <lst name="spellchecker"> + <str name="classname">solr.FileBasedSpellChecker</str> + <str name="name">file</str> + <str name="sourceLocation">spellings.txt</str> + <str name="characterEncoding">UTF-8</str> + <str name="spellcheckIndexDir">./spellcheckerFile</str> + </lst> + </searchComponent> + + <!-- a request handler utilizing the spellcheck component --> + <requestHandler name="/spellCheckCompRH" class="solr.SearchHandler"> + <lst name="defaults"> + <!-- omp = Only More Popular --> + <str name="spellcheck.onlyMorePopular">false</str> + <!-- exr = Extended Results --> + <str name="spellcheck.extendedResults">false</str> + <!-- The number of suggestions to return --> + <str name="spellcheck.count">1</str> + </lst> + <arr name="last-components"> + <str>spellcheck</str> + </arr> + </requestHandler> + + <!-- a search component that enables you to configure the top results for + a given query regardless of the normal lucene scoring.--> + +<!-- poussin 20090902 remove elevate this file is empty, what need ? + <searchComponent name="elevator" class="solr.QueryElevationComponent" > + <str name="queryFieldType">string</str> + <str name="config-file">elevate.xml</str> + </searchComponent> + --> + <!-- a request handler utilizing the elevator component --> +<!-- + <requestHandler name="/elevate" class="solr.SearchHandler" startup="lazy"> + <lst name="defaults"> + <str name="echoParams">explicit</str> + </lst> + <arr name="last-components"> + <str>elevator</str> + </arr> + </requestHandler> + --> + + <!-- Update request handler. + + Note: Since solr1.1 requestHandlers requires a valid content type header if posted in + the body. For example, curl now requires: -H 'Content-type:text/xml; charset=utf-8' + The response format differs from solr1.1 formatting and returns a standard error code. + + To enable solr1.1 behavior, remove the /update handler or change its path + --> + <requestHandler name="/update" class="solr.XmlUpdateRequestHandler" /> + + <!-- + Analysis request handler. Since Solr 1.3. Use to returnhow a document is analyzed. Useful + for debugging and as a token server for other types of applications + --> + <requestHandler name="/analysis" class="solr.AnalysisRequestHandler" /> + + + <!-- CSV update handler, loaded on demand --> + <requestHandler name="/update/csv" class="solr.CSVRequestHandler" startup="lazy" /> + + + <!-- + Admin Handlers - This will register all the standard admin RequestHandlers. Adding + this single handler is equivolent to registering: + + <requestHandler name="/admin/luke" class="org.apache.solr.handler.admin.LukeRequestHandler" /> + <requestHandler name="/admin/system" class="org.apache.solr.handler.admin.SystemInfoHandler" /> + <requestHandler name="/admin/plugins" class="org.apache.solr.handler.admin.PluginInfoHandler" /> + <requestHandler name="/admin/threads" class="org.apache.solr.handler.admin.ThreadDumpHandler" /> + <requestHandler name="/admin/properties" class="org.apache.solr.handler.admin.PropertiesRequestHandler" /> + <requestHandler name="/admin/file" class="org.apache.solr.handler.admin.ShowFileRequestHandler" > + + If you wish to hide files under ${solr.home}/conf, explicitly register the ShowFileRequestHandler using: + <requestHandler name="/admin/file" class="org.apache.solr.handler.admin.ShowFileRequestHandler" > + <lst name="invariants"> + <str name="hidden">synonyms.txt</str> + <str name="hidden">anotherfile.txt</str> + </lst> + </requestHandler> + --> + <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" /> + + <!-- ping/healthcheck --> + <requestHandler name="/admin/ping" class="PingRequestHandler"> + <lst name="defaults"> + <str name="qt">standard</str> + <str name="q">solrpingquery</str> + <str name="echoParams">all</str> + </lst> + </requestHandler> + + <!-- Echo the request contents back to the client --> + <requestHandler name="/debug/dump" class="solr.DumpRequestHandler" > + <lst name="defaults"> + <str name="echoParams">explicit</str> <!-- for all params (including the default etc) use: 'all' --> + <str name="echoHandler">true</str> + </lst> + </requestHandler> + + <highlighting> + <!-- Configure the standard fragmenter --> + <!-- This could most likely be commented out in the "default" case --> + <fragmenter name="gap" class="org.apache.solr.highlight.GapFragmenter" default="true"> + <lst name="defaults"> + <int name="hl.fragsize">100</int> + </lst> + </fragmenter> + + <!-- A regular-expression-based fragmenter (f.i., for sentence extraction) --> + <fragmenter name="regex" class="org.apache.solr.highlight.RegexFragmenter"> + <lst name="defaults"> + <!-- slightly smaller fragsizes work better because of slop --> + <int name="hl.fragsize">70</int> + <!-- allow 50% slop on fragment sizes --> + <float name="hl.regex.slop">0.5</float> + <!-- a basic sentence pattern --> + <str name="hl.regex.pattern">[-\w ,/\n\"']{20,200}</str> + </lst> + </fragmenter> + + <!-- Configure the standard formatter --> + <formatter name="html" class="org.apache.solr.highlight.HtmlFormatter" default="true"> + <lst name="defaults"> + <str name="hl.simple.pre"><![CDATA[<em>]]></str> + <str name="hl.simple.post"><![CDATA[</em>]]></str> + </lst> + </formatter> + </highlighting> + + + <!-- queryResponseWriter plugins... query responses will be written using the + writer specified by the 'wt' request parameter matching the name of a registered + writer. + The "default" writer is the default and will be used if 'wt' is not specified + in the request. XMLResponseWriter will be used if nothing is specified here. + The json, python, and ruby writers are also available by default. + + <queryResponseWriter name="xml" class="org.apache.solr.request.XMLResponseWriter" default="true"/> + <queryResponseWriter name="json" class="org.apache.solr.request.JSONResponseWriter"/> + <queryResponseWriter name="python" class="org.apache.solr.request.PythonResponseWriter"/> + <queryResponseWriter name="ruby" class="org.apache.solr.request.RubyResponseWriter"/> + <queryResponseWriter name="php" class="org.apache.solr.request.PHPResponseWriter"/> + <queryResponseWriter name="phps" class="org.apache.solr.request.PHPSerializedResponseWriter"/> + + <queryResponseWriter name="custom" class="com.example.MyResponseWriter"/> + --> + + <!-- XSLT response writer transforms the XML output by any xslt file found + in Solr's conf/xslt directory. Changes to xslt files are checked for + every xsltCacheLifetimeSeconds. + --> + <queryResponseWriter name="xslt" class="org.apache.solr.request.XSLTResponseWriter"> + <int name="xsltCacheLifetimeSeconds">5</int> + </queryResponseWriter> + + + <queryParser name="wikitty" class="org.nuiton.wikitty.solr.WikittyQueryParser"/> + + <!-- example of registering a query parser + <queryParser name="lucene" class="org.apache.solr.search.LuceneQParserPlugin"/> + --> + + <!-- example of registering a custom function parser + <valueSourceParser name="myfunc" class="com.mycompany.MyValueSourceParser" /> + --> + + <!-- config for the admin interface --> + <admin> + <defaultQuery>solr</defaultQuery> + + <!-- configure a healthcheck file for servers behind a loadbalancer + <healthcheck type="file">server-enabled</healthcheck> + --> + </admin> + +</config> Modified: trunk/wikitty-ui-zk/pom.xml =================================================================== --- trunk/wikitty-ui-zk/pom.xml 2010-09-28 09:51:33 UTC (rev 350) +++ trunk/wikitty-ui-zk/pom.xml 2010-09-28 10:05:55 UTC (rev 351) @@ -6,7 +6,7 @@ <parent> <groupId>org.nuiton</groupId> <artifactId>wikitty</artifactId> - <version>2.1.1-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </parent> <!-- ************************************************************* -->