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.getString("_UI_DuplicateFeature_message", new Object JavaDoc []{ feature, eClass.getName() }));
784             }
785           }
786         }
787       }
788       // Otherwise it's treated as an EEnum
789
//
790
else
791       {
792         EEnum eEnum = EcoreFactory.eINSTANCE.createEEnum();
793         eModelElementToIDOMNodeMap.put(eEnum, type);
794         eEnum.setName(type.getName());
795         ePackage.getEClassifiers().add(eEnum);
796         eEnum.getEAnnotations().addAll(extractEAnnotations(modelAnnotation));
797         EcoreUtil.setDocumentation(eEnum, getModelDocumentation(type.getComment()));
798
799         // Walk the fields.
800
//
801
for (IDOMNode child = type.getFirstChild(); child != null; child = child.getNextNode())
802         {
803           if (child.getNodeType() == IDOMNode.FIELD)
804           {
805             analyzeField(eEnum, (IDOMField)child);
806           }
807         }
808       }
809     }
810     // Find Packages and Factories
811
else
812     {
813       String JavaDoc typeName = type.getName();
814       boolean isEPackage = false;
815       if (typeName.endsWith("Package") && typeName.length() > 7)
816       {
817         String JavaDoc packagePrefix = typeName.substring(0, typeName.length() - 7);
818
819         // It's definitely a package if it was declared as such.
820
//
821
if ("package".equals(kind))
822         {
823           isEPackage = true;
824         }
825
826         int index = qualifiedPackageName == null ? -1 : qualifiedPackageName.lastIndexOf(".");
827         String JavaDoc name = index == -1 ? qualifiedPackageName : qualifiedPackageName.substring(index + 1);
828         String JavaDoc nsURI = "http:///" + (qualifiedPackageName == null ? "null" : qualifiedPackageName.replace('.', '/')) + ".ecore";
829         String JavaDoc nsPrefix = qualifiedPackageName == null ? "null" : qualifiedPackageName;
830
831         List JavaDoc eClasses = new ArrayList JavaDoc();
832         List JavaDoc eDataTypes = new ArrayList JavaDoc();
833         Map JavaDoc ordering = new HashMap JavaDoc();
834
835         // It's definitely a package if expected constants eNAME, eNS_PREFIX, or eNS_URI appear.
836
//
837
for (IDOMNode child = type.getFirstChild(); child != null; child = child.getNextNode())
838         {
839           if (child.getNodeType() == IDOMNode.FIELD)
840           {
841             IDOMField field = (IDOMField)child;
842             String JavaDoc childName = child.getName();
843             String JavaDoc childType = field.getType();
844             if ("eNAME".equals(childName))
845             {
846               isEPackage = true;
847               name = field.getInitializer();
848               name = name.substring(2, name.length() - 1);
849             }
850             else if ("eNS_URI".equals(childName))
851             {
852               isEPackage = true;
853               nsURI = field.getInitializer();
854               nsURI = nsURI.substring(2, nsURI.length() - 1);
855             }
856             else if ("eNS_PREFIX".equals(childName))
857             {
858               isEPackage = true;
859               nsPrefix = field.getInitializer();
860               nsPrefix = nsPrefix.substring(2, nsPrefix.length() - 1);
861             }
862             else if ("int".equals(childType) && !childName.endsWith("FEATURE_COUNT"))
863             {
864               try
865               {
866                 String JavaDoc initializer = field.getInitializer();
867                 int plusIndex = initializer.lastIndexOf("+");
868                 if (plusIndex != -1)
869                 {
870                   initializer = initializer.substring(plusIndex + 1);
871                 }
872                 initializer = initializer.trim();
873                 int value = Integer.parseInt(initializer);
874                 ordering.put(childName, new Integer JavaDoc(value));
875               }
876               catch (NumberFormatException JavaDoc exception)
877               {
878                 // This will catch inherited features, or additional things we don't want to worry about.
879
}
880             }
881           }
882           else if (child.getNodeType() == IDOMNode.METHOD)
883           {
884             IDOMMethod method = (IDOMMethod)child;
885             String JavaDoc methodAnnotation = getModelAnnotation(method.getComment());
886             if (methodAnnotation != null)
887             {
888               String JavaDoc returnType = method.getReturnType();
889               if (returnType != null)
890               {
891                 if (returnType.endsWith("EDataType"))
892                 {
893                   EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType();
894                   eDataType.setInstanceClassName(getModelAnnotationAttribute(methodAnnotation, "instanceClass"));
895                   eDataType.setName(method.getName().substring(3));
896                   String JavaDoc isSerializable = getModelAnnotationAttribute(methodAnnotation, "serializable");
897                   if ("false".equals(isSerializable))
898                   {
899                     eDataType.setSerializable(false);
900                   }
901                   eDataTypes.add(eDataType);
902                   eDataType.getEAnnotations().addAll(extractEAnnotations(methodAnnotation));
903                   EcoreUtil.setDocumentation(eDataType, getModelDocumentation(method.getComment()));
904                 }
905                 else if (returnType.endsWith("EClass"))
906                 {
907                   EClass eClass = EcoreFactory.eINSTANCE.createEClass();
908                   String JavaDoc instanceClass = getModelAnnotationAttribute(methodAnnotation, "instanceClass");
909                   if (instanceClass != null)
910                   {
911                     eClass.setInterface(true);
912                     eClass.setAbstract(true);
913                     eClass.setInstanceClassName(instanceClass);
914                     eClass.setName(method.getName().substring(3));
915                     eClasses.add(eClass);
916                   }
917                   else
918                   {
919                     eClass.setInstanceClassName("java.util.Map$Entry");
920                     eClass.setName(method.getName().substring(3));
921                     eClasses.add(eClass);
922
923                     String JavaDoc features = getModelAnnotationAttribute(methodAnnotation, "features");
924                     if (features != null)
925                     {
926                       for (StringTokenizer JavaDoc stringTokenizer = new StringTokenizer JavaDoc(features, " "); stringTokenizer.hasMoreTokens();)
927                       {
928                         String JavaDoc feature = stringTokenizer.nextToken();
929                         analyzeMethod(eClass, getFilteredModelAnnotations(methodAnnotation, feature), "get"
930                           + Character.toUpperCase(feature.charAt(0)) + feature.substring(1), "java.lang.Object", null, null);
931                       }
932                     }
933                     else
934                     {
935                       analyzeMethod(eClass, getFilteredModelAnnotations(methodAnnotation, "key"), "getKey", "java.lang.Object", null, null);
936
937                       analyzeMethod(
938                         eClass,
939                         getFilteredModelAnnotations(methodAnnotation, "value"),
940                         "getValue",
941                         "java.lang.Object",
942                         null,
943                         null);
944                     }
945                   }
946                   eClass.getEAnnotations().addAll(extractEAnnotations(methodAnnotation));
947                   EcoreUtil.setDocumentation(eClass, getModelDocumentation(method.getComment()));
948                 }
949               }
950             }
951           }
952         }
953
954         if (isEPackage || !eClasses.isEmpty() || !eDataTypes.isEmpty())
955         {
956           EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage();
957           ePackageToOrderingMap.put(ePackage, ordering);
958           eModelElementToIDOMNodeMap.put(ePackage, type);
959           ePackage.setNsURI(nsURI);
960           ePackage.setNsPrefix(nsPrefix);
961           ePackage.setName(name);
962           ePackage.getEClassifiers().addAll(eClasses);
963           ePackage.getEClassifiers().addAll(eDataTypes);
964           if (modelAnnotation != null)
965           {
966             ePackage.getEAnnotations().addAll(extractEAnnotations(modelAnnotation));
967           }
968           EcoreUtil.setDocumentation(ePackage, getModelDocumentation(type.getComment()));
969
970           ePackageToPrefixMap.put(ePackage, packagePrefix);
971
972           EPackage existingEPackage = (EPackage)packageNameToEPackageMap.get(qualifiedPackageName);
973           if (existingEPackage != null)
974           {
975             ePackage.getEClassifiers().addAll(existingEPackage.getEClassifiers());
976           }
977
978           packageNameToEPackageMap.put(qualifiedPackageName, ePackage);
979         }
980       }
981     }
982   }
983
984   /**
985    * Creates an EOperation, EAttribute, or EReference as appropriate.
986    */

