001    /*
002     * JBoss, Home of Professional Open Source.
003     * Copyright 2008, Red Hat Middleware LLC, and individual contributors
004     * as indicated by the @author tags. See the copyright.txt file in the
005     * distribution for a full listing of individual contributors. 
006     *
007     * This is free software; you can redistribute it and/or modify it
008     * under the terms of the GNU Lesser General Public License as
009     * published by the Free Software Foundation; either version 2.1 of
010     * the License, or (at your option) any later version.
011     *
012     * This software is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015     * Lesser General Public License for more details.
016     *
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this software; if not, write to the Free
019     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021     */
022    package org.jboss.dna.sequencer.java;
023    
024    import java.io.IOException;
025    import java.io.InputStream;
026    import java.util.List;
027    import org.apache.commons.lang.StringUtils;
028    import org.jboss.dna.common.monitor.ProgressMonitor;
029    import org.jboss.dna.graph.properties.NameFactory;
030    import org.jboss.dna.graph.properties.Path;
031    import org.jboss.dna.graph.properties.PathFactory;
032    import org.jboss.dna.graph.sequencers.SequencerContext;
033    import org.jboss.dna.graph.sequencers.SequencerOutput;
034    import org.jboss.dna.graph.sequencers.StreamSequencer;
035    import org.jboss.dna.sequencer.java.metadata.AnnotationMetadata;
036    import org.jboss.dna.sequencer.java.metadata.ArrayTypeFieldMetadata;
037    import org.jboss.dna.sequencer.java.metadata.ClassMetadata;
038    import org.jboss.dna.sequencer.java.metadata.ConstructorMetadata;
039    import org.jboss.dna.sequencer.java.metadata.FieldMetadata;
040    import org.jboss.dna.sequencer.java.metadata.ImportMetadata;
041    import org.jboss.dna.sequencer.java.metadata.ImportOnDemandMetadata;
042    import org.jboss.dna.sequencer.java.metadata.JavaMetadata;
043    import org.jboss.dna.sequencer.java.metadata.MarkerAnnotationMetadata;
044    import org.jboss.dna.sequencer.java.metadata.MethodMetadata;
045    import org.jboss.dna.sequencer.java.metadata.MethodTypeMemberMetadata;
046    import org.jboss.dna.sequencer.java.metadata.ModifierMetadata;
047    import org.jboss.dna.sequencer.java.metadata.NormalAnnotationMetadata;
048    import org.jboss.dna.sequencer.java.metadata.PackageMetadata;
049    import org.jboss.dna.sequencer.java.metadata.ParameterizedTypeFieldMetadata;
050    import org.jboss.dna.sequencer.java.metadata.PrimitiveFieldMetadata;
051    import org.jboss.dna.sequencer.java.metadata.QualifiedTypeFieldMetadata;
052    import org.jboss.dna.sequencer.java.metadata.SimpleTypeFieldMetadata;
053    import org.jboss.dna.sequencer.java.metadata.SingleImportMetadata;
054    import org.jboss.dna.sequencer.java.metadata.SingleMemberAnnotationMetadata;
055    import org.jboss.dna.sequencer.java.metadata.TypeMetadata;
056    import org.jboss.dna.sequencer.java.metadata.Variable;
057    
058    /**
059     * A Java sequencer that processes a compilation unit, extracts the meta data for the compilation unit, and then writes these
060     * informations to the repository.
061     * <p>
062     * The structural representation of the informations from the compilation unit looks like this:
063     * <ul>
064     * <li><strong>java:compilationUnit</strong> node of type <code>java:compilationUnit</code>
065     * <ul>
066     * <li> <strong>java:package</strong> - optional child node that represents the package child node of the compilation unit.
067     * <ul>
068     * <li> <strong>java:packageDeclaration</strong> - the package declaration.
069     * <ul>
070     * <li><strong>java:packageName</strong></li> - the package name.
071     * </ul>
072     * </li>
073     * </ul>
074     * </li>
075     * <li> <strong>java:import</strong> - optional child node that represents the import declaration of the compilation unit
076     * <ul>
077     * <li> <strong>java:importDeclaration</strong> - the import declaration
078     * <ul>
079     * <li><strong>java:singleImport</strong>
080     * <ul>
081     * <li> <strong>java:singleTypeImportDeclaration</strong>
082     * <ul>
083     * <li> <strong>java:singleTypeImportkeyword</strong> - the keyword "import"
084     * <li><strong>java:singleImportName</strong></li> - the name of a single import. </li>
085     * </ul>
086     * </li>
087     * </ul>
088     * </li>
089     * <li><strong>java:importOnDemand</strong>
090     * <li> <strong>java:typeImportOnDemandDeclaration</strong>
091     * <ul>
092     * <li> <strong>java:onDemandImportKeyword</strong> - the keyword "import"
093     * <li><strong>java:onDemandImportName</strong></li> - the name of the on demand import. </li>
094     * </ul>
095     * </li>
096     * </li>
097     * </ul>
098     * </li>
099     * </ul>
100     * </li>
101     * <li><strong>java:unitType</strong> - optional child node that represents the top level type (class, interface, enum,
102     * annotation) declaration of the compilation unit</li>
103     * <ul>
104     * <li> <strong>java:classDeclaration</strong> - optional child node that represents the class declaration of the compilation
105     * unit
106     * <ul>
107     * <li> <strong>java:normalClass</strong> - the normal class.
108     * <ul>
109     * <li> <strong>java:normalClassDeclaration</strong> - the normal class declaration
110     * <ul>
111     * <li> <strong>java:modifier</strong> - modifier child node.
112     * <ul>
113     * <li><strong>java:modifierDeclaration</strong> - the modifier declaration.
114     * <ul>
115     * <li><strong>java:modifierName</strong> - modifier name.</li>
116     * </ul>
117     * </li>
118     * </ul>
119     * </li>
120     * <li> <strong>java:normalClassName</strong> - class name.</li>
121     * <li> <strong>java:field</strong> - field child node.
122     * <ul>
123     * <li><strong>java:fieldType</strong> - field type child node.
124     * <ul>
125     * <li><strong>java:type</strong> - type child node.
126     * <ul>
127     * <li>[java:primitiveType, java:simpleType, java:parameterizedType] - can be primitive type or simple type and or parameterized
128     * type<.</li>
129     * </ul>
130     * </li>
131     * </ul>
132     * </li>
133     * </ul>
134     * </li>
135     * <li> <strong>java:constructor</strong> - the constructor child node
136     * <ul>
137     * <li><strong>java:constructorDeclaration</strong> - the constructor declaration.
138     * <ul>
139     * <li><strong>java:constructorName</strong> - constructor name. </li>
140     * <li><strong>java:modifier </strong> - the modifier child node.</li> +
141     * <li><strong>java:parameter </strong> - the parameter child node</li>
142     * </ul>
143     * </li>
144     * </ul>
145     * </li>
146     * <li> <strong>java:method</strong> - method child node.
147     * <ul>
148     * <li></strong>java:methodDeclaration</strong> - method declaration.
149     * <ul>
150     * <li><strong>java:methodName </strong> - method name. </li>
151     * <li><strong>java:modifier </strong> - the modifier child node.</li> +
152     * <li><strong>java:resultType </strong> - the result type child node </li> +
153     * <li><strong>java:parameter </strong> - the parameter child node</li>
154     * </ul>
155     * </li>
156     * </ul>
157     * </li>
158     * </ul>
159     * </li>
160     * </ul>
161     * </li>
162     * </ul>
163     * </li>
164     * </ul>
165     * </li>
166     * </ul>
167     * </p>
168     * 
169     * @author Serge Pagop
170     */
171    public class JavaMetadataSequencer implements JavaSourceCndDefinition, StreamSequencer {
172    
173        /**
174         * {@inheritDoc}
175         * 
176         * @see org.jboss.dna.graph.sequencers.StreamSequencer#sequence(java.io.InputStream,
177         *      org.jboss.dna.graph.sequencers.SequencerOutput, org.jboss.dna.graph.sequencers.SequencerContext,
178         *      org.jboss.dna.common.monitor.ProgressMonitor)
179         */
180        public void sequence( InputStream stream,
181                              SequencerOutput output,
182                              SequencerContext context,
183                              ProgressMonitor progressMonitor ) {
184            progressMonitor.beginTask(10, JavaMetadataI18n.sequencerTaskName);
185    
186            JavaMetadata javaMetadata = null;
187            NameFactory nameFactory = context.getFactories().getNameFactory();
188            PathFactory pathFactory = context.getFactories().getPathFactory();
189    
190            try {
191                javaMetadata = JavaMetadata.instance(stream, JavaMetadataUtil.length(stream), null, progressMonitor.createSubtask(10));
192                if (progressMonitor.isCancelled()) return;
193            } catch (IOException e) {
194                e.printStackTrace();
195                return;
196            }
197            if (javaMetadata != null) {
198                Path javaCompilationUnitNode = pathFactory.create(JAVA_COMPILATION_UNIT_NODE);
199                output.setProperty(javaCompilationUnitNode,
200                                   nameFactory.create(JAVA_COMPILATION_UNIT_PRIMARY_TYPE),
201                                   "java:compilationUnit");
202    
203                // sequence package declaration of a unit.
204                PackageMetadata packageMetadata = javaMetadata.getPackageMetadata();
205                if (packageMetadata != null) {
206                    if (StringUtils.isNotEmpty(packageMetadata.getName())) {
207    
208                        Path javaPackageDeclarationChildNode = pathFactory.create(JAVA_COMPILATION_UNIT_NODE + SLASH
209                                                                                  + JAVA_PACKAGE_CHILD_NODE + SLASH
210                                                                                  + JAVA_PACKAGE_DECLARATION_CHILD_NODE);
211                        output.setProperty(javaPackageDeclarationChildNode,
212                                           nameFactory.create(JAVA_PACKAGE_NAME),
213                                           javaMetadata.getPackageMetadata().getName());
214                    }
215    
216                    int markerAnnotationIndex = 1;
217                    int singleAnnatationIndex = 1;
218                    int normalAnnotationIndex = 1;
219                    for (AnnotationMetadata annotationMetadata : packageMetadata.getAnnotationMetada()) {
220                        if (annotationMetadata instanceof MarkerAnnotationMetadata) {
221                            MarkerAnnotationMetadata markerAnnotationMetadata = (MarkerAnnotationMetadata)annotationMetadata;
222                            Path markerAnnotationChildNode = pathFactory.create(JAVA_COMPILATION_UNIT_NODE + SLASH
223                                                                                + JAVA_PACKAGE_CHILD_NODE + SLASH
224                                                                                + JAVA_PACKAGE_DECLARATION_CHILD_NODE + SLASH
225                                                                                + JAVA_ANNOTATION_CHILD_NODE + SLASH
226                                                                                + JAVA_ANNOTATION_DECLARATION_CHILD_NODE + SLASH
227                                                                                + JAVA_ANNOTATION_TYPE_CHILD_NODE + SLASH
228                                                                                + JAVA_MARKER_ANNOTATION_CHILD_NODE + "["
229                                                                                + markerAnnotationIndex + "]");
230                            output.setProperty(markerAnnotationChildNode,
231                                               nameFactory.create(JAVA_MARKER_ANNOTATION_NAME),
232                                               markerAnnotationMetadata.getName());
233                            markerAnnotationIndex++;
234                        }
235                        if (annotationMetadata instanceof SingleMemberAnnotationMetadata) {
236                            SingleMemberAnnotationMetadata singleMemberAnnotationMetadata = (SingleMemberAnnotationMetadata)annotationMetadata;
237                            Path singleMemberAnnotationChildNode = pathFactory.create(JAVA_COMPILATION_UNIT_NODE + SLASH
238                                                                                      + JAVA_PACKAGE_CHILD_NODE + SLASH
239                                                                                      + JAVA_PACKAGE_DECLARATION_CHILD_NODE + SLASH
240                                                                                      + JAVA_ANNOTATION_CHILD_NODE + SLASH
241                                                                                      + JAVA_ANNOTATION_DECLARATION_CHILD_NODE
242                                                                                      + SLASH + JAVA_ANNOTATION_TYPE_CHILD_NODE
243                                                                                      + SLASH
244                                                                                      + JAVA_SINGLE_ELEMENT_ANNOTATION_CHILD_NODE
245                                                                                      + "[" + singleAnnatationIndex + "]");
246                            output.setProperty(singleMemberAnnotationChildNode,
247                                               nameFactory.create(JAVA_SINGLE_ANNOTATION_NAME),
248                                               singleMemberAnnotationMetadata.getName());
249                            singleAnnatationIndex++;
250                        }
251                        if (annotationMetadata instanceof NormalAnnotationMetadata) {
252                            NormalAnnotationMetadata normalAnnotationMetadata = (NormalAnnotationMetadata)annotationMetadata;
253                            Path normalAnnotationChildNode = pathFactory.create(JAVA_COMPILATION_UNIT_NODE + SLASH
254                                                                                + JAVA_PACKAGE_CHILD_NODE + SLASH
255                                                                                + JAVA_PACKAGE_DECLARATION_CHILD_NODE + SLASH
256                                                                                + JAVA_ANNOTATION_CHILD_NODE + SLASH
257                                                                                + JAVA_ANNOTATION_DECLARATION_CHILD_NODE + SLASH
258                                                                                + JAVA_ANNOTATION_TYPE_CHILD_NODE + SLASH
259                                                                                + JAVA_NORMAL_ANNOTATION_CHILD_NODE + "["
260                                                                                + normalAnnotationIndex + "]");
261    
262                            output.setProperty(normalAnnotationChildNode,
263                                               nameFactory.create(JAVA_NORMALANNOTATION_NAME),
264                                               normalAnnotationMetadata.getName());
265                            normalAnnotationIndex++;
266                        }
267                    }
268                }
269    
270                // sequence import declarations of a unit
271                int importOnDemandIndex = 1;
272                int singleImportIndex = 1;
273                for (ImportMetadata importMetadata : javaMetadata.getImports()) {
274                    if (importMetadata instanceof ImportOnDemandMetadata) {
275                        ImportOnDemandMetadata importOnDemandMetadata = (ImportOnDemandMetadata)importMetadata;
276                        Path importOnDemandChildNode = pathFactory.create(JAVA_COMPILATION_UNIT_NODE + SLASH + JAVA_IMPORT_CHILD_NODE
277                                                                          + SLASH + JAVA_IMPORT_DECLARATION_CHILD_NODE + SLASH
278                                                                          + JAVA_ON_DEMAND_IMPORT_CHILD_NODE + SLASH
279                                                                          + JAVA_ON_DEMAND_IMPORT_TYPE_DECLARATION_CHILD_NODE + "["
280                                                                          + importOnDemandIndex + "]");
281                        output.setProperty(importOnDemandChildNode,
282                                           nameFactory.create(JAVA_ON_DEMAND_IMPORT_NAME),
283                                           importOnDemandMetadata.getName());
284                        importOnDemandIndex++;
285                    }
286                    if (importMetadata instanceof SingleImportMetadata) {
287                        SingleImportMetadata singleImportMetadata = (SingleImportMetadata)importMetadata;
288                        Path singleImportChildNode = pathFactory.create(JAVA_COMPILATION_UNIT_NODE + SLASH + JAVA_IMPORT_CHILD_NODE
289                                                                        + SLASH + JAVA_IMPORT_DECLARATION_CHILD_NODE + SLASH
290                                                                        + JAVA_SINGLE_IMPORT_CHILD_NODE + SLASH
291                                                                        + JAVA_SINGLE_IMPORT_TYPE_DECLARATION_CHILD_NODE + "["
292                                                                        + singleImportIndex + "]");
293                        output.setProperty(singleImportChildNode,
294                                           nameFactory.create(JAVA_SINGLE_IMPORT_NAME),
295                                           singleImportMetadata.getName());
296                        singleImportIndex++;
297                    }
298                }
299    
300                // sequence type declaration (class declaration) information
301                for (TypeMetadata typeMetadata : javaMetadata.getTypeMetadata()) {
302                    // class declaration
303                    if (typeMetadata instanceof ClassMetadata) {
304    
305                        String normalClassRootPath = JAVA_COMPILATION_UNIT_NODE + SLASH + JAVA_UNIT_TYPE_CHILD_NODE + SLASH
306                                                     + JAVA_CLASS_DECLARATION_CHILD_NODE + SLASH + JAVA_NORMAL_CLASS_CHILD_NODE
307                                                     + SLASH + JAVA_NORMAL_CLASS_DECLARATION_CHILD_NODE;
308    
309                        ClassMetadata classMetadata = (ClassMetadata)typeMetadata;
310                        Path classChildNode = pathFactory.create(normalClassRootPath);
311                        output.setProperty(classChildNode, nameFactory.create(JAVA_NORMAL_CLASS_NAME), classMetadata.getName());
312    
313                        // process modifiers of the class declaration
314                        List<ModifierMetadata> classModifiers = classMetadata.getModifiers();
315                        int modifierIndex = 1;
316                        for (ModifierMetadata modifierMetadata : classModifiers) {
317    
318                            Path classModifierChildNode = pathFactory.create(normalClassRootPath + SLASH + JAVA_MODIFIER_CHILD_NODE
319                                                                             + SLASH + JAVA_MODIFIER_DECLARATION_CHILD_NODE + "["
320                                                                             + modifierIndex + "]");
321    
322                            output.setProperty(classModifierChildNode,
323                                               nameFactory.create(JAVA_MODIFIER_NAME),
324                                               modifierMetadata.getName());
325                        }
326    
327                        // process fields of the class unit.
328                        int primitiveIndex = 1;
329                        int simpleIndex = 1;
330                        int parameterizedIndex = 1;
331                        int arrayIndex = 1;
332                        for (FieldMetadata fieldMetadata : classMetadata.getFields()) {
333                            String fieldMemberDataRootPath = JavaMetadataUtil.createPath(normalClassRootPath + SLASH
334                                                                                         + JAVA_FIELD_CHILD_NODE + SLASH
335                                                                                         + JAVA_FIELD_TYPE_CHILD_NODE + SLASH
336                                                                                         + JAVA_TYPE_CHILD_NODE);
337                            if (fieldMetadata instanceof PrimitiveFieldMetadata) {
338                                // primitive type
339                                PrimitiveFieldMetadata primitiveFieldMetadata = (PrimitiveFieldMetadata)fieldMetadata;
340                                String primitiveFieldRootPath = JavaMetadataUtil.createPathWithIndex(fieldMemberDataRootPath + SLASH
341                                                                                                     + JAVA_PRIMITIVE_TYPE_CHILD_NODE,
342                                                                                                     primitiveIndex);
343                                // type
344                                Path primitiveTypeChildNode = pathFactory.create(primitiveFieldRootPath);
345                                output.setProperty(primitiveTypeChildNode,
346                                                   nameFactory.create(JAVA_PRIMITIVE_TYPE_NAME),
347                                                   primitiveFieldMetadata.getType());
348                                // modifiers
349                                List<ModifierMetadata> modifiers = primitiveFieldMetadata.getModifiers();
350                                int primitiveModifierIndex = 1;
351                                for (ModifierMetadata modifierMetadata : modifiers) {
352                                    String modifierPath = JavaMetadataUtil.createPathWithIndex(primitiveFieldRootPath + SLASH
353                                                                                               + JAVA_MODIFIER_CHILD_NODE + SLASH
354                                                                                               + JAVA_MODIFIER_DECLARATION_CHILD_NODE,
355                                                                                               primitiveModifierIndex);
356                                    Path modifierChildNode = pathFactory.create(modifierPath);
357                                    output.setProperty(modifierChildNode,
358                                                       nameFactory.create(JAVA_MODIFIER_NAME),
359                                                       modifierMetadata.getName());
360                                    primitiveModifierIndex++;
361                                }
362                                // variables
363                                List<Variable> variables = primitiveFieldMetadata.getVariables();
364                                int primitiveVariableIndex = 1;
365                                for (Variable variable : variables) {
366                                    String variablePath = JavaMetadataUtil.createPathWithIndex(primitiveFieldRootPath + SLASH
367                                                                                               + JAVA_PRIMITIVE_TYPE_VARIABLE + SLASH
368                                                                                               + JAVA_VARIABLE,
369                                                                                               primitiveVariableIndex);
370                                    Path primitiveChildNode = pathFactory.create(variablePath);
371                                    VariableSequencer.sequenceTheVariable(output, nameFactory, variable, primitiveChildNode);
372                                    primitiveVariableIndex++;
373                                }
374                                primitiveIndex++;
375                            }
376    
377                            // Array type
378                            if (fieldMetadata instanceof ArrayTypeFieldMetadata) {
379                                ArrayTypeFieldMetadata arrayTypeFieldMetadata = (ArrayTypeFieldMetadata)fieldMetadata;
380                                String arrayTypeRootPath = JavaMetadataUtil.createPathWithIndex(fieldMemberDataRootPath + SLASH
381                                                                                                + JAVA_ARRAY_TYPE_CHILD_NODE,
382                                                                                                arrayIndex);
383                                ArrayTypeFieldMetadataSequencer.sequenceFieldMemberData(arrayTypeFieldMetadata,
384                                                                                        pathFactory,
385                                                                                        nameFactory,
386                                                                                        output,
387                                                                                        arrayTypeRootPath,
388                                                                                        arrayIndex);
389                                arrayIndex++;
390                            }
391    
392                            // Simple type
393                            if (fieldMetadata instanceof SimpleTypeFieldMetadata) {
394                                SimpleTypeFieldMetadata simpleTypeFieldMetadata = (SimpleTypeFieldMetadata)fieldMetadata;
395                                String simpleTypeFieldRootPath = JavaMetadataUtil.createPathWithIndex(JAVA_COMPILATION_UNIT_NODE
396                                                                                                      + SLASH
397                                                                                                      + JAVA_UNIT_TYPE_CHILD_NODE
398                                                                                                      + SLASH
399                                                                                                      + JAVA_CLASS_DECLARATION_CHILD_NODE
400                                                                                                      + SLASH
401                                                                                                      + JAVA_NORMAL_CLASS_CHILD_NODE
402                                                                                                      + SLASH
403                                                                                                      + JAVA_NORMAL_CLASS_DECLARATION_CHILD_NODE
404                                                                                                      + SLASH + JAVA_FIELD_CHILD_NODE
405                                                                                                      + SLASH
406                                                                                                      + JAVA_FIELD_TYPE_CHILD_NODE
407                                                                                                      + SLASH + JAVA_TYPE_CHILD_NODE
408                                                                                                      + SLASH
409                                                                                                      + JAVA_SIMPLE_TYPE_CHILD_NODE,
410                                                                                                      simpleIndex);
411                                Path simpleTypeFieldChildNode = pathFactory.create(simpleTypeFieldRootPath);
412                                output.setProperty(simpleTypeFieldChildNode,
413                                                   nameFactory.create(JAVA_SIMPLE_TYPE_NAME),
414                                                   simpleTypeFieldMetadata.getType());
415    
416                                // Simple type modifies
417                                List<ModifierMetadata> simpleModifiers = simpleTypeFieldMetadata.getModifiers();
418                                int simpleTypeModifierIndex = 1;
419                                for (ModifierMetadata modifierMetadata : simpleModifiers) {
420                                    String simpleTypeModifierPath = JavaMetadataUtil.createPathWithIndex(simpleTypeFieldRootPath
421                                                                                                         + SLASH
422                                                                                                         + JAVA_SIMPLE_TYPE_MODIFIER_CHILD_NODE
423                                                                                                         + SLASH
424                                                                                                         + JAVA_MODIFIER_DECLARATION_CHILD_NODE,
425                                                                                                         simpleTypeModifierIndex);
426                                    Path simpleTypeModifierChildNode = pathFactory.create(simpleTypeModifierPath);
427                                    output.setProperty(simpleTypeModifierChildNode,
428                                                       nameFactory.create(JAVA_MODIFIER_NAME),
429                                                       modifierMetadata.getName());
430                                    simpleTypeModifierIndex++;
431                                }
432    
433                                // Simple type variables
434                                List<Variable> variables = simpleTypeFieldMetadata.getVariables();
435                                int simpleTypeVariableIndex = 1;
436                                for (Variable variable : variables) {
437                                    String variablePath = JavaMetadataUtil.createPathWithIndex(simpleTypeFieldRootPath + SLASH
438                                                                                               + JAVA_SIMPLE_TYPE_VARIABLE + SLASH
439                                                                                               + JAVA_VARIABLE,
440                                                                                               simpleTypeVariableIndex);
441                                    Path primitiveChildNode = pathFactory.create(variablePath);
442                                    VariableSequencer.sequenceTheVariable(output, nameFactory, variable, primitiveChildNode);
443                                    simpleTypeVariableIndex++;
444                                }
445    
446                                simpleIndex++;
447                            }
448    
449                            // Qualified type
450                            if (fieldMetadata instanceof QualifiedTypeFieldMetadata) {
451                                @SuppressWarnings( "unused" )
452                                QualifiedTypeFieldMetadata qualifiedTypeFieldMetadata = (QualifiedTypeFieldMetadata)fieldMetadata;
453                            }
454    
455                            // Parameterized type
456                            if (fieldMetadata instanceof ParameterizedTypeFieldMetadata) {
457                                ParameterizedTypeFieldMetadata parameterizedTypeFieldMetadata = (ParameterizedTypeFieldMetadata)fieldMetadata;
458                                String parameterizedTypeFieldRootPath = ParameterizedTypeFieldMetadataSequencer.getParameterizedTypeFieldRootPath(parameterizedIndex);
459                                ParameterizedTypeFieldMetadataSequencer.sequenceTheParameterizedTypeName(parameterizedTypeFieldMetadata,
460                                                                                                         parameterizedTypeFieldRootPath,
461                                                                                                         pathFactory,
462                                                                                                         nameFactory,
463                                                                                                         output);
464                                // Parameterized type modifiers
465                                List<ModifierMetadata> parameterizedTypeModifiers = parameterizedTypeFieldMetadata.getModifiers();
466                                int parameterizedTypeModifierIndex = 1;
467                                for (ModifierMetadata modifierMetadata : parameterizedTypeModifiers) {
468                                    String parameterizedTypeModifierPath = ParameterizedTypeFieldMetadataSequencer.getParameterizedTypeFieldRModifierPath(parameterizedTypeFieldRootPath,
469                                                                                                                                                          parameterizedTypeModifierIndex);
470                                    ParameterizedTypeFieldMetadataSequencer.sequenceTheParameterizedTypeModifier(modifierMetadata,
471                                                                                                                 parameterizedTypeModifierPath,
472                                                                                                                 pathFactory,
473                                                                                                                 nameFactory,
474                                                                                                                 output);
475                                    parameterizedTypeModifierIndex++;
476                                }
477                                // Parameterized type variables
478                                List<Variable> parameterizedTypeVariables = parameterizedTypeFieldMetadata.getVariables();
479                                int parameterizedTypeVariableIndex = 1;
480                                for (Variable variable : parameterizedTypeVariables) {
481    
482                                    Path parameterizedTypeVariableChildNode = ParameterizedTypeFieldMetadataSequencer.getParameterizedTypeFieldVariablePath(pathFactory,
483                                                                                                                                                            parameterizedTypeFieldRootPath,
484                                                                                                                                                            parameterizedTypeVariableIndex);
485                                    VariableSequencer.sequenceTheVariable(output,
486                                                                          nameFactory,
487                                                                          variable,
488                                                                          parameterizedTypeVariableChildNode);
489                                    parameterizedTypeVariableIndex++;
490                                }
491    
492                                parameterizedIndex++;
493                            }
494    
495                        }
496    
497                        // process methods of the unit.
498                        List<MethodMetadata> methods = classMetadata.getMethods();
499                        int methodIndex = 1;
500                        int constructorIndex = 1;
501                        for (MethodMetadata methodMetadata : methods) {
502                            if (methodMetadata.isContructor()) {
503                                // process constructor
504                                ConstructorMetadata constructorMetadata = (ConstructorMetadata)methodMetadata;
505                                String constructorRootPath = JavaMetadataUtil.createPathWithIndex(JAVA_COMPILATION_UNIT_NODE
506                                                                                                  + SLASH
507                                                                                                  + JAVA_UNIT_TYPE_CHILD_NODE
508                                                                                                  + SLASH
509                                                                                                  + JAVA_CLASS_DECLARATION_CHILD_NODE
510                                                                                                  + SLASH
511                                                                                                  + JAVA_NORMAL_CLASS_CHILD_NODE
512                                                                                                  + SLASH
513                                                                                                  + JAVA_NORMAL_CLASS_DECLARATION_CHILD_NODE
514                                                                                                  + SLASH
515                                                                                                  + JAVA_CONSTRUCTOR_CHILD_NODE
516                                                                                                  + SLASH
517                                                                                                  + JAVA_CONSTRUCTOR_DECLARATION_CHILD_NODE,
518                                                                                                  constructorIndex);
519                                Path constructorChildNode = pathFactory.create(constructorRootPath);
520                                output.setProperty(constructorChildNode,
521                                                   nameFactory.create(JAVA_CONSTRUCTOR_NAME),
522                                                   constructorMetadata.getName());
523                                List<ModifierMetadata> modifiers = constructorMetadata.getModifiers();
524                                // modifiers
525                                int constructorModifierIndex = 1;
526                                for (ModifierMetadata modifierMetadata : modifiers) {
527                                    String contructorModifierPath = JavaMetadataUtil.createPathWithIndex(constructorRootPath
528                                                                                                         + SLASH
529                                                                                                         + JAVA_MODIFIER_CHILD_NODE
530                                                                                                         + SLASH
531                                                                                                         + JAVA_MODIFIER_DECLARATION_CHILD_NODE,
532                                                                                                         constructorModifierIndex);
533    
534                                    Path constructorModifierChildNode = pathFactory.create(contructorModifierPath);
535                                    output.setProperty(constructorModifierChildNode,
536                                                       nameFactory.create(JAVA_MODIFIER_NAME),
537                                                       modifierMetadata.getName());
538                                    constructorModifierIndex++;
539                                }
540    
541                                // constructor parameters
542                                int constructorParameterIndex = 1;
543                                for (FieldMetadata fieldMetadata : constructorMetadata.getParameters()) {
544    
545                                    String constructorParameterRootPath = JavaMetadataUtil.createPathWithIndex(constructorRootPath
546                                                                                                               + SLASH
547                                                                                                               + JAVA_PARAMETER
548                                                                                                               + SLASH
549                                                                                                               + JAVA_FORMAL_PARAMETER,
550                                                                                                               constructorParameterIndex);
551                                    // primitive type
552                                    if (fieldMetadata instanceof PrimitiveFieldMetadata) {
553    
554                                        PrimitiveFieldMetadata primitiveMetadata = (PrimitiveFieldMetadata)fieldMetadata;
555                                        String constructPrimitiveFormalParamRootPath = MethodMetadataSequencer.createMethodParamRootPath(constructorParameterRootPath);
556                                        // type
557                                        Path constructorPrimitiveTypeParamChildNode = pathFactory.create(constructPrimitiveFormalParamRootPath);
558                                        output.setProperty(constructorPrimitiveTypeParamChildNode,
559                                                           nameFactory.create(JAVA_PRIMITIVE_TYPE_NAME),
560                                                           primitiveMetadata.getType());
561    
562                                        Path constructorPrimitiveParamChildNode = MethodMetadataSequencer.createMethodParamPath(pathFactory,
563                                                                                                                                constructPrimitiveFormalParamRootPath);
564                                        // variables
565                                        for (Variable variable : primitiveMetadata.getVariables()) {
566                                            VariableSequencer.sequenceTheVariable(output,
567                                                                                  nameFactory,
568                                                                                  variable,
569                                                                                  constructorPrimitiveParamChildNode);
570                                        }
571                                    }
572                                    // Simple type
573                                    if (fieldMetadata instanceof SimpleTypeFieldMetadata) {
574                                        SimpleTypeFieldMetadata simpleTypeFieldMetadata = (SimpleTypeFieldMetadata)fieldMetadata;
575                                        SimpleTypeMetadataSequencer.sequenceMethodFormalParam(output,
576                                                                                              nameFactory,
577                                                                                              pathFactory,
578                                                                                              simpleTypeFieldMetadata,
579                                                                                              constructorParameterRootPath);
580    
581                                    }
582                                    // parameterized type
583                                    if (fieldMetadata instanceof ParameterizedTypeFieldMetadata) {
584                                        @SuppressWarnings( "unused" )
585                                        ParameterizedTypeFieldMetadata parameterizedTypeFieldMetadata = (ParameterizedTypeFieldMetadata)fieldMetadata;
586    
587                                    }
588                                    // TODO support for more types
589    
590                                    constructorParameterIndex++;
591                                }
592    
593                                constructorIndex++;
594                            } else {
595    
596                                // normal method
597                                MethodTypeMemberMetadata methodTypeMemberMetadata = (MethodTypeMemberMetadata)methodMetadata;
598                                String methodRootPath = JavaMetadataUtil.createPathWithIndex(JAVA_COMPILATION_UNIT_NODE
599                                                                                             + SLASH
600                                                                                             + JAVA_UNIT_TYPE_CHILD_NODE
601                                                                                             + SLASH
602                                                                                             + JAVA_CLASS_DECLARATION_CHILD_NODE
603                                                                                             + SLASH
604                                                                                             + JAVA_NORMAL_CLASS_CHILD_NODE
605                                                                                             + SLASH
606                                                                                             + JAVA_NORMAL_CLASS_DECLARATION_CHILD_NODE
607                                                                                             + SLASH + JAVA_METHOD_CHILD_NODE + SLASH
608                                                                                             + JAVA_METHOD_DECLARATION_CHILD_NODE,
609                                                                                             methodIndex);
610                                Path methodChildNode = pathFactory.create(methodRootPath);
611                                output.setProperty(methodChildNode,
612                                                   nameFactory.create(JAVA_METHOD_NAME),
613                                                   methodTypeMemberMetadata.getName());
614    
615                                // method modifiers
616                                int methodModierIndex = 1;
617                                for (ModifierMetadata modifierMetadata : methodTypeMemberMetadata.getModifiers()) {
618                                    String methodModifierPath = JavaMetadataUtil.createPathWithIndex(methodRootPath
619                                                                                                     + SLASH
620                                                                                                     + JAVA_MODIFIER_CHILD_NODE
621                                                                                                     + SLASH
622                                                                                                     + JAVA_MODIFIER_DECLARATION_CHILD_NODE,
623                                                                                                     methodModierIndex);
624                                    Path methodModifierChildNode = pathFactory.create(methodModifierPath);
625                                    output.setProperty(methodModifierChildNode,
626                                                       nameFactory.create(JAVA_MODIFIER_NAME),
627                                                       modifierMetadata.getName());
628                                    methodModierIndex++;
629                                }
630    
631                                int methodParameterIndex = 1;
632                                for (FieldMetadata fieldMetadata : methodMetadata.getParameters()) {
633    
634                                    String methodParamRootPath = JavaMetadataUtil.createPathWithIndex(methodRootPath + SLASH
635                                                                                                      + JAVA_PARAMETER + SLASH
636                                                                                                      + JAVA_FORMAL_PARAMETER,
637                                                                                                      methodParameterIndex);
638    
639                                    if (fieldMetadata instanceof PrimitiveFieldMetadata) {
640    
641                                        PrimitiveFieldMetadata primitive = (PrimitiveFieldMetadata)fieldMetadata;
642    
643                                        String methodPrimitiveFormalParamRootPath = JavaMetadataUtil.createPath(methodParamRootPath
644                                                                                                                + SLASH
645                                                                                                                + JAVA_TYPE_CHILD_NODE
646                                                                                                                + SLASH
647                                                                                                                + JAVA_PRIMITIVE_TYPE_CHILD_NODE);
648    
649                                        Path methodParamChildNode = MethodMetadataSequencer.createMethodParamPath(pathFactory,
650                                                                                                                  methodPrimitiveFormalParamRootPath);
651                                        // variables
652                                        for (Variable variable : primitive.getVariables()) {
653                                            VariableSequencer.sequenceTheVariable(output, nameFactory, variable, methodParamChildNode);
654                                        }
655                                        // type
656                                        Path methodPrimitiveTypeParamChildNode = pathFactory.create(methodPrimitiveFormalParamRootPath);
657                                        output.setProperty(methodPrimitiveTypeParamChildNode,
658                                                           nameFactory.create(JAVA_PRIMITIVE_TYPE_NAME),
659                                                           primitive.getType());
660    
661                                    }
662    
663                                    if (fieldMetadata instanceof SimpleTypeFieldMetadata) {
664                                        SimpleTypeFieldMetadata simpleTypeFieldMetadata = (SimpleTypeFieldMetadata)fieldMetadata;
665                                        SimpleTypeMetadataSequencer.sequenceMethodFormalParam(output,
666                                                                                              nameFactory,
667                                                                                              pathFactory,
668                                                                                              simpleTypeFieldMetadata,
669                                                                                              methodParamRootPath);
670                                    }
671                                    if (fieldMetadata instanceof ArrayTypeFieldMetadata) {
672                                        ArrayTypeFieldMetadata arrayTypeFieldMetadata = (ArrayTypeFieldMetadata)fieldMetadata;
673                                        ArrayTypeFieldMetadataSequencer.sequenceMethodFormalParam(output,
674                                                                                                  nameFactory,
675                                                                                                  pathFactory,
676                                                                                                  arrayTypeFieldMetadata,
677                                                                                                  methodParamRootPath);
678    
679                                    }
680    
681                                    // TODO parameter reference types
682    
683                                    methodParameterIndex++;
684                                }
685    
686                                // method return type
687                                FieldMetadata methodReturnType = methodTypeMemberMetadata.getReturnType();
688    
689                                if (methodReturnType instanceof PrimitiveFieldMetadata) {
690                                    PrimitiveFieldMetadata methodReturnPrimitiveType = (PrimitiveFieldMetadata)methodReturnType;
691                                    String methodReturnPrimitiveTypePath = JavaMetadataUtil.createPath(methodRootPath
692                                                                                                       + SLASH
693                                                                                                       + JAVA_RETURN_TYPE
694                                                                                                       + SLASH
695                                                                                                       + JAVA_PRIMITIVE_TYPE_CHILD_NODE);
696                                    Path methodReturnPrimitiveTypeChildNode = pathFactory.create(methodReturnPrimitiveTypePath);
697                                    output.setProperty(methodReturnPrimitiveTypeChildNode,
698                                                       nameFactory.create(JAVA_PRIMITIVE_TYPE_NAME),
699                                                       methodReturnPrimitiveType.getType());
700    
701                                }
702                                if(methodReturnType instanceof SimpleTypeFieldMetadata) {
703                                    SimpleTypeFieldMetadata simpleTypeFieldMetadata = (SimpleTypeFieldMetadata) methodReturnType;
704                                    SimpleTypeMetadataSequencer.sequenceMethodReturnType(output,nameFactory,pathFactory,simpleTypeFieldMetadata,methodRootPath);
705                                }
706    
707                                // TODO method return reference type
708    
709                                methodIndex++;
710                            }
711                        }
712                    }
713                    // interface declaration
714    
715                    // enumeration declaration
716                }
717            }
718    
719            progressMonitor.done();
720        }
721    }