KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > importer > java > builder > JavaEcoreBuilder


1 /**
2  * <copyright>
3  *
4  * Copyright (c) 2002-2005 IBM Corporation and others.
5  * All rights reserved. This program and the accompanying materials
6  * are made available under the terms of the Eclipse Public License v1.0
7  * which accompanies this distribution, and is available at
8  * http://www.eclipse.org/legal/epl-v10.html
9  *
10  * Contributors:
11  * IBM - Initial API and implementation
12  *
13  * </copyright>
14  *
15  * $Id: JavaEcoreBuilder.java,v 1.7 2005/06/22 19:53:52 davidms Exp $
16  */

17 package org.eclipse.emf.importer.java.builder;
18
19 import java.io.BufferedInputStream JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.Arrays JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.Comparator JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Set JavaDoc;
32 import java.util.StringTokenizer JavaDoc;
33 import java.util.TreeSet JavaDoc;
34 import java.util.regex.Matcher JavaDoc;
35 import java.util.regex.Pattern JavaDoc;
36
37 import org.eclipse.core.resources.IContainer;
38 import org.eclipse.core.resources.IFile;
39 import org.eclipse.core.resources.IProject;
40 import org.eclipse.core.resources.IResource;
41 import org.eclipse.core.runtime.CoreException;
42 import org.eclipse.core.runtime.IPath;
43 import org.eclipse.core.runtime.IProgressMonitor;
44 import org.eclipse.core.runtime.IStatus;
45 import org.eclipse.core.runtime.MultiStatus;
46 import org.eclipse.core.runtime.Status;
47 import org.eclipse.jdt.core.Flags;
48 import org.eclipse.jdt.core.IJavaProject;
49 import org.eclipse.jdt.core.IPackageFragmentRoot;
50 import org.eclipse.jdt.core.JavaCore;
51 import org.eclipse.jdt.core.JavaModelException;
52 import org.eclipse.jdt.core.jdom.DOMFactory;
53 import org.eclipse.jdt.core.jdom.IDOMCompilationUnit;
54 import org.eclipse.jdt.core.jdom.IDOMField;
55 import org.eclipse.jdt.core.jdom.IDOMImport;
56 import org.eclipse.jdt.core.jdom.IDOMMethod;
57 import org.eclipse.jdt.core.jdom.IDOMNode;
58 import org.eclipse.jdt.core.jdom.IDOMPackage;
59 import org.eclipse.jdt.core.jdom.IDOMType;
60
61 import org.eclipse.emf.codegen.ecore.CodeGenEcorePlugin;
62 import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
63 import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
64 import org.eclipse.emf.codegen.util.CodeGenUtil;
65 import org.eclipse.emf.common.util.EList;
66 import org.eclipse.emf.common.util.EMap;
67 import org.eclipse.emf.ecore.EAnnotation;
68 import org.eclipse.emf.ecore.EAttribute;
69 import org.eclipse.emf.ecore.EClass;
70 import org.eclipse.emf.ecore.EClassifier;
71 import org.eclipse.emf.ecore.EDataType;
72 import org.eclipse.emf.ecore.EEnum;
73 import org.eclipse.emf.ecore.EEnumLiteral;
74 import org.eclipse.emf.ecore.EModelElement;
75 import org.eclipse.emf.ecore.ENamedElement;
76 import org.eclipse.emf.ecore.EObject;
77 import org.eclipse.emf.ecore.EOperation;
78 import org.eclipse.emf.ecore.EPackage;
79 import org.eclipse.emf.ecore.EParameter;
80 import org.eclipse.emf.ecore.EReference;
81 import org.eclipse.emf.ecore.EStructuralFeature;
82 import org.eclipse.emf.ecore.ETypedElement;
83 import org.eclipse.emf.ecore.EcoreFactory;
84 import org.eclipse.emf.ecore.EcorePackage;
85 import org.eclipse.emf.ecore.plugin.EcorePlugin;
86 import org.eclipse.emf.ecore.resource.Resource;
87 import org.eclipse.emf.ecore.resource.ResourceSet;
88 import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
89 import org.eclipse.emf.ecore.util.EcoreUtil;
90 import org.eclipse.emf.ecore.util.ExtendedMetaData;
91 import org.eclipse.emf.ecore.xml.namespace.XMLNamespacePackage;
92 import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
93 import org.eclipse.emf.importer.ModelImporter;
94 import org.eclipse.emf.importer.java.JavaImporterPlugin;
95
96
97 public class JavaEcoreBuilder
98 {
99   /**
100    * The factory used to create JDOM.
101    */

102   protected static DOMFactory jdomFactory = new DOMFactory();
103
104   /**
105    * The file being generated.
106    */

107   protected IFile genModelFile;
108
109   /**
110    * The GenModel being generated.
111    */

112   protected GenModel genModel;
113
114   /**
115    * The map from a package name to the corresponding package.
116    * These are populated from the GenModels of required projects.
117    */

118   protected Map JavaDoc externalPackageNameToEPackageMap = new HashMap JavaDoc();
119
120   /**
121    * The map from a package name to the corresponding package.
122    * These are populated on demand during traversal as modeled class and enums are discovered.
123    */

124   protected Map JavaDoc packageNameToEPackageMap = new HashMap JavaDoc();
125
126   /**
127    * The map from package to the map of ordering constants.
128    * These are populated as the package interface is traversed.
129    */

130   protected Map JavaDoc ePackageToOrderingMap = new HashMap JavaDoc();
131
132   /**
133    * The map from package to the it's prefix.
134    * These are populated as the package interfaces are traversed.
135    */

136   protected Map JavaDoc ePackageToPrefixMap = new HashMap JavaDoc();
137
138   /**
139    * The map from a model element to the corresponding JDOM node.
140    * These are populated during traversal as each model element is created.
141    */

142   protected Map JavaDoc eModelElementToIDOMNodeMap = new HashMap JavaDoc();
143
144   /**
145    * The map from a typed element to its type name.
146    * These are populated during traversal as each typed element is created.
147    * They must be patched after traversal is completed.
148    */

149   protected Map JavaDoc eTypedElementToTypeNameMap = new HashMap JavaDoc();
150
151   /**
152    * The map from a typed element to its datatype's instance type name.
153    * These are populated during traversal as each typed element is created.
154    * They must be patched after traversal is completed.
155    * They are only needed if the instance must be determined bottom up.
156    */

157   protected Map JavaDoc eTypedElementToInstanceTypeNameMap = new HashMap JavaDoc();
158
159   /**
160    * The set of data types that were created without setting the instance class.
161    */

162   protected Set JavaDoc demandCreatedEDataTypes = new HashSet JavaDoc();
163
164   /**
165    * The map from a class to its base class names.
166    * These are populated during traversal as each class is created.
167    * They must be patched after traversal is completed.
168    */

169   protected Map JavaDoc eClassToSuperTypeNamesMap = new HashMap JavaDoc();
170
171   /**
172    * The map from a reference to the name it's opposite.
173    * These are populated during traversal as each reference with an opposite is created.
174    * They must be patched after traversal and patching of typed elements is completed.
175    * The opposite found as a feature of the type.
176    */

177   protected Map JavaDoc eReferenceToOppositeNameMap = new HashMap JavaDoc();
178
179   /**
180    * All the external GenModels from all required projects.
181    */

182   protected Collection JavaDoc externalGenModels = new ArrayList JavaDoc();
183
184   /**
185    * All the used GenPackages.
186    */

187   protected Collection JavaDoc usedGenPackages = new ArrayList JavaDoc();
188
189   protected MultiStatus status;
190
191   /**
192    * The old version to against which to reconcile.
193    */

194   protected GenModel oldGenModelVersion;
195
196   /**
197    * Creates a builder for the given file.
198    */

199   public JavaEcoreBuilder(IFile genModelFile)
200   {
201     this.genModelFile = genModelFile;
202
203     status = new MultiStatus(
204       JavaImporterPlugin.getPlugin().getBundle().getSymbolicName(),
205       0,
206       CodeGenEcorePlugin.INSTANCE.getString("_UI_ErrorsWereDetectedJava_message"),
207       null);
208   }
209
210   public JavaEcoreBuilder(IFile genModelFile, GenModel oldGenModelVersion)
211   {
212     this(genModelFile);
213     this.oldGenModelVersion = oldGenModelVersion;
214   }
215
216   public JavaEcoreBuilder(IFile genModelFile, GenModel oldGenModelVersion, GenModel genModel)
217   {
218     this(genModelFile, oldGenModelVersion);
219     this.genModel = genModel;
220   }
221
222   protected ResourceSet createResourceSet()
223   {
224     ResourceSet result = new ResourceSetImpl();
225     result.getURIConverter().getURIMap().putAll(EcorePlugin.computePlatformURIMap());
226     return result;
227   }
228     
229   protected IPath analyseProject(IProject project) throws Exception JavaDoc
230   {
231     // Walk the project looking for .java files to analyze.
232
//
233
IJavaProject javaProject = JavaCore.create(project);
234     IPackageFragmentRoot[] packageFragmentRoots = javaProject.getPackageFragmentRoots();
235     Set JavaDoc visited = new HashSet JavaDoc();
236     for (int i = 0; i < packageFragmentRoots.length; ++i)
237     {
238       if (packageFragmentRoots[i].getKind() == IPackageFragmentRoot.K_SOURCE)
239       {
240         traverse((IContainer)packageFragmentRoots[i].getUnderlyingResource(), visited);
241       }
242     }
243
244     // Fix all the typed elements that have names which need resolving.
245
//
246
for (Iterator JavaDoc i = eTypedElementToTypeNameMap.entrySet().iterator(); i.hasNext();)
247     {
248       Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
249       ETypedElement eTypedElement = (ETypedElement)entry.getKey();
250       String JavaDoc typeName = (String JavaDoc)entry.getValue();
251       EClassifier eClassifier = resolve(eTypedElement, typeName);
252
253       // If we have resolved to an EClass but we have an EAttribute, we can change it to be an EReference.
254
//
255
if (eClassifier instanceof EClass && eTypedElement instanceof EAttribute)
256       {
257         EAttribute eAttribute = (EAttribute)eTypedElement;
258         EClass container = eAttribute.getEContainingClass();
259         EReference eReference = EcoreFactory.eINSTANCE.createEReference();
260         eReference.setChangeable(eAttribute.isChangeable());
261         eReference.setVolatile(eAttribute.isVolatile());
262         eReference.setTransient(eAttribute.isTransient());
263         eReference.setLowerBound(eAttribute.getLowerBound());
264         eReference.setUpperBound(eAttribute.getUpperBound());
265         eReference.setName(eTypedElement.getName());
266         eReference.getEAnnotations().addAll(eTypedElement.getEAnnotations());
267         container.getEStructuralFeatures().add(container.getEStructuralFeatures().indexOf(eTypedElement), eReference);
268         container.getEStructuralFeatures().remove(eTypedElement);
269         eTypedElement = eReference;
270       }
271       else if (eClassifier instanceof EDataType && eTypedElement instanceof EReference)
272       {
273         EReference eReference = (EReference)eTypedElement;
274         EClass container = eReference.getEContainingClass();
275         EAttribute eAttribute = EcoreFactory.eINSTANCE.createEAttribute();
276         eAttribute.setChangeable(eReference.isChangeable());
277         eAttribute.setVolatile(eReference.isVolatile());
278         eAttribute.setTransient(eReference.isTransient());
279         eAttribute.setLowerBound(eReference.getLowerBound());
280         eAttribute.setUpperBound(eReference.getUpperBound());
281         eAttribute.setName(eTypedElement.getName());
282         eAttribute.getEAnnotations().addAll(eTypedElement.getEAnnotations());
283         container.getEStructuralFeatures().remove(eTypedElement);
284         eTypedElement = eAttribute;
285       }
286
287       String JavaDoc instanceClassName = (String JavaDoc)eTypedElementToInstanceTypeNameMap.get(eTypedElement);
288       if (instanceClassName != null && demandCreatedEDataTypes.contains(eClassifier))
289       {
290         demandCreatedEDataTypes.remove(eClassifier);
291         EClassifier resolvedInstanceClassName = resolve(eTypedElement, instanceClassName, false);
292         ((EDataType)eClassifier).setInstanceClassName(resolvedInstanceClassName.getInstanceClassName());
293       }
294
295       if (eClassifier == null)
296       {
297         error(CodeGenEcorePlugin.INSTANCE.getString("_UI_TheTypeDoesNotResolveCorrectly_message", new Object JavaDoc []{ typeName }));
298         eClassifier = EcorePackage.eINSTANCE.getEObject();
299       }
300
301       // Finally set the type.
302
//
303
eTypedElement.setEType(eClassifier);
304
305       used(eClassifier);
306     }
307
308     // Fix all the classes that have supers that need resolving.
309
//
310
for (Iterator JavaDoc i = eClassToSuperTypeNamesMap.entrySet().iterator(); i.hasNext();)
311     {
312       Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
313       EClass eClass = (EClass)entry.getKey();
314       String JavaDoc[] superTypeNames = (String JavaDoc[])entry.getValue();
315       if (superTypeNames != null)
316       {
317         for (int j = 0; j < superTypeNames.length; ++j)
318         {
319           EClassifier eClassifier = resolve(eClass, superTypeNames[j], false);
320           if (eClassifier.getEPackage() == null)
321           {
322             EPackage ePackage = (EPackage)EcoreUtil.getRootContainer(eClass);
323             EClass superEClass = EcoreFactory.eINSTANCE.createEClass();
324             superEClass.setInstanceClassName(eClassifier.getInstanceClassName());
325             superEClass.setName(eClassifier.getName());
326             superEClass.setAbstract(true);
327             superEClass.setInterface(true);
328             ePackage.getEClassifiers().add(superEClass);
329             eClassifier = superEClass;
330           }
331
332           if (eClassifier instanceof EClass)
333           {
334             if (eClassifier != EcorePackage.eINSTANCE.getEObject())
335             {
336               eClass.getESuperTypes().add(eClassifier);
337               used(eClassifier);
338             }
339           }
340           else
341           {
342             error(CodeGenEcorePlugin.INSTANCE.getString(
343               "_UI_TheSuperTypeDoesNotResolveCorrectly_message",
344               new Object JavaDoc []{ superTypeNames[j] }));
345           }
346         }
347       }
348     }
349
350     // Now we need to hook up opposites by finding the named feature in the type.
351
//
352
for (Iterator JavaDoc i = eReferenceToOppositeNameMap.entrySet().iterator(); i.hasNext();)
353     {
354       Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
355       EReference eReference = (EReference)entry.getKey();
356       String JavaDoc oppositeName = (String JavaDoc)entry.getValue();
357       EClass eClass = (EClass)eReference.getEType();
358       EReference eOpposite = (EReference)eClass.getEStructuralFeature(oppositeName);
359       if (eOpposite == null)
360       {
361         error(CodeGenEcorePlugin.INSTANCE.getString("_UI_TheAttributeIsNotAMemberOf_message", new Object JavaDoc []{
362           oppositeName,
363           eClass.getName() }));
364       }
365       else if (eOpposite.getEOpposite() != eReference && eOpposite.getEOpposite() != null)
366       {
367         error(CodeGenEcorePlugin.INSTANCE.getString("_UI_TheOppositeAlreadyHasOpposite_message", new Object JavaDoc []{
368           oppositeName,
369           eOpposite.getEOpposite().getName(),
370           eOpposite.getEOpposite().getEContainingClass().getName() }));
371       }
372       else
373       {
374         eReference.setEOpposite(eOpposite);
375         eOpposite.setEOpposite(eReference);
376
377         used(eOpposite);
378
379         // Containers must be transient.
380
//
381
if (eOpposite.isContainment())
382         {
383           eReference.setTransient(true);
384         }
385       }
386     }
387
388     // Now we should sort.
389
//
390
for (Iterator JavaDoc i = ePackageToOrderingMap.entrySet().iterator(); i.hasNext();)
391     {
392       Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
393       EPackage ePackage = (EPackage)entry.getKey();
394       Map JavaDoc nameToIDMap = (Map JavaDoc)entry.getValue();
395
396       sort(ePackage.getEClassifiers(), nameToIDMap);
397       for (Iterator JavaDoc j = ePackage.getEClassifiers().iterator(); j.hasNext();)
398       {
399         EClassifier eClassifier = (EClassifier)j.next();
400         if (eClassifier instanceof EClass)
401         {
402           EClass eClass = (EClass)eClassifier;
403           sort(eClass.getEStructuralFeatures(), nameToIDMap);
404         }
405       }
406     }
407
408     // Find the fragment root so that we can generate to the right location (by default).
409
//
410
IPath targetFragmentRoot = project.getFullPath();
411     for (int i = 0; i < packageFragmentRoots.length; ++i)
412     {
413       if (packageFragmentRoots[i].getKind() == IPackageFragmentRoot.K_SOURCE)
414       {
415         IPath path = packageFragmentRoots[i].getUnderlyingResource().getFullPath();
416         if (targetFragmentRoot.isPrefixOf(path))
417         {
418           targetFragmentRoot = path;
419           break;
420         }
421       }
422     }
423     
424     return targetFragmentRoot;
425   }
426
427   public void computeEPackages(IProgressMonitor progressMonitor, ModelImporter modelImporter) throws Exception JavaDoc
428   {
429     IProject project = genModelFile.getProject();
430     project.open(progressMonitor);
431     
432     Collection JavaDoc allGenModelFiles = new ArrayList JavaDoc();
433     Collection JavaDoc allReferencedProjects = new ArrayList JavaDoc();
434     getAllReferencedProjects(allReferencedProjects, project.getDescription().getReferencedProjects());
435     getAllReferencedProjects(allReferencedProjects, project.getDescription().getDynamicReferences());
436     for (Iterator JavaDoc i = allReferencedProjects.iterator(); i.hasNext();)
437     {
438       getAllGenModelFiles(allGenModelFiles, (IProject)i.next());
439     }
440     
441     ResourceSet resourceSet = modelImporter.createResourceSet();
442     for (Iterator JavaDoc i = allGenModelFiles.iterator(); i.hasNext();)
443     {
444       IFile file = (IFile)i.next();
445       Resource resource = resourceSet.getResource(modelImporter.createFileURI(file.getFullPath().toString()), true);
446       GenModel genModel = (GenModel)resource.getContents().get(0);
447       externalGenModels.add(genModel);
448       for (Iterator JavaDoc j = genModel.getGenPackages().iterator(); j.hasNext();)
449       {
450         GenPackage genPackage = (GenPackage)j.next();
451         determineExternalPackages(genPackage, modelImporter);
452       }
453     }
454     
455     IPath targetFragmentRoot = analyseProject(project);
456     modelImporter.setModelPluginDirectory(targetFragmentRoot.toString());
457     
458     for (Iterator JavaDoc i = packageNameToEPackageMap.values().iterator(); i.hasNext();)
459     {
460       EPackage ePackage = (EPackage)i.next();
461       modelImporter.getEPackages().add(ePackage);
462
463       ModelImporter.EPackageInfo ePackageInfo = modelImporter.getEPackageInfo(ePackage);
464       ePackageInfo.setPrefix((String JavaDoc)ePackageToPrefixMap.get(ePackage));
465       for (Iterator JavaDoc entries = packageNameToEPackageMap.entrySet().iterator(); entries.hasNext();)
466       {
467         Map.Entry JavaDoc entry = (Map.Entry JavaDoc)entries.next();
468         if (entry.getValue() == ePackage)
469         {
470           String JavaDoc qualifiedPackageName = (String JavaDoc)entry.getKey();
471           int index = qualifiedPackageName == null ? -1 : qualifiedPackageName.lastIndexOf(".");
472           if (index != -1)
473           {
474             ePackageInfo.setBasePackage(qualifiedPackageName.substring(0, index));
475           }
476           break;
477         }
478       }
479     }
480   }
481   
482   public void used(EModelElement modelElement)
483   {
484     EPackage ePackage = (EPackage)EcoreUtil.getRootContainer(modelElement);
485     if (ePackage != EcorePackage.eINSTANCE)
486     {
487       for (Iterator JavaDoc i = externalGenModels.iterator(); i.hasNext();)
488       {
489         GenModel genModel = (GenModel)i.next();
490         GenPackage genPackage = genModel.findGenPackage(ePackage);
491         if (genPackage != null)
492         {
493           if (!usedGenPackages.contains(genPackage))
494           {
495             usedGenPackages.add(genPackage);
496
497             // Compute the closure.
498
//
499
for (Iterator JavaDoc j = ePackage.eAllContents(); j.hasNext();)
500             {
501               EObject eObject = (EObject)j.next();
502               for (Iterator JavaDoc k = eObject.eCrossReferences().iterator(); k.hasNext();)
503               {
504                 Object JavaDoc o = k.next();
505                 if (o instanceof EModelElement)
506                 {
507                   used((EModelElement)o);
508                 }
509               }
510             }
511           }
512           break;
513         }
514       }
515     }
516   }
517
518   public void determineExternalPackages(GenPackage genPackage)
519   {
520     determineExternalPackages(genPackage, null);
521   }
522   
523   protected void determineExternalPackages(GenPackage genPackage, ModelImporter modelImporter)
524   {
525     if (modelImporter != null)
526     {
527       modelImporter.getReferencedGenPackages().add(genPackage);
528     }
529     EPackage ePackage = genPackage.getEcorePackage();
530     externalPackageNameToEPackageMap.put(genPackage.getInterfacePackageName(), ePackage);
531     for (Iterator JavaDoc i = genPackage.getNestedGenPackages().iterator(); i.hasNext();)
532     {
533       determineExternalPackages((GenPackage)i.next());
534     }
535   }
536
537   /**
538    * Walks the projects recursively.
539    */

540   public void getAllReferencedProjects(Collection JavaDoc result, IProject[] projects) throws CoreException
541   {
542     for (int i = 0; i < projects.length; ++i)
543     {
544       IProject project = projects[i];
545       if (!result.contains(project) && project.exists() && project.isOpen())
546       {
547         result.add(project);
548         getAllReferencedProjects(result, project.getDescription().getReferencedProjects());
549         getAllReferencedProjects(result, project.getDescription().getDynamicReferences());
550       }
551     }
552   }
553
554   /**
555    * Walks the container recursively.
556    */

557   public void getAllGenModelFiles(Collection JavaDoc result, IContainer container) throws CoreException
558   {
559     IResource[] contents = container.members();
560     for (int i = 0; i < contents.length; ++i)
561     {
562       IResource resource = contents[i];
563       if (resource.getType() == IResource.FILE)
564       {
565         getAllGenModelFiles(result, (IFile)resource);
566       }
567       else
568       {
569         getAllGenModelFiles(result, (IContainer)resource);
570       }
571     }
572   }
573
574   /**
575    * Walks the container recursively.
576    */

577   public void getAllGenModelFiles(Collection JavaDoc result, IFile file) throws CoreException
578   {
579     if (file.getName().endsWith(".genmodel"))
580     {
581       IProject project = file.getProject();
582       IJavaProject javaProject = JavaCore.create(project);
583       try
584       {
585         IPath outputLocation = javaProject.getOutputLocation();
586         if (project == project.getWorkspace().getRoot().findMember(javaProject.getOutputLocation())
587           || !outputLocation.isPrefixOf(file.getFullPath()))
588         {
589           result.add(file);
590         }
591       }
592       catch (JavaModelException exception)
593       {
594         JavaImporterPlugin.INSTANCE.log(exception);
595       }
596     }
597   }
598
599   /**
600    * Walks the container recursively.
601    */

602   public void traverse(IContainer container, Set JavaDoc visited) throws CoreException
603   {
604     IResource[] contents = container.members();
605     for (int i = 0; i < contents.length; ++i)
606     {
607       IResource resource = contents[i];
608       if (visited.add(resource))
609       {
610         if (resource.getType() == IResource.FILE)
611         {
612           traverse((IFile)resource);
613         }
614         else
615         {
616           traverse((IContainer)resource, visited);
617         }
618       }
619     }
620   }
621
622   /**
623    * Analyzes .java files as JDOM compilation units.
624    */

625   public void traverse(IFile file) throws CoreException
626   {
627     if ("java".equalsIgnoreCase(file.getProjectRelativePath().getFileExtension()))
628     {
629       try
630       {
631         BufferedInputStream JavaDoc bufferedInputStream = new BufferedInputStream JavaDoc(file.getContents(true));
632         byte[] input = new byte [bufferedInputStream.available()];
633         bufferedInputStream.read(input);
634         bufferedInputStream.close();
635
636         //purpose: using charset from 'file' to decode bytes into in-memory
637
// String object
638
//modifer: Wu Zhi Qiang
639
//date: Aug 25, 2004
640
//action: first get the charset from 'file', then use it
641
// to decode the 'input' bytes object
642
String JavaDoc encoding = null;
643         try
644         {
645           encoding = file.getCharset();
646         }
647         catch (CoreException ce)
648         {
649           // use no encoding
650
}
651         String JavaDoc contents = encoding == null ? new String JavaDoc(input) : new String JavaDoc(input, encoding);
652         IDOMCompilationUnit jCompilationUnit = jdomFactory.createCompilationUnit(contents, "NAME");
653         analyzeCompilationUnit(jCompilationUnit);
654       }
655       catch (IOException JavaDoc exception)
656       {
657         JavaImporterPlugin.INSTANCE.log(exception);
658       }
659     }
660   }
661
662   /**
663    * Walks the compilation unit to analyze the type.
664    */

665   protected void analyzeCompilationUnit(IDOMCompilationUnit compilationUnit)
666   {
667     for (IDOMNode child = compilationUnit.getFirstChild(); child != null; child = child.getNextNode())
668     {
669       if (child.getNodeType() == IDOMNode.TYPE)
670       {
671         analyzeType((IDOMType)child);
672         break;
673       }
674     }
675   }
676
677   /**
678    * Walks the type either as an EClass or an ENum to analyze either the methods or the fields.
679    */

680   protected void analyzeType(IDOMType type)
681   {
682     IDOMCompilationUnit compilationUnit = (IDOMCompilationUnit)type.getParent();
683     String JavaDoc qualifiedPackageName = null;
684     if (compilationUnit.getFirstChild() instanceof IDOMPackage)
685     {
686       qualifiedPackageName = ((IDOMPackage)compilationUnit.getFirstChild()).getName();
687     }
688
689     // Check whether this has @model annotation contents.
690
// If not, it might be a package interface, for backwards compatibility.
691
//
692
String JavaDoc modelAnnotation = getModelAnnotation(type.getComment());
693     boolean isEClassifier = false;
694     String JavaDoc kind = null;
695
696     if (modelAnnotation != null)
697     {
698       kind = getModelAnnotationAttribute(modelAnnotation, "kind");
699       isEClassifier = !"package".equals(kind);
700     }
701     
702     if (isEClassifier)
703     {
704       // Get the package name and see if there's an EPackage for it.
705
//
706
EPackage ePackage = (EPackage)packageNameToEPackageMap.get(qualifiedPackageName);
707       if (ePackage == null)
708       {
709         // Create the EPackage on demand.
710
//
711
ePackage = EcoreFactory.eINSTANCE.createEPackage();
712         int index = qualifiedPackageName == null ? -1 : qualifiedPackageName.lastIndexOf(".");
713         String JavaDoc packageName = index == -1 ? qualifiedPackageName : qualifiedPackageName.substring(index + 1);
714         ePackage.setName(packageName);
715         ePackage.setNsURI("http:///" + (qualifiedPackageName == null ? "null" : qualifiedPackageName.replace('.', '/')) + ".ecore");
716         ePackage.setNsPrefix(qualifiedPackageName == null ? "null" : qualifiedPackageName);
717         packageNameToEPackageMap.put(qualifiedPackageName, ePackage);
718
719         if (packageName != null)
720         {
721           String JavaDoc prefix = Character.toUpperCase(packageName.charAt(0)) + packageName.substring(1);
722           ePackageToPrefixMap.put(ePackage, prefix);
723         }
724       }
725
726       // If it's an interface, then it will be treated as an EClass
727
//
728
if ((type.getFlags() & Flags.AccInterface) != 0)
729       {
730         EClass eClass = EcoreFactory.eINSTANCE.createEClass();
731         eModelElementToIDOMNodeMap.put(eClass, type);
732         eClass.setName(type.getName());
733         ePackage.getEClassifiers().add(eClass);
734         eClass.getEAnnotations().addAll(extractEAnnotations(modelAnnotation));
735         EcoreUtil.setDocumentation(eClass, getModelDocumentation(type.getComment()));
736
737         String JavaDoc[] superInterfaces = type.getSuperInterfaces();
738         String JavaDoc extend = getExtendsAnnotation(type.getComment());
739         if (extend != null && superInterfaces != null)
740         {
741           List JavaDoc superInterfaceList = new ArrayList JavaDoc(Arrays.asList(superInterfaces));
742           for (StringTokenizer JavaDoc stringTokenizer = new StringTokenizer JavaDoc(extend, " ,\t\n\r\f"); stringTokenizer.hasMoreTokens();)
743           {
744             superInterfaceList.remove(stringTokenizer.nextToken());
745           }
746           superInterfaces = new String JavaDoc [superInterfaceList.size()];
747           superInterfaceList.toArray(superInterfaces);
748         }
749         eClassToSuperTypeNamesMap.put(eClass, superInterfaces);
750
751         String JavaDoc isAbstract = getModelAnnotationAttribute(modelAnnotation, "abstract");
752         eClass.setAbstract("true".equals(isAbstract));
753
754         String JavaDoc isInterface = getModelAnnotationAttribute(modelAnnotation, "interface");
755         eClass.setInterface("true".equals(isInterface));
756
757         // Walk the methods.
758
//
759
for (IDOMNode child = type.getFirstChild(); child != null; child = child.getNextNode())
760         {
761           if (child.getNodeType() == IDOMNode.METHOD)
762           {
763             analyzeMethod(eClass, (IDOMMethod)child);
764           }
765         }
766
767         // Additional attributes and references may be defined directly on the interface in order to allow the
768
// get accessor method to have suppressed visibility.
769
//
770
String JavaDoc features = getModelAnnotationAttribute(modelAnnotation, "features");
771         if (features != null)
772         {
773           for (StringTokenizer JavaDoc stringTokenizer = new StringTokenizer JavaDoc(features, " "); stringTokenizer.hasMoreTokens();)
774           {
775             String JavaDoc feature = stringTokenizer.nextToken();
776             if (eClass.getEStructuralFeature(feature) == null)
777             {
778               analyzeMethod(eClass, getFilteredModelAnnotations(modelAnnotation, feature), "get" + Character.toUpperCase(feature.charAt(0))
779                 + feature.substring(1), "java.lang.Object", null, null);
780             }
781             else
782             {
783               warning(CodeGenEcorePlugin.INSTANCE.get