KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > emf > codegen > util > CodeGenUtil


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  * CodeGenUtil.java,v 1.1 2005/05/16 18:39:08 marcelop Exp
16  */

17 package org.eclipse.emf.codegen.util;
18
19 import java.io.IOException JavaDoc;
20 import java.io.PrintStream JavaDoc;
21 import java.net.URL JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Collections JavaDoc;
25 import java.util.HashSet JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.ListIterator JavaDoc;
29 import java.util.Set JavaDoc;
30
31 import org.osgi.framework.Bundle;
32 import org.osgi.framework.BundleException;
33 import org.osgi.framework.Constants;
34
35 import org.eclipse.core.resources.IContainer;
36 import org.eclipse.core.resources.IFolder;
37 import org.eclipse.core.resources.IProject;
38 import org.eclipse.core.resources.IProjectDescription;
39 import org.eclipse.core.resources.IResource;
40 import org.eclipse.core.resources.IWorkspace;
41 import org.eclipse.core.resources.ResourcesPlugin;
42 import org.eclipse.core.runtime.CoreException;
43 import org.eclipse.core.runtime.IPath;
44 import org.eclipse.core.runtime.IProgressMonitor;
45 import org.eclipse.core.runtime.NullProgressMonitor;
46 import org.eclipse.core.runtime.Path;
47 import org.eclipse.core.runtime.Platform;
48 import org.eclipse.core.runtime.SubProgressMonitor;
49 import org.eclipse.jdt.core.IJavaProject;
50 import org.eclipse.jdt.core.JavaConventions;
51 import org.eclipse.jdt.core.JavaCore;
52 import org.eclipse.jdt.core.JavaModelException;
53 import org.eclipse.osgi.util.ManifestElement;
54
55 import org.eclipse.emf.codegen.CodeGenPlugin;
56 import org.eclipse.emf.codegen.jet.JETException;
57
58 /**
59  * This class contains convenient static methods for EMF code generation.
60  * <p>
61  * This class, like much of the code in this plug-in, is currently undergoing change and should not be considered API.
62  */