987   protected void analyzeMethod(EClass eClass, IDOMMethod method)
988   {
989     // Check whether this has @model annotation contents.
990
//
991
String JavaDoc modelAnnotation = getModelAnnotation(method.getComment());
992     if (modelAnnotation != null)
993     {
994       String JavaDoc methodName = method.getName();
995       String JavaDoc returnType = method.getReturnType();
996       String JavaDoc[] parameterNames = method.getParameterNames();
997       String JavaDoc[] parameterTypes = method.getParameterTypes();
998
999       ETypedElement eTypedElement = analyzeMethod(eClass, modelAnnotation, methodName, returnType, parameterNames, parameterTypes);
1000      if (eTypedElement != null)
1001      {
1002        EcoreUtil.setDocumentation(eTypedElement, getModelDocumentation(method.getComment()));
1003      }
1004
1005      eModelElementToIDOMNodeMap.put(eTypedElement, method);
1006      if (eTypedElement instanceof EOperation)
1007      {
1008        EOperation eOperation = (EOperation)eTypedElement;
1009        for (Iterator JavaDoc i = eOperation.getEParameters().iterator(); i.hasNext();)
1010        {
1011          EParameter eParameter = (EParameter)i.next();
1012          eModelElementToIDOMNodeMap.put(eParameter, method);
1013        }
1014      }
1015    }
1016  }
1017
1018  protected ETypedElement analyzeMethod(
1019    EClass eClass,
1020    String JavaDoc modelAnnotation,
1021    String JavaDoc methodName,
1022    String JavaDoc returnType,
1023    String JavaDoc[] parameterNames,
1024    String JavaDoc[] parameterTypes)
1025  {
1026    // We will create an EAttribute, EReference, or an EOperation.
1027
//
1028
ETypedElement eTypedElement = null;
1029    String JavaDoc featureName = methodName;
1030    String JavaDoc parameters = getModelAnnotationAttribute(modelAnnotation, "parameters");
1031    String JavaDoc kind = getModelAnnotationAttribute(modelAnnotation, "kind");
1032
1033    // An operation is declared via the kind property or, for backwards compatibility, by specifying parameters
1034
// (though attribute or reference kind takes precedence).
1035
//
1036
boolean declaredEOperation = "operation".equals(kind) ||
1037      (parameters != null && !"attribute".equals(kind) && !"reference".equals(kind));
1038
1039    // Check whether there are parameters; the special attribute and reference rules only apply for the case of no arguments.
1040
//
1041
if (parameterNames == null && !declaredEOperation && methodName.startsWith("get") && methodName.length() > 3 &&
1042        Character.isUpperCase(methodName.charAt(3)) && !"boolean".equals(returnType) && !"void".equals(returnType))
1043    {
1044      // The feature name is extracted lower cased.
1045
//
1046
featureName = CodeGenUtil.uncapName(methodName.substring(3));
1047    }
1048    else if (parameterNames == null && !declaredEOperation && methodName.startsWith("is") && methodName.length() > 2 &&
1049             Character.isUpperCase(methodName.charAt(2)) && "boolean".equals(returnType))
1050    {
1051      // The name is extracted and lower cased.
1052
//
1053
featureName = CodeGenUtil.uncapName(methodName.substring(2));
1054    }
1055    else
1056    {
1057      // The method is not a structural feature, so it's modeled as an operation.
1058
//
1059
EOperation eOperation = EcoreFactory.eINSTANCE.createEOperation();
1060      eClass.getEOperations().add(eTypedElement = eOperation);
1061
1062      handleETypedElement(eOperation, methodName, returnType, modelAnnotation, eClass.getName() + "." + methodName);
1063      
1064      if (parameterTypes != null)
1065      {
1066        // Each token in parameters will specify a dataType for the corresponding paramter, but can be overridden by a
1067
// parameter-name-prefixed dataType property.
1068
//
1069
StringTokenizer JavaDoc stringTokenizer = new StringTokenizer JavaDoc(parameters == null ? "" : parameters);
1070        for (int i = 0; i < parameterNames.length; ++i)
1071        {
1072          EParameter eParameter = EcoreFactory.eINSTANCE.createEParameter();
1073          eOperation.getEParameters().add(eParameter);
1074          String JavaDoc parameterName = parameterNames[i];
1075          String JavaDoc parameterType = parameterTypes[i];
1076          String JavaDoc parameterModelAnnotation = getFilteredModelAnnotations(modelAnnotation, parameterName);
1077
1078          if (stringTokenizer.hasMoreTokens())
1079          {
1080            String JavaDoc dataType = stringTokenizer.nextToken();
1081            if (!"-".equals(dataType))
1082            {
1083              StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(parameterModelAnnotation);
1084              buffer.append("dataType=\"");
1085              buffer.append(dataType);
1086              buffer.append("\" ");
1087              parameterModelAnnotation = buffer.toString();
1088            }
1089          }
1090
1091          StringBuffer JavaDoc identifierName = new StringBuffer JavaDoc(eClass.getName());
1092          identifierName.append('.');
1093          identifierName.append(methodName);
1094          identifierName.append('(');
1095          identifierName.append(parameterName);
1096          identifierName.append(')');
1097          handleETypedElement(eParameter, parameterName, parameterType, parameterModelAnnotation, identifierName.toString());
1098          eParameter.getEAnnotations().addAll(extractEAnnotations(parameterModelAnnotation));
1099        }
1100      }
1101    }
1102
1103    // If we aren't doing an operation...
1104
//
1105
if (eTypedElement == null)
1106    {
1107      // We'll create one of these.
1108
//
1109
EStructuralFeature eStructuralFeature = null;
1110
1111      // If any of these attributes appear, this must be a reference.
1112
//
1113
String JavaDoc opposite = getModelAnnotationAttribute(modelAnnotation, "opposite");
1114      String JavaDoc containment = getModelAnnotationAttribute(modelAnnotation, "containment");
1115      String JavaDoc resolveProxies = getModelAnnotationAttribute(modelAnnotation, "resolveProxies");
1116      String JavaDoc mapType = getModelAnnotationAttribute(modelAnnotation, "mapType");
1117      String JavaDoc keyType = getModelAnnotationAttribute(modelAnnotation, "keyType");
1118      String JavaDoc valueType = getModelAnnotationAttribute(modelAnnotation, "valueType");
1119      if (opposite != null || containment != null || resolveProxies != null || mapType != null || (keyType != null && valueType != null))
1120      {
1121        EReference eReference = EcoreFactory.eINSTANCE.createEReference();
1122        eClass.getEStructuralFeatures().add(eTypedElement = eStructuralFeature = eReference);
1123
1124        // Set the EReference attributes.
1125
//
1126
eReference.setContainment("true".equals(containment) || mapType != null && !returnType.endsWith("Entry") || keyType != null
1127          && valueType != null);
1128        eReference.setResolveProxies(!eReference.isContainment() && !"false".equals(resolveProxies));
1129        eReference.setUnsettable("true".equals(getModelAnnotationAttribute(modelAnnotation, "unsettable")));
1130
1131        // Defer the handling of the opposite.
1132
//
1133
if (opposite != null)
1134        {
1135          eReferenceToOppositeNameMap.put(eReference, opposite);
1136        }
1137      }
1138      else
1139      {
1140        // Assume that it's an atttribute for now.
1141
// It will/could become a reference if the type resolves to an EClass.
1142
//
1143
EAttribute eAttribute = EcoreFactory.eINSTANCE.createEAttribute();
1144        eClass.getEStructuralFeatures().add(eTypedElement = eStructuralFeature = eAttribute);
1145
1146        // Set the EAttribute attributes.
1147
//
1148
eAttribute.setUnsettable("true".equals(getModelAnnotationAttribute(modelAnnotation, "unsettable")));
1149        eAttribute.setID("true".equals(getModelAnnotationAttribute(modelAnnotation, "id")));
1150        String JavaDoc defaultValueLiteral = getModelAnnotationAttribute(modelAnnotation, "defaultValue");
1151        if (defaultValueLiteral == null)
1152        {
1153          defaultValueLiteral = getModelAnnotationAttribute(modelAnnotation, "default");
1154        }
1155        eStructuralFeature.setDefaultValueLiteral(defaultValueLiteral);
1156      }
1157
1158      // Handle the type, multiplicity and other ETypedElement attributes.
1159
//
1160
handleETypedElement(eStructuralFeature, featureName, returnType, modelAnnotation,eClass.getName() + "." + methodName);
1161      
1162      // Set the EStructuralFeature attributes.
1163
//
1164
eStructuralFeature.setChangeable(!"false".equals(getModelAnnotationAttribute(modelAnnotation, "changeable")));
1165      eStructuralFeature.setDerived("true".equals(getModelAnnotationAttribute(modelAnnotation, "derived")));
1166      eStructuralFeature.setVolatile("true".equals(getModelAnnotationAttribute(modelAnnotation, "volatile")));
1167      eStructuralFeature.setTransient("true".equals(getModelAnnotationAttribute(modelAnnotation, "transient")));
1168
1169      // Set the visibility annotations for the EstructuralFeature.
1170
//
1171
EcoreUtil.setSuppressedVisibility
1172        (eStructuralFeature, EcoreUtil.GET, "true".equals(getModelAnnotationAttribute(modelAnnotation, "suppressedGetVisibility")));
1173      EcoreUtil.setSuppressedVisibility
1174        (eStructuralFeature, EcoreUtil.SET, "true".equals(getModelAnnotationAttribute(modelAnnotation, "suppressedSetVisibility")));
1175      EcoreUtil.setSuppressedVisibility
1176        (eStructuralFeature, EcoreUtil.IS_SET, "true".equals(getModelAnnotationAttribute(modelAnnotation, "suppressedIsSetVisibility")));
1177      EcoreUtil.setSuppressedVisibility
1178        (eStructuralFeature, EcoreUtil.UNSET, "true".equals(getModelAnnotationAttribute(modelAnnotation, "suppressedUnsetVisibility")));
1179    }
1180
1181    if (eTypedElement != null)
1182    {
1183      // Process the annotations.
1184
//
1185
eTypedElement.getEAnnotations().addAll(extractEAnnotations(modelAnnotation));
1186    }
1187
1188    return eTypedElement;
1189  }
1190
1191  protected void handleETypedElement(ETypedElement eTypedElement, String JavaDoc name, String JavaDoc type, String JavaDoc modelAnnotation, String JavaDoc identifierName)
1192  {
1193    eTypedElement.setName(name);
1194    if ("void".equals(type)) return;
1195    
1196    String JavaDoc mapType = getModelAnnotationAttribute(modelAnnotation, "mapType");
1197    String JavaDoc dataType = getModelAnnotationAttribute(modelAnnotation, "dataType");
1198    String JavaDoc modelType = getModelAnnotationAttribute(modelAnnotation, "type");
1199    String JavaDoc keyType = getModelAnnotationAttribute(modelAnnotation, "keyType");
1200    String JavaDoc valueType = getModelAnnotationAttribute(modelAnnotation, "valueType");
1201    String JavaDoc many = getModelAnnotationAttribute(modelAnnotation, "many");
1202
1203    // For lists, maps, and feature maps, the default is many-valued, which can be overriden by an upper-bound declaration.
1204
//
1205
if (dataType == null || mapType != null)
1206    {
1207      if ("EList".equals(type) || "org.eclipse.emf.common.util.EList".equals(type)|| "List".equals(type) || "java.util.List".equals(type))
1208      {
1209        eTypedElement.setUpperBound(-1);
1210        if (modelType == null && !"false".equals(many))
1211        {
1212          error(CodeGenEcorePlugin.INSTANCE.getString("_UI_TheTypeMustBeSpecifiedFor_message", new Object JavaDoc [] { identifierName }));
1213          modelType = "java.lang.Object";
1214        }
1215      }
1216      else if ("EMap".equals(type) || "org.eclipse.emf.common.util.EMap".equals(type) ||
1217               "Map".equals(type) || "java.util.Map".equals(type) ||
1218               mapType != null || (keyType != null && valueType != null) ||
1219               "FeatureMap".equals(type) || "org.eclipse.emf.common.util.FeatureMap".equals(type))
1220      {
1221        eTypedElement.setUpperBound(-1);
1222      }
1223    }
1224
1225    if (many != null)
1226    {
1227      eTypedElement.setUpperBound("true".equals(many) ? -1 : 1);
1228    }
1229
1230    eTypedElement.setLowerBound("true".equals(getModelAnnotationAttribute(modelAnnotation, "required")) ? 1 : 0);
1231
1232    String JavaDoc lowerBound = getModelAnnotationAttribute(modelAnnotation, "lowerBound");
1233    if (lowerBound == null)
1234    {
1235      lowerBound = getModelAnnotationAttribute(modelAnnotation, "lower");
1236    }
1237    if (lowerBound != null)
1238    {
1239      eTypedElement.setLowerBound(Integer.parseInt(lowerBound));
1240    }
1241    String JavaDoc upperBound = getModelAnnotationAttribute(modelAnnotation, "upperBound");
1242    if (upperBound == null)
1243    {
1244      upperBound = getModelAnnotationAttribute(modelAnnotation, "upper");
1245    }
1246    if (upperBound != null)
1247    {
1248      eTypedElement.setUpperBound(Integer.parseInt(upperBound));
1249    }
1250
1251    // The type can be augmented by specifying the it explicitly in the annotation.
1252
// This mostly makes sense only for many-valued typed elements, where the Java
1253
// type is a list and the item type needs to be specified.
1254
//
1255
if (modelType != null)
1256    {
1257      type = modelType;
1258    }
1259
1260    if (mapType != null)
1261    {
1262      if (keyType != null && valueType != null)
1263      {
1264        type = mapType + "@" + keyType + "/" + valueType;
1265      }
1266      else
1267      {
1268        type = mapType;
1269      }
1270    }
1271    else if (dataType != null)
1272    {
1273      eTypedElementToInstanceTypeNameMap.put(eTypedElement, type);
1274      type = dataType;
1275    }
1276    else if (keyType != null && valueType != null)
1277    {
1278      // Special paired return type.
1279
//
1280
type = keyType + "/" + valueType;
1281    }
1282    eTypedElementToTypeNameMap.put(eTypedElement, type);
1283
1284    eTypedElement.setUnique(!"false".equals(getModelAnnotationAttribute(modelAnnotation, "unique")));
1285    eTypedElement.setOrdered(!"false".equals(getModelAnnotationAttribute(modelAnnotation, "ordered")));
1286  }
1287
1288  protected EStructuralFeature createFeature(EClass eClass, String JavaDoc name, EClassifier eType)
1289  {
1290    if (eType instanceof EClass)
1291    {
1292      EReference eReference = EcoreFactory.eINSTANCE.createEReference();
1293      eReference.setName(name);
1294      eReference.setEType(eType);
1295      eClass.getEStructuralFeatures().add(eReference);
1296      return eReference;
1297    }
1298    else
1299    {
1300      EAttribute eAttribute = EcoreFactory.eINSTANCE.createEAttribute();
1301      eAttribute.setName(name);
1302      eAttribute.setEType(eType);
1303      eClass.getEStructuralFeatures().add(eAttribute);
1304      return eAttribute;
1305    }
1306  }
1307
1308  /**
1309   * Creates EEnumLiteral as appropriate.
1310   */

1311  protected void analyzeField(EEnum eEnum, IDOMField field)
1312  {
1313    String JavaDoc modelAnnotation = getModelAnnotation(field.getComment());
1314    if (modelAnnotation != null)
1315    {
1316      // Allow a mixed case version of the name to be provided.
1317
//
1318
String JavaDoc literalName = getModelAnnotationAttribute(modelAnnotation, "name");
1319      if (literalName == null)
1320      {
1321        literalName = field.getName();
1322      }
1323
1324      // Create one and set the name and value.
1325
//
1326
EEnumLiteral eEnumLiteral = EcoreFactory.eINSTANCE.createEEnumLiteral();
1327      eModelElementToIDOMNodeMap.put(eEnumLiteral, field);
1328      eEnumLiteral.setName(literalName);
1329      eEnumLiteral.getEAnnotations().addAll(extractEAnnotations(modelAnnotation));
1330      EcoreUtil.setDocumentation(eEnumLiteral, getModelDocumentation(field.getComment()));
1331      if (field.getInitializer() != null)
1332      {
1333        try
1334        {
1335          int value = Integer.parseInt(field.getInitializer().trim());
1336          eEnumLiteral.setValue(value);
1337        }
1338        catch (NumberFormatException JavaDoc exception)
1339        {
1340          JavaImporterPlugin.INSTANCE.log(exception);
1341          eEnumLiteral.setValue(eEnum.getELiterals().size());
1342        }
1343      }
1344      else
1345      {
1346        eEnumLiteral.setValue(eEnum.getELiterals().size());
1347      }
1348      eEnum.getELiterals().add(eEnumLiteral);
1349    }
1350  }
1351
1352  /**
1353   * The pattern for extracting the model documentation.
1354   */