63 public class CodeGenUtil
64 {
65   private static Set JavaDoc javaReservedWords;
66
67   /**
68    * Returns the set of all Java's keywords and textual literals, as of Java 1.4.
69    */

70   public static Set JavaDoc getJavaReservedWords()
71   {
72     if (javaReservedWords == null)
73     {
74       Set JavaDoc result = new HashSet JavaDoc(100);
75       result.add("abstract");
76       result.add("assert");
77       result.add("boolean");
78       result.add("break");
79       result.add("byte");
80       result.add("case");
81       result.add("catch");
82       result.add("char");
83       result.add("class");
84       result.add("const");
85       result.add("continue");
86       result.add("default");
87       result.add("do");
88       result.add("double");
89       result.add("else");
90       result.add("extends");
91       result.add("false");
92       result.add("final");
93       result.add("finally");
94       result.add("float");
95       result.add("for");
96       result.add("goto");
97       result.add("if");
98       result.add("implements");
99       result.add("import");
100       result.add("instanceof");
101       result.add("int");
102       result.add("interface");
103       result.add("long");
104       result.add("native");
105       result.add("new");
106       result.add("null");
107       result.add("package");
108       result.add("private");
109       result.add("protected");
110       result.add("public");
111       result.add("return");
112       result.add("short");
113       result.add("static");
114       result.add("strictfp");
115       result.add("super");
116       result.add("switch");
117       result.add("synchronized");
118       result.add("this");
119       result.add("throw");
120       result.add("throws");
121       result.add("transient");
122       result.add("true");
123       result.add("try");
124       result.add("void");
125       result.add("volatile");
126       result.add("while");
127       javaReservedWords = Collections.unmodifiableSet(result);
128     }
129     return javaReservedWords;
130   }
131
132   private static Set JavaDoc javaDefaultTypes;
133
134   /**
135    * Returns the short names of the primitives and types in java.lang (i.e. those
136    * that don't need qualification).
137    */

138   public static Set JavaDoc getJavaDefaultTypes()
139   {
140     if (javaDefaultTypes == null)
141     {
142       Set JavaDoc result = new HashSet JavaDoc();
143       result = new HashSet JavaDoc(100);
144       result.add("AbstractMethodError");
145       result.add("ArithmeticException");
146       result.add("ArrayIndexOutOfBoundsException");
147       result.add("ArrayStoreException");
148       result.add("Boolean");
149       result.add("Byte");
150       result.add("Character");
151       result.add("Class");
152       result.add("ClassCastException");
153       result.add("ClassCircularityError");
154       result.add("ClassFormatError");
155       result.add("ClassLoader");
156       result.add("ClassNotFoundException");
157       result.add("CloneNotSupportedException");
158       result.add("Cloneable");
159       result.add("Comparable");
160       result.add("Compiler");
161       result.add("Double");
162       result.add("Error");
163       result.add("Exception");
164       result.add("ExceptionInInitializerError");
165       result.add("Float");
166       result.add("FloatingDecimal");
167       result.add("IllegalAccessError");
168       result.add("IllegalAccessException");
169       result.add("IllegalArgumentException");
170       result.add("IllegalMonitorStateException");
171       result.add("IllegalStateException");
172       result.add("IllegalThreadStateException");
173       result.add("IncompatibleClassChangeError");
174       result.add("IndexOutOfBoundsException");
175       result.add("InheritableThreadLocal");
176       result.add("InstantiationError");
177       result.add("InstantiationException");
178       result.add("Integer");
179       result.add("InternalError");
180       result.add("InterruptedException");
181       result.add("LinkageError");
182       result.add("Long");
183       result.add("Math");
184       result.add("NegativeArraySizeException");
185       result.add("NoClassDefFoundError");
186       result.add("NoSuchFieldError");
187       result.add("NoSuchFieldException");
188       result.add("NoSuchMethodError");
189       result.add("NoSuchMethodException");
190       result.add("NullPointerException");
191       result.add("Number");
192       result.add("NumberFormatException");
193       result.add("Object");
194       result.add("OutOfMemoryError");
195       result.add("Package");
196       result.add("Process");
197       result.add("Runnable");
198       result.add("Runtime");
199       result.add("RuntimeException");
200       result.add("RuntimePermission");
201       result.add("SecurityException");
202       result.add("SecurityManager");
203       result.add("Short");
204       result.add("StackOverflowError");
205       result.add("String");
206       result.add("StringBuffer");
207       result.add("StringIndexOutOfBoundsException");
208       result.add("System");
209       result.add("Thread");
210       result.add("ThreadDeath");
211       result.add("ThreadGroup");
212       result.add("ThreadLocal");
213       result.add("Throwable");
214       result.add("UnknownError");
215       result.add("UnsatisfiedLinkError");
216       result.add("UnsupportedClassVersionError");
217       result.add("UnsupportedOperationException");
218       result.add("VerifyError");
219       result.add("VirtualMachineError");
220       result.add("Void");
221       result.add("boolean");
222       result.add("byte");
223       result.add("char");
224       result.add("double");
225       result.add("float");
226       result.add("int");
227       result.add("long");
228       result.add("short");
229       javaDefaultTypes = Collections.unmodifiableSet(result);
230     }
231     return javaDefaultTypes;
232   }
233
234   /**
235    * Tests whether a given string is a Java reserved word.
236    */

237   public static boolean isJavaReservedWord(String JavaDoc s)
238   {
239     return getJavaReservedWords().contains(s);
240   }
241
242   /**
243    * Tests whether the given string is the name of a primitive or java.lang type.
244    */

245   public static boolean isJavaDefaultType(String JavaDoc s)
246   {
247     return getJavaDefaultTypes().contains(s);
248   }
249
250   /**
251    * Tests whether the given string is the name of a java.lang type.
252    */

253   public static boolean isJavaLangType(String JavaDoc s)
254   {
255     return getJavaDefaultTypes().contains(s) && Character.isUpperCase(s.charAt(0));
256   }
257
258   /**
259    * Tests whether the given string is the name of a primitive type.
260    */

261   public static boolean isJavaPrimitiveType(String JavaDoc s)
262   {
263     return getJavaDefaultTypes().contains(s) && Character.isLowerCase(s.charAt(0));
264   }
265   
266   // Interprets escaped characters within the string according to Java
267
// literal rules, with two exceptions: an unescaped " does not terminate
268
// the string, and a \ not followed by b, t, n, f, r, ", ', u, or an octal
269
// digit is taken literally, not as an error
270
public static String JavaDoc parseString(String JavaDoc s)
271   {
272     if (s == null) return null;
273
274     int len = s.length();
275     StringBuffer JavaDoc result = new StringBuffer JavaDoc(len);
276     for (int i = 0; i < len; i++)
277     {
278       char c = s.charAt(i);
279       if (c == '\\' && len > i + 1)
280       {
281         if ("btnfr\"\'\\".indexOf(s.charAt(i + 1)) != -1)
282         {
283           c = parseChar(s.substring(i, i + 2));
284           i++;
285         }
286         else if (s.charAt(i + 1) == 'u' && len > i + 5)
287         {
288           c = parseChar(s.substring(i, i + 6));
289           i += 5;
290         }
291         else
292         {
293           int j; // will point at the character after 0 to 3 octal digits
294
for (j = i + 1; j < len && j - i < 4; j++)
295           {
296             char digit = s.charAt(j);
297             if (digit < '0' || digit > '7') break;
298           }
299           c = parseChar(s.substring(i, j));
300           i = j - 1;
301         }
302       }
303       result.append(c);
304     }
305     return result.toString();
306   }
307   
308   // Interprets escaped characters according to Java literal rules, with one
309
// exception: a single \ is taken literally, not as an error.
310
public static char parseChar(String JavaDoc c)
311   {
312     if (c == null) throw new IllegalArgumentException JavaDoc("null");
313
314     if ("\\b".equals(c)) return '\b';
315     if ("\\t".equals(c)) return '\t';
316     if ("\\n".equals(c)) return '\n';
317     if ("\\f".equals(c)) return '\f';
318     if ("\\r".equals(c)) return '\r';
319     if ("\\\"".equals(c)) return '\"';
320     if ("\\\'".equals(c)) return '\'';
321     if ("\\\\".equals(c)) return '\\';
322
323     if (c.startsWith("\\u") && c.length() == 6)
324     {
325       int i = Integer.parseInt(c.substring(2), 16);
326       if (i >= Character.MIN_VALUE && i <= Character.MAX_VALUE)
327       {
328         return (char)i;
329       }
330     }
331     else if (c.length() >= 2 && c.length() <= 4 && c.charAt(0) == '\\')
332     {
333       int i = Integer.parseInt(c.substring(1), 8);
334       if (i >= Character.MIN_VALUE && i <= Character.MAX_VALUE)
335       {
336         return (char)i;
337       }
338     }
339
340     if (c.length() != 1) throw new IllegalArgumentException JavaDoc(c);
341     return c.charAt(0);
342   }
343   
344   public static String JavaDoc validJavaIdentifier(String JavaDoc name)
345   {
346     if (name == null || name.length() == 0)
347     {
348       return name;
349     }
350     else if (JavaConventions.validateIdentifier(name).isOK())
351     {
352       return name;
353     }
354
355     StringBuffer JavaDoc result = new StringBuffer JavaDoc();
356     if (Character.isJavaIdentifierStart(name.charAt(0)))
357     {
358       result.append(name.charAt(0));
359     }
360     else
361     {
362       result.append('_');
363       if (Character.isJavaIdentifierPart(name.charAt(0)))
364       {
365         result.append(name.charAt(0));
366       }
367     }
368     for (int i = 1; i < name.length(); ++ i)
369     {
370       if (Character.isJavaIdentifierPart(name.charAt(i)))
371       {
372         result.append(name.charAt(i));
373       }
374     }
375
376     return result.length() == 0 ? "_" : result.toString();
377   }
378   
379   public static String JavaDoc capName(String JavaDoc name)
380   {
381     if (name.length() == 0)
382       return name;
383     else
384       return name.substring(0,1).toUpperCase() + name.substring(1);
385   }
386
387   public static String JavaDoc uncapName(String JavaDoc name)
388   {
389     if (name.length() == 0)
390       return name;
391     else
392       return name.substring(0,1).toLowerCase() + name.substring(1);
393   }
394
395   public static String JavaDoc uncapPrefixedName(String JavaDoc name, boolean forceDifferent)
396   {
397     // lower all except the last upper case character if there are
398
// more than one upper case characters in the beginning.
399
// e.g. XSDElementContent -> xsdElementContent
400
// However if the whole string is uppercase, the whole string
401
// is turned into lower case.
402
// e.g. CPU -> cpu
403
if (name.length() == 0)
404     {
405       return name;
406     }
407     else
408     {
409       String JavaDoc lowerName = name.toLowerCase();
410       int i;
411       for (i = 0; i < name.length(); i++)
412       {
413         if (name.charAt(i) == lowerName.charAt(i))
414         {
415           break;
416         }
417       }
418       if (i > 1 && i < name.length())
419       {
420         --i;
421       }
422       String JavaDoc prefix = name.substring(0, i);
423       String JavaDoc lowerCasePrefix = prefix.toLowerCase();
424       if (forceDifferent && lowerCasePrefix.equals(prefix))
425       {
426         lowerCasePrefix = "_" + lowerCasePrefix;
427       }
428       return lowerCasePrefix + name.substring(i);
429     }
430   }
431
432   public static String JavaDoc safeName(String JavaDoc name)
433   {
434     if (CodeGenUtil.isJavaReservedWord(name)) return name + "_";
435     return name;
436   }
437   
438   public static String JavaDoc format(String JavaDoc name, char separator, String JavaDoc prefix, boolean includePrefix)
439   {
440     List JavaDoc parsedName = new ArrayList JavaDoc();
441
442     if (prefix != null &&
443           name.startsWith(prefix) &&
444           name.length() > prefix.length() && Character.isUpperCase(name.charAt(prefix.length())))
445     {
446       name = name.substring(prefix.length());
447       if (includePrefix)
448       {
449         parsedName = parseName(prefix, '_');
450       }
451     }
452
453     if (name.length() != 0) parsedName.addAll(parseName(name, '_'));
454
455     StringBuffer JavaDoc result = new StringBuffer JavaDoc();
456
457     for (Iterator JavaDoc nameIter = parsedName.iterator(); nameIter.hasNext(); )
458     {
459       String JavaDoc nameComponent = (String JavaDoc)nameIter.next();
460       result.append(nameComponent);
461
462       if (nameIter.hasNext() && nameComponent.length() > 1)
463       {
464         result.append(separator);
465       }
466     }
467
468     return result.length() == 0 && prefix != null ? prefix : result.toString();
469   }
470
471   /**
472    * This method breaks sourceName into words delimited by sourceSeparator and/or mixed-case naming.
473    */

474   public static List JavaDoc parseName(String JavaDoc sourceName, char sourceSeparator)
475   {
476     List JavaDoc result = new ArrayList JavaDoc();
477     StringBuffer JavaDoc currentWord = new StringBuffer JavaDoc();
478
479     int length = sourceName.length();
480     boolean lastIsLower = false;
481
482     for (int index=0; index<length; index++)
483     {
484       char curChar = sourceName.charAt(index);
485       if (Character.isUpperCase(curChar) || (!lastIsLower && Character.isDigit(curChar)) || curChar == sourceSeparator)
486       {
487         if (lastIsLower || curChar == sourceSeparator)
488         {
489           result.add(currentWord.toString());
490           currentWord = new StringBuffer JavaDoc();
491         }
492         lastIsLower = false;
493       }
494       else
495       {
496         if (!lastIsLower)
497         {
498           int currentWordLength = currentWord.length();
499           if (currentWordLength > 1)
500           {
501             char lastChar = currentWord.charAt(--currentWordLength);
502             currentWord.setLength(currentWordLength);
503             result.add(currentWord.toString());
504             currentWord = new StringBuffer JavaDoc();
505             currentWord.append(lastChar);
506           }
507         }
508         lastIsLower = true;
509       }
510       if (curChar != sourceSeparator)
511       {
512         currentWord.append(curChar);
513       }
514     }
515
516     result.add(currentWord.toString());
517     return result;
518   }
519   
520   public static boolean isInJavaOutput(IResource resource)
521   {
522     IProject project = resource.getProject();
523     IJavaProject javaProject = JavaCore.create(project);
524     try
525     {
526       if (javaProject.exists() && project != project.getWorkspace().getRoot().findMember(javaProject.getOutputLocation())
527         && javaProject.getOutputLocation().isPrefixOf(resource.getFullPath()))
528       {
529         return true;
530       }
531     }
532     catch (JavaModelException exception)
533     {
534       CodeGenPlugin.INSTANCE.log(exception);
535     }
536
537     return false;
538   }
539   
540   /**
541    * This is a progress monitor that prints the progress information to a stream.
542    */

543   public static class StreamProgressMonitor extends NullProgressMonitor
544   {
545     protected PrintStream JavaDoc printStream;
546
547     public StreamProgressMonitor(PrintStream JavaDoc printStream)
548     {
549       this.printStream = printStream;
550     }
551
552     public void beginTask(String JavaDoc name, int totalWork)
553     {
554       if (name != null && name.length() != 0)
555       {
556         printStream.println(">>> " + name);
557       }
558       super.beginTask(name, totalWork);
559     }
560
561     public void setTaskName(String JavaDoc name)
562     {
563       if (name != null && name.length() != 0)
564       {
565         printStream.println("<>> " + name);
566       }
567       super.setTaskName(name);
568     }
569
570     public void subTask(String JavaDoc name)
571     {
572       if (name != null && name.length() != 0)
573       {
574         printStream.println(">> " + name);
575       }
576       super.subTask(name);
577     }
578   }
579
580   public static IContainer findOrCreateContainer
581     (IPath path, boolean forceRefresh, IPath localLocation, IProgressMonitor progressMonitor) throws CoreException
582   {
583     String JavaDoc projectName = path.segment(0);
584     IProjectDescription projectDescription = ResourcesPlugin.getWorkspace().newProjectDescription(projectName);
585     projectDescription.setLocation(localLocation);
586     return findOrCreateContainer(path, forceRefresh, projectDescription, progressMonitor);
587   }
588
589   public static IContainer findOrCreateContainer
590     (IPath path, boolean forceRefresh, IProjectDescription projectDescription, IProgressMonitor progressMonitor) throws CoreException
591   {
592     try
593     {
594       String JavaDoc projectName = path.segment(0);
595       progressMonitor.beginTask("", path.segmentCount() + 3);
596       progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_ExaminingProject_message", new Object JavaDoc [] { projectName }));
597       IWorkspace workspace = ResourcesPlugin.getWorkspace();
598       IProject project = workspace.getRoot().getProject(path.segment(0));
599
600       if (forceRefresh)
601       {
602         project.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(progressMonitor, 1));
603       }
604       else
605       {
606         progressMonitor.worked(1);
607       }
608
609       if (!project.exists())
610       {
611         project.create(projectDescription, new SubProgressMonitor(progressMonitor, 1));
612         project.open(new SubProgressMonitor(progressMonitor, 1));
613       }
614       else
615       {
616         project.open(new SubProgressMonitor(progressMonitor, 2));
617       }
618
619       IContainer container = project;
620       for (int i = 1, length = path.segmentCount(); i < length; ++ i)
621       {
622         IFolder folder = container.getFolder(new Path(path.segment(i)));
623         if (!folder.exists())
624         {
625           folder.create(false, true, new SubProgressMonitor(progressMonitor, 1));
626         }
627         else
628         {
629           progressMonitor.worked(1);
630         }
631
632         container = folder;
633       }
634
635       return container;
636     }
637     finally
638     {
639       progressMonitor.done();
640     }
641   }
642
643   public static List JavaDoc getClasspathPaths(String JavaDoc pluginID) throws JETException
644   {
645     List JavaDoc result = new ArrayList JavaDoc();
646     try
647     {
648       Bundle bundle = Platform.getBundle(pluginID);
649       String JavaDoc requires = (String JavaDoc)bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH);
650       if (requires == null)
651       {
652         requires = ".";
653       }
654       ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, requires);
655       if (elements != null)
656       {
657         for (int i = 0; i < elements.length; ++i)
658         {
659           ManifestElement element = elements[i];
660           String JavaDoc value = element.getValue();
661           if (".".equals(value))
662           {
663             value = "/";
664           }
665           try
666           {
667             URL JavaDoc url = bundle.getEntry(value);
668             if (url != null)
669             {
670               URL JavaDoc resolvedURL = Platform.resolve(url);
671               String JavaDoc resolvedURLString = resolvedURL.toString();
672               if (resolvedURLString.endsWith("!/"))
673               {
674                 resolvedURLString = resolvedURL.getFile();
675                 resolvedURLString = resolvedURLString.substring(0,resolvedURLString.length() - "!/".length());
676               }
677               if (resolvedURLString.startsWith("file:"))
678               {
679                 result.add(resolvedURLString.substring("file:".length()));
680               }
681               else
682               {
683                 result.add(Platform.asLocalURL(url).getFile());
684               }
685             }
686           }
687           catch (IOException JavaDoc exception)
688           {
689             throw new JETException(exception);
690           }
691           break;
692         }
693       }
694     }
695     catch (BundleException exception)
696     {
697       throw new JETException(exception);
698     }
699     return result;
700   }
701   
702   public static void addClasspathEntries(Collection JavaDoc classpathEntries, String JavaDoc variableName, String JavaDoc pluginID) throws JETException
703   {
704     for (ListIterator JavaDoc i = getClasspathPaths(pluginID).listIterator(); i.hasNext(); )
705     {
706       IPath path = new Path((String JavaDoc)i.next());
707       if (variableName == null)
708       {
709         classpathEntries.add(JavaCore.newLibraryEntry(path, null, null));
710       }
711       else
712       {
713         String JavaDoc mangledName = variableName + (i.previousIndex() == 0 ? "" : "_" + i.previousIndex());
714         try
715         {
716           JavaCore.setClasspathVariable(mangledName, path, null);
717         }
718         catch (JavaModelException exception)
719         {
720           throw new JETException(exception);
721         }
722         classpathEntries.add(JavaCore.newVariableEntry(new Path(mangledName), null, null));
723       }
724     }
725   }
726
727   public static void addClasspathEntries(Collection JavaDoc classpathEntries, String JavaDoc pluginID) throws Exception JavaDoc
728   {
729     addClasspathEntries(classpathEntries, null, pluginID);
730   }
731   
732   /**
733    * Returns the package name for a qualified class name, ie, a substring
734    * from the first char until the last &quot;.&quot;. If the argument is
735    * <tt>null</tt> or a non-qualified name, this method returns <tt>null</tt>.
736    * @param qualifiedClassName
737    * @return String
738    */

739   public static String JavaDoc getPackageName(String JavaDoc qualifiedClassName)
740   {
741     int index = qualifiedClassName != null ?
742       qualifiedClassName.lastIndexOf('.') :
743       -1;
744       
745     return index >= 0 ?
746       qualifiedClassName.substring(0, index) :
747       null;
748   }
749   
750   /**
751    * Returns the simple class name for a qualified class name, ie, a substring
752    * from starting after the last &quot;.&quot;. If the argument is
753    * a non-qualified name, this method returns the argument.
754    * @param qualifiedClassName
755    * @return String
756    */

757   public static String JavaDoc getSimpleClassName(String JavaDoc qualifiedClassName)
758   {
759     int index = qualifiedClassName != null ?
760       qualifiedClassName.lastIndexOf('.') :
761       -1;
762       
763     return index >= 0 ?
764       qualifiedClassName.substring(index+1) :
765       qualifiedClassName;
766   }
767   
768 }
769
Popular Tags