1355  protected static Pattern JavaDoc modelDocExpression = Pattern.compile(
1356    "<!--\\s*begin-model-doc\\s*-->[ \\f\\n\\r\\t]*\\*\\s?(.*?)<!--\\s*end-model-doc\\s*-->",
1357    Pattern.MULTILINE | Pattern.DOTALL);
1358
1359  /**
1360   * Returns the model documentation, or null.
1361   */

1362  protected String JavaDoc getModelDocumentation(String JavaDoc comment)
1363  {
1364    if (comment != null)
1365    {
1366      Matcher JavaDoc matcher = modelDocExpression.matcher(comment);
1367      if (matcher.find())
1368      {
1369        return comment.substring(matcher.start(1), matcher.end(1)).replaceAll("[\\n\\r]*\\s*\\*[\\s]?", "\n").replaceAll("\\s*$", "");
1370      }
1371    }
1372
1373    return null;
1374  }
1375
1376  /**
1377   * The pattern for extracting the @model annotations.
1378   */

1379  protected static Pattern JavaDoc modelAnnotationExpression = Pattern.compile(
1380    "@[ \\f\\n\\r\\t*]*model[ \\f\\n\\r\\t*]*((\\w*\\s*=\\s*(['\"])(?>\\\\.|.)*?\\3[ \\f\\n\\r\\t*]*)*)",
1381    Pattern.MULTILINE);
1382
1383  /**
1384   * Returns the @model annotation contents, or null.
1385   */

1386  protected String JavaDoc getModelAnnotation(String JavaDoc comment)
1387  {
1388    if (comment != null)
1389    {
1390      Matcher JavaDoc matcher = modelAnnotationExpression.matcher(comment);
1391      if (matcher.find())
1392      {
1393        return comment.substring(matcher.start(1), matcher.end(1));
1394      }
1395    }
1396
1397    return null;
1398  }
1399
1400  /**
1401   * The pattern for extracting the @extends annotations.
1402   */

1403  protected static Pattern JavaDoc extendsAnnotationExpression = Pattern.compile("@\\s*extends\\s*(([.\\w]*\\s*,*\\s*)+)", Pattern.MULTILINE);
1404
1405  /**
1406   * The pattern for extracting the @implements annotations.
1407   */

1408  protected static Pattern JavaDoc implementsAnnotationExpression = Pattern.compile("@\\s*implements\\s*(([.\\w]*\\s*,*\\s*)+)", Pattern.MULTILINE);
1409
1410  /**
1411   * Returns the @extends/@implements annotation contents, or null.
1412   */

1413  protected String JavaDoc getExtendsAnnotation(String JavaDoc comment)
1414  {
1415    if (comment != null)
1416    {
1417      StringBuffer JavaDoc result = new StringBuffer JavaDoc();
1418      Matcher JavaDoc extendsMatcher = extendsAnnotationExpression.matcher(comment);
1419      while (extendsMatcher.find())
1420      {
1421        result.append(comment.substring(extendsMatcher.start(1), extendsMatcher.end(1)));
1422        result.append(' ');
1423      }
1424
1425      Matcher JavaDoc implementsMatcher = implementsAnnotationExpression.matcher(comment);
1426      while (implementsMatcher.find())
1427      {
1428        result.append(comment.substring(implementsMatcher.start(1), implementsMatcher.end(1)));
1429        result.append(' ');
1430      }
1431
1432      return result.length() == 0 ? null : result.toString();
1433    }
1434
1435    return null;
1436  }
1437
1438  /**
1439   * Returns the unquoted value of attribute-name="value" or of attribute-name='value', or null.
1440   */

1441  protected String JavaDoc getModelAnnotationAttribute(String JavaDoc modelAnnotation, String JavaDoc attributeName)
1442  {
1443    Pattern JavaDoc modelAnnotationAttributeExpressionDoubleQuote = Pattern.compile(
1444      "\\b" + attributeName + "\\s*=\\s*([\"'])((?>\\\\.|.)*?)\\1",
1445      Pattern.MULTILINE);
1446    Matcher JavaDoc matcher = modelAnnotationAttributeExpressionDoubleQuote.matcher(modelAnnotation);
1447    if (matcher.find())
1448    {
1449      return modelAnnotation.substring(matcher.start(2), matcher.end(2));
1450    }
1451    else
1452    {
1453      return null;
1454    }
1455  }
1456
1457  /**
1458   * Returns the space separated concatenation of the unquoted value of each attribute-name="value" or attribute-name='value' repeat, or null.
1459   */

1460  protected String JavaDoc getModelAnnotationAttributes(String JavaDoc modelAnnotation, String JavaDoc attributeName)
1461  {
1462    StringBuffer JavaDoc result = null;
1463    Pattern JavaDoc modelAnnotationAttributeExpressionDoubleQuote = Pattern.compile(
1464      "\\b" + attributeName + "\\s*=\\s*([\"'])((?>\\\\.|.)*?)\\1",
1465      Pattern.MULTILINE);
1466    for (Matcher JavaDoc matcher = modelAnnotationAttributeExpressionDoubleQuote.matcher(modelAnnotation); matcher.find();)
1467    {
1468      if (result == null)
1469      {
1470        result = new StringBuffer JavaDoc();
1471      }
1472      else
1473      {
1474        result.append(' ');
1475      }
1476      result.append(modelAnnotation.subSequence(matcher.start(2), matcher.end(2)));
1477    }
1478
1479    return result == null ? null : result.toString();
1480  }
1481
1482  protected static Pattern JavaDoc eAnnotationExpression = Pattern.compile("\\G\\s*((?>\\\\.|\\S)+)((?:\\s+(?>\\\\.|\\S)+\\s*+=\\s*(['\"])((?>\\\\.|.)*?)\\3)*)");
1483
1484  protected static Pattern JavaDoc eAnnotationDetailExpression = Pattern.compile("\\s+((?>\\\\.|\\S)+)\\s*+=\\s*((['\"])((?>\\\\.|.)*?)\\3)");
1485
1486  protected List JavaDoc extractEAnnotations(String JavaDoc modelAnnotation)
1487  {
1488    List JavaDoc result = Collections.EMPTY_LIST;
1489    String JavaDoc annotations = getModelAnnotationAttributes(modelAnnotation, "annotation");
1490    if (annotations != null)
1491    {
1492      for (Matcher JavaDoc matcher = eAnnotationExpression.matcher(annotations); matcher.find();)
1493      {
1494        if (result == Collections.EMPTY_LIST)
1495        {
1496          result = new ArrayList JavaDoc();
1497        }
1498        EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
1499        result.add(eAnnotation);
1500        eAnnotation.setSource(parseString(matcher.group(1)));
1501        EMap details = eAnnotation.getDetails();
1502        for (Matcher JavaDoc detailMatcher = eAnnotationDetailExpression.matcher(matcher.group(2)); detailMatcher.find();)
1503        {
1504          details.put(parseString(detailMatcher.group(1)), parseString(detailMatcher.group(4)));
1505        }
1506      }
1507    }
1508
1509    String JavaDoc extendedMetaDataAnnotations = getModelAnnotationAttributes(modelAnnotation, "extendedMetaData");
1510    if (extendedMetaDataAnnotations != null)
1511    {
1512      if (result == Collections.EMPTY_LIST)
1513      {
1514        result = new ArrayList JavaDoc();
1515      }
1516      EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
1517      result.add(eAnnotation);
1518      eAnnotation.setSource(ExtendedMetaData.ANNOTATION_URI);
1519      EMap details = eAnnotation.getDetails();
1520      for (Matcher JavaDoc detailMatcher = eAnnotationDetailExpression.matcher(" " + extendedMetaDataAnnotations); detailMatcher.find();)
1521      {
1522        details.put(parseString(detailMatcher.group(1)), parseString(detailMatcher.group(4)));
1523      }
1524    }
1525
1526    return result;
1527  }
1528
1529  private static String JavaDoc parseString(String JavaDoc stringLiteralBody)
1530  {
1531    return CodeGenUtil.parseString(stringLiteralBody);
1532  }
1533
1534  /**
1535   * Returns the filtered matches xyzAttribute-name="value" or of xyxAttribute-name='value', or null.
1536   */

1537  protected String JavaDoc getFilteredModelAnnotations(String JavaDoc modelAnnotation, String JavaDoc filter)
1538  {
1539    StringBuffer JavaDoc result = new StringBuffer JavaDoc();
1540    Pattern JavaDoc modelAnnotationAttributeExpressionDoubleQuote = Pattern.compile("\\b" + filter
1541      + "([A-Z]\\w*\\s*=\\s*([\"'])((?>\\\\.|.)*?)\\2)", Pattern.MULTILINE);
1542    int start = 0;
1543    int end = modelAnnotation.length();
1544    Matcher JavaDoc matcher;
1545    while ((matcher = modelAnnotationAttributeExpressionDoubleQuote.matcher(modelAnnotation.subSequence(start, end))).find())
1546    {
1547      result.append(modelAnnotation.substring(start + matcher.start(1), start + matcher.start(1) + 1).toLowerCase());
1548      result.append(modelAnnotation.substring(start + matcher.start(1) + 1, start + matcher.end(1)));
1549      result.append(' ');
1550      start += matcher.end(0);
1551    }
1552    return result.toString();
1553  }
1554
1555  protected EClassifier resolve(EModelElement eModelElement, String JavaDoc typeName)
1556  {
1557    return resolve(eModelElement, typeName, true);
1558  }
1559
1560  protected EClassifier resolve(EModelElement eModelElement, String JavaDoc typeName, boolean recordDemandCreatedEDataType)
1561  {
1562    EPackage ePackage = (EPackage)EcoreUtil.getRootContainer(eModelElement);
1563
1564    // We want to resolve to this.
1565
//
1566
EClassifier eClassifier = null;
1567
1568    // Is this is a map entry name consisting of /-separated pair of type names.
1569
// It may start with the name of the map entry followed by @.
1570
//
1571
int indexOfSlash = typeName.indexOf("/");
1572    if (indexOfSlash != -1)
1573    {
1574      String JavaDoc mapType = null;
1575      String JavaDoc keyType = typeName.substring(0, indexOfSlash);
1576      int indexOfAt = keyType.indexOf("@");
1577      if (indexOfAt != -1)
1578      {
1579        mapType = keyType.substring(0, indexOfAt);
1580        keyType = keyType.substring(indexOfAt + 1);
1581      }
1582      EClassifier keyEClassifier = resolve(eModelElement, keyType);
1583
1584      String JavaDoc valueType = typeName.substring(indexOfSlash + 1);
1585      EClassifier valueEClassifier = resolve(eModelElement, valueType);
1586
1587      if (mapType == null)
1588      {
1589        eClassifier = resolveMapEntry(ePackage, keyEClassifier, valueEClassifier);
1590        if (eClassifier == null)
1591        {
1592          eClassifier = resolveMapEntry(EcorePackage.eINSTANCE, keyEClassifier, valueEClassifier);
1593        }
1594      }
1595      else
1596      {
1597        eClassifier = resolve(eModelElement, mapType, false);
1598      }
1599
1600      if (eClassifier == null)
1601      {
1602        EClass eClass = EcoreFactory.eINSTANCE.createEClass();
1603        eClass.setInstanceClassName("java.util.Map$Entry");
1604
1605        String JavaDoc baseName = mapType != null ? mapType : keyEClassifier.getName() + "To" + valueEClassifier.getName() + "MapEntry";
1606        String JavaDoc name = baseName;
1607        for (int j = 1; ePackage.getEClassifier(name) != null; ++j)
1608        {
1609          name = baseName + "_" + j;
1610        }
1611        eClass.setName(name);
1612        createFeature(eClass, "key", keyEClassifier);
1613        createFeature(eClass, "value", valueEClassifier);
1614
1615        ePackage.getEClassifiers().add(eClass);
1616
1617        eClassifier = eClass;
1618      }
1619
1620      return eClassifier;
1621    }
1622
1623    // Check if the name is qualified
1624
//
1625
String JavaDoc baseName = typeName;
1626    String JavaDoc packageName = "";
1627    int index = typeName.lastIndexOf(".");
1628    if (index == -1)
1629    {
1630      // Look through the imports of the containing compilation unit.
1631
//
1632
for (IDOMNode node = (IDOMNode)eModelElementToIDOMNodeMap.get(eModelElement); node != null; node = node.getParent())
1633      {
1634        if (node.getNodeType() == IDOMNode.COMPILATION_UNIT)
1635        {
1636          // Find an explicit import or the first wildcard import.
1637
//
1638
boolean firstWildcard = true;
1639          for (IDOMNode child = ((IDOMCompilationUnit)node).getFirstChild(); child != null; child = child.getNextNode())
1640          {
1641            if (child.getNodeType() == IDOMNode.IMPORT)
1642            {
1643              IDOMImport jImport = (IDOMImport)child;
1644              String JavaDoc importName = jImport.getName();
1645              if (importName.endsWith("." + baseName))
1646              {
1647                int importIndex = importName.lastIndexOf(".");
1648                packageName = importName.substring(0, importIndex);
1649                typeName = packageName + "." + baseName;
1650                break;
1651              }
1652              else if (firstWildcard && importName.endsWith(".*"))
1653              {
1654                int importIndex = importName.lastIndexOf(".");
1655                packageName = importName.substring(0, importIndex);
1656                typeName = packageName + "." + baseName;
1657                firstWildcard = false;
1658              }
1659            }
1660          }
1661
1662          // Find the modeled package for the import and look up the name there.
1663
//
1664
EPackage otherEPackage = (EPackage)packageNameToEPackageMap.get(packageName);
1665          if (otherEPackage == null)
1666          {
1667            otherEPackage = (EPackage)externalPackageNameToEPackageMap.get(packageName);
1668          }
1669          if (otherEPackage != null)
1670          {
1671            eClassifier = otherEPackage.getEClassifier(baseName);
1672          }
1673          break;
1674        }
1675      }
1676      // If we can't find it, try the simple name in the package...
1677
//
1678
if (eClassifier == null && "".equals(packageName))
1679      {
1680        eClassifier = ePackage.getEClassifier(typeName);
1681      }
1682    }
1683    else
1684    {
1685      // Find the modeled package for the name and look up the name there.
1686
//
1687
packageName = typeName.substring(0, index);
1688      baseName = typeName.substring(index + 1);
1689      EPackage otherEPackage = (EPackage)packageNameToEPackageMap.get(packageName);
1690      if (otherEPackage == null)
1691      {
1692        otherEPackage = (EPackage)externalPackageNameToEPackageMap.get(packageName);
1693        if (otherEPackage == null)
1694        {
1695          if ("org.eclipse.emf.ecore".equals(packageName))
1696          {
1697            otherEPackage = EcorePackage.eINSTANCE;
1698          }
1699          else if ("org.eclipse.emf.ecore.xml.type".equals(packageName))
1700          {
1701            otherEPackage = XMLTypePackage.eINSTANCE;
1702          }
1703          else if ("org.eclipse.emf.ecore.xml.namespace".equals(packageName))
1704          {
1705            otherEPackage = XMLNamespacePackage.eINSTANCE;
1706          }
1707        }
1708      }
1709      if (otherEPackage != null)
1710      {
1711        eClassifier = otherEPackage.getEClassifier(baseName);
1712      }
1713    }
1714
1715    // If we still don't have one, we'll have to settle for an EDataType or EClass with an instance class name.
1716
//
1717
if (eClassifier == null)
1718    {
1719      // See if we already have the EDataType.
1720
//
1721
for (Iterator JavaDoc j = ePackage.getEClassifiers().iterator(); j.hasNext();)
1722      {
1723        EClassifier ePackageClassifier = (EClassifier)j.next();
1724        String JavaDoc name = ePackageClassifier.getInstanceClassName();
1725        if (name != null && name.replace('$', '.').equals(typeName.replace('$', '.')))
1726        {
1727          eClassifier = ePackageClassifier;
1728          break;
1729        }
1730      }
1731    }
1732
1733    if (EcorePackage.eINSTANCE.getEObject().getInstanceClassName().equals(typeName))
1734    {
1735      eClassifier = EcorePackage.eINSTANCE.getEObject();
1736    }
1737
1738    // Just to be helpful, we'll recognize a type of org.eclipse.emf.ecore.util.FeatureMap and convert it to EFeatureMapEntry.
1739
// This way a dataType need not be specified. But, we won't do this if recordDemandCreateEDataType is false, so we don't
1740
// change the instanceClass of a new EDataType that's implicitly being defined for FeatureMap.
1741
//
1742
if (eClassifier == null && recordDemandCreatedEDataType
1743      && EcorePackage.eINSTANCE.getEFeatureMap().getInstanceClassName().equals(typeName))
1744    {
1745      eClassifier = EcorePackage.eINSTANCE.getEFeatureMapEntry();
1746    }
1747
1748    // If we don't have one yet, maybe it's one of the special types...
1749
//
1750
if (eClassifier == null
1751      && (packageName.length() == 0 || packageName.equals("java.lang") || packageName.equals("java.math") || packageName.equals("java.util")))
1752    {
1753      for (Iterator JavaDoc j = EcorePackage.eINSTANCE.getEClassifiers().iterator(); j.hasNext();)
1754      {
1755        EClassifier ecoreEClassifier = (EClassifier)j.next();
1756        if (ecoreEClassifier instanceof EDataType)
1757        {
1758          String JavaDoc instanceClassName = ecoreEClassifier.getInstanceClassName();
1759          if (instanceClassName.equals(typeName) || instanceClassName.equals("java.lang." + typeName))
1760          {
1761            eClassifier = ecoreEClassifier;
1762            break;
1763          }
1764        }
1765      }
1766    }
1767
1768    // If we still don't have one, we'll have to settle for an EDataType not an EClass,
1769
// so create a new EDataType with a nice unique name.
1770
//
1771
if (eClassifier == null && !(eModelElement instanceof EReference))
1772    {
1773      EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType();
1774
1775      // If the name isn't qualified, it might be a primitive or from java.lang. Otherwise, assume it's in the current
1776
// package and use the nsPrefix for the qualified package name.
1777
//
1778
boolean primitive = false;
1779      if (packageName.length() == 0)
1780      {
1781        // For arrays, consider the element type.
1782
//
1783
int i = typeName.indexOf('[');
1784        String JavaDoc elementTypeName = i == -1 ? typeName : typeName.substring(0, i);
1785
1786        if (CodeGenUtil.isJavaPrimitiveType(elementTypeName))
1787        {
1788          primitive = true;
1789        }
1790        else if (CodeGenUtil.isJavaLangType(elementTypeName))
1791        {
1792          packageName = "java.lang";
1793          typeName = packageName + "." + typeName;
1794        }
1795        else
1796        {
1797          packageName = ePackage.getNsPrefix();
1798          typeName = packageName + '.' + typeName;
1799        }
1800      }
1801      eDataType.setInstanceClassName(typeName);
1802
1803      // Even primitives should be represented by a data type with a conventional (i.e. capitalized) name.
1804
//
1805
String JavaDoc name = baseName;
1806      if (primitive && name.length() > 0)
1807      {
1808        name = name.substring(0, 1).toUpperCase() + name.substring(1);
1809      }
1810
1811      // Make array names legal.
1812
//
1813
while (name.endsWith("[]"))
1814      {
1815        name = name.substring(0, name.length() - 2) + "Array";
1816      }
1817
1818      // Avoid classifier name collisions.
1819
//
1820
for (int j = 1; ePackage.getEClassifier(name) != null; ++j)
1821      {
1822        name = baseName + "_" + j;
1823      }
1824      eDataType.setName(name);
1825
1826      if (recordDemandCreatedEDataType)
1827      {
1828        demandCreatedEDataTypes.add(eDataType);
1829        ePackage.getEClassifiers().add(eDataType);
1830      }
1831      eClassifier = eDataType;
1832    }
1833
1834    return eClassifier;
1835  }
1836
1837  protected EClass resolveMapEntry(EPackage ePackage, EClassifier keyEClassifier, EClassifier valueEClassifier)
1838  {
1839    for (Iterator JavaDoc j = ePackage.getEClassifiers().iterator(); j.hasNext();)
1840    {
1841      EClassifier ePackageClassifier = (EClassifier)j.next();
1842      if (ePackageClassifier instanceof EClass
1843        && ("java.util.Map.Entry".equals(ePackageClassifier.getInstanceClassName()) || "java.util.Map$Entry".equals(ePackageClassifier.getInstanceClassName())))
1844      {
1845        EClass mapEntryInterface = (EClass)ePackageClassifier;
1846        EStructuralFeature keyFeature = mapEntryInterface.getEStructuralFeature("key");
1847        if (keyFeature != null && resolveType(keyFeature) == keyEClassifier && !keyFeature.isMany())
1848        {
1849          EStructuralFeature valueFeature = mapEntryInterface.getEStructuralFeature("value");
1850          if (valueFeature != null && resolveType(valueFeature) == valueEClassifier && !valueFeature.isMany())
1851          {
1852            return mapEntryInterface;
1853          }
1854        }
1855      }
1856    }
1857
1858    return null;
1859  }
1860
1861  protected EClassifier resolveType(ETypedElement eTypedElement)
1862  {
1863    EClassifier type = eTypedElement.getEType();
1864    if (type == null)
1865    {
1866      String JavaDoc typeName = (String JavaDoc)eTypedElementToTypeNameMap.get(eTypedElement);
1867      if (typeName != null)
1868      {
1869        type = resolve(eTypedElement, typeName);
1870      }
1871    }
1872    return type;
1873  }
1874
1875  protected void sort(EList eList, final Map JavaDoc nameToIDMap)
1876  {
1877    Collection JavaDoc ordered = new TreeSet JavaDoc(new Comparator JavaDoc()
1878      {
1879        public boolean equals(Object JavaDoc object)
1880        {
1881          return object == this;
1882        }
1883
1884        public int compare(Object JavaDoc firstObject, Object JavaDoc secondObject)
1885        {
1886          int firstValue = getOrderingValue((ENamedElement)firstObject, nameToIDMap);
1887          int secondValue = getOrderingValue((ENamedElement)secondObject, nameToIDMap);
1888          return firstValue - secondValue;
1889        }
1890      });
1891    ordered.addAll(eList);
1892    int index = 0;
1893    for (Iterator JavaDoc i = ordered.iterator(); i.hasNext(); ++index)
1894    {
1895      eList.move(index, i.next());
1896    }
1897  }
1898
1899  protected int getOrderingValue(ENamedElement eNamedElement, Map JavaDoc nameToIDMap)
1900  {
1901    Integer JavaDoc result = (Integer JavaDoc)nameToIDMap.get(eNamedElement);
1902    if (result == null)
1903    {
1904      if (eNamedElement instanceof EClassifier)
1905      {
1906        String JavaDoc prefix = (String JavaDoc)ePackageToPrefixMap.get(eNamedElement.eContainer());
1907        String JavaDoc name = eNamedElement.getName();
1908        String JavaDoc id = CodeGenUtil.format(name, '_', prefix, true).toUpperCase();
1909        result = (Integer JavaDoc)nameToIDMap.get(id);
1910      }
1911      else
1912      {
1913        String JavaDoc prefix = (String JavaDoc)ePackageToPrefixMap.get(eNamedElement.eContainer().eContainer());
1914        String JavaDoc eClassName = ((ENamedElement)eNamedElement.eContainer()).getName();
1915        String JavaDoc eFeatureName = eNamedElement.getName();
1916        String JavaDoc id = CodeGenUtil.format(eClassName, '_', prefix, true).toUpperCase() + "__"
1917          + CodeGenUtil.format(eFeatureName, '_', prefix, true).toUpperCase();
1918        result = (Integer JavaDoc)nameToIDMap.get(id);
1919      }
1920      if (result != null)
1921      {
1922        nameToIDMap.put(eNamedElement, result);
1923      }
1924    }
1925
1926    if (result != null)
1927    {
1928      return result.intValue();
1929    }
1930
1931    return Integer.MAX_VALUE;
1932  }
1933
1934  /**
1935   * Returns the status.
1936   * @return the status.
1937   */

1938  public IStatus getStatus()
1939  {
1940    return status;
1941  }
1942
1943  /**
1944   * Returns the generator model.
1945   * @return the generator model.
1946   */

1947  public GenModel getGenModel()
1948  {
1949    return genModel;
1950  }
1951
1952  /**
1953   * Produces another IStatus in the MultiStatus.
1954   * @param message a description of the error.
1955   */

1956  protected void error(String JavaDoc message)
1957  {
1958    System.err.println("-->Error: " + message);
1959    status.add(new Status(IStatus.ERROR, JavaImporterPlugin.getPlugin().getBundle().getSymbolicName(), 0, message, null));
1960  }
1961
1962  /**
1963   * Produces another IStatus in the MultiStatus, with warning severity.
1964   * @param message a description of the error.
1965   */

1966  protected void warning(String JavaDoc message)
1967  {
1968    System.err.println("-->Warning: " + message);
1969    status.add(new Status(IStatus.WARNING, JavaImporterPlugin.getPlugin().getBundle().getSymbolicName(), 0, message, null));
1970  }
1971}
1972
Popular Tags