< prev index next >

src/jdk.xml.bind/share/classes/com/sun/codemodel/internal/JCodeModel.java

Print this page


   1 /*
   2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.codemodel.internal;
  27 
  28 import java.io.File;
  29 import java.io.IOException;
  30 import java.io.PrintStream;
  31 import java.lang.reflect.Modifier;
  32 import java.util.ArrayList;
  33 import java.util.Collections;
  34 import java.util.HashMap;
  35 import java.util.Iterator;
  36 import java.util.List;
  37 import java.util.Map;
  38 
  39 import com.sun.codemodel.internal.writer.FileCodeWriter;
  40 import com.sun.codemodel.internal.writer.ProgressCodeWriter;
  41 
  42 
  43 /**
  44  * Root of the code DOM.
  45  *
  46  * <p>
  47  * Here's your typical CodeModel application.
  48  *
  49  * <pre>
  50  * JCodeModel cm = new JCodeModel();
  51  *
  52  * // generate source code by populating the 'cm' tree.
  53  * cm._class(...);
  54  * ...
  55  *
  56  * // write them out
  57  * cm.build(new File("."));
  58  * </pre>
  59  *
  60  * <p>
  61  * Every CodeModel node is always owned by one {@link JCodeModel} object
  62  * at any given time (which can be often accesesd by the {@code owner()} method.)
  63  *
  64  * As such, when you generate Java code, most of the operation works
  65  * in a top-down fashion. For example, you create a class from {@link JCodeModel},
  66  * which gives you a {@link JDefinedClass}. Then you invoke a method on it
  67  * to generate a new method, which gives you {@link JMethod}, and so on.
  68  *
  69  * There are a few exceptions to this, most notably building {@link JExpression}s,
  70  * but generally you work with CodeModel in a top-down fashion.
  71  *
  72  * Because of this design, most of the CodeModel classes aren't directly instanciable.
  73  *
  74  *
  75  * <h2>Where to go from here?</h2>
  76  * <p>
  77  * Most of the time you'd want to populate new type definitions in a {@link JCodeModel}.
  78  * See {@link #_class(String, ClassType)}.
  79  */
  80 public final class JCodeModel {
  81 
  82     /** The packages that this JCodeWriter contains. */
  83     private HashMap<String,JPackage> packages = new HashMap<String,JPackage>();



  84 
  85     /** All JReferencedClasses are pooled here. */
  86     private final HashMap<Class<?>,JReferencedClass> refClasses = new HashMap<Class<?>,JReferencedClass>();
  87 
  88 
  89     /** Obtains a reference to the special "null" type. */
  90     public final JNullType NULL = new JNullType(this);
  91     // primitive types
  92     public final JPrimitiveType VOID    = new JPrimitiveType(this,"void",   Void.class);
  93     public final JPrimitiveType BOOLEAN = new JPrimitiveType(this,"boolean",Boolean.class);
  94     public final JPrimitiveType BYTE    = new JPrimitiveType(this,"byte",   Byte.class);
  95     public final JPrimitiveType SHORT   = new JPrimitiveType(this,"short",  Short.class);
  96     public final JPrimitiveType CHAR    = new JPrimitiveType(this,"char",   Character.class);
  97     public final JPrimitiveType INT     = new JPrimitiveType(this,"int",    Integer.class);
  98     public final JPrimitiveType FLOAT   = new JPrimitiveType(this,"float",  Float.class);
  99     public final JPrimitiveType LONG    = new JPrimitiveType(this,"long",   Long.class);
 100     public final JPrimitiveType DOUBLE  = new JPrimitiveType(this,"double", Double.class);
 101 
 102     /**
 103      * If the flag is true, we will consider two classes "Foo" and "foo"
 104      * as a collision.
 105      */
 106     protected static final boolean isCaseSensitiveFileSystem = getFileSystemCaseSensitivity();
 107 
 108     private static boolean getFileSystemCaseSensitivity() {
 109         try {
 110             // let the system property override, in case the user really
 111             // wants to override.
 112             if( System.getProperty("com.sun.codemodel.internal.FileSystemCaseSensitive")!=null )
 113                 return true;
 114         } catch( Exception e ) {}
 115 
 116         // on Unix, it's case sensitive.
 117         return (File.separatorChar == '/');
 118     }
 119 
 120 
 121     public JCodeModel() {}
 122 
 123     /**
 124      * Add a package to the list of packages to be generated
 125      *
 126      * @param name
 127      *        Name of the package. Use "" to indicate the root package.
 128      *
 129      * @return Newly generated package
 130      */
 131     public JPackage _package(String name) {
 132         JPackage p = packages.get(name);
 133         if (p == null) {
 134             p = new JPackage(name, this);
 135             packages.put(name, p);
 136         }
 137         return p;
 138     }
 139 












































 140     public final JPackage rootPackage() {
 141         return _package("");
 142     }
 143 
 144     /**
 145      * Returns an iterator that walks the packages defined using this code
 146      * writer.
 147      */
 148     public Iterator<JPackage> packages() {
 149         return packages.values().iterator();
 150     }
 151 
 152     /**
 153      * Creates a new generated class.
 154      *
 155      * @exception JClassAlreadyExistsException
 156      *      When the specified class/interface was already created.
 157      */
 158     public JDefinedClass _class(String fullyqualifiedName) throws JClassAlreadyExistsException {
 159         return _class(fullyqualifiedName,ClassType.CLASS);


 275     /**
 276      * A convenience method for <code>build(srcDir,resourceDir,System.out)</code>.
 277      */
 278     public void build( File srcDir, File resourceDir ) throws IOException {
 279         build(srcDir,resourceDir,System.out);
 280     }
 281 
 282     /**
 283      * A convenience method for <code>build(out,out)</code>.
 284      */
 285     public void build( CodeWriter out ) throws IOException {
 286         build(out,out);
 287     }
 288 
 289     /**
 290      * Generates Java source code.
 291      */
 292     public void build( CodeWriter source, CodeWriter resource ) throws IOException {
 293         JPackage[] pkgs = packages.values().toArray(new JPackage[packages.size()]);
 294         // avoid concurrent modification exception
 295         for( JPackage pkg : pkgs )
 296             pkg.build(source,resource);




 297         source.close();
 298         resource.close();
 299     }
 300 
 301     /**
 302      * Returns the number of files to be generated if
 303      * {@link #build} is invoked now.
 304      */
 305     public int countArtifacts() {
 306         int r = 0;
 307         JPackage[] pkgs = packages.values().toArray(new JPackage[packages.size()]);
 308         // avoid concurrent modification exception
 309         for( JPackage pkg : pkgs )
 310             r += pkg.countArtifacts();
 311         return r;
 312     }
 313 
 314 
 315     /**
 316      * Obtains a reference to an existing class from its Class object.


   1 /*
   2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.codemodel.internal;
  27 
  28 import java.io.File;
  29 import java.io.IOException;
  30 import java.io.PrintStream;
  31 import java.lang.reflect.Modifier;
  32 import java.util.ArrayList;
  33 import java.util.Collections;
  34 import java.util.HashMap;
  35 import java.util.Iterator;
  36 import java.util.List;
  37 import java.util.Map;
  38 
  39 import com.sun.codemodel.internal.writer.FileCodeWriter;
  40 import com.sun.codemodel.internal.writer.ProgressCodeWriter;
  41 

  42 /**
  43  * Root of the code DOM.
  44  *
  45  * <p>
  46  * Here's your typical CodeModel application.
  47  *
  48  * <pre>
  49  * JCodeModel cm = new JCodeModel();
  50  *
  51  * // generate source code by populating the 'cm' tree.
  52  * cm._class(...);
  53  * ...
  54  *
  55  * // write them out
  56  * cm.build(new File("."));
  57  * </pre>
  58  *
  59  * <p>
  60  * Every CodeModel node is always owned by one {@link JCodeModel} object
  61  * at any given time (which can be often accesesd by the {@code owner()} method.)
  62  *
  63  * As such, when you generate Java code, most of the operation works
  64  * in a top-down fashion. For example, you create a class from {@link JCodeModel},
  65  * which gives you a {@link JDefinedClass}. Then you invoke a method on it
  66  * to generate a new method, which gives you {@link JMethod}, and so on.
  67  *
  68  * There are a few exceptions to this, most notably building {@link JExpression}s,
  69  * but generally you work with CodeModel in a top-down fashion.
  70  *
  71  * Because of this design, most of the CodeModel classes aren't directly instanciable.
  72  *
  73  *
  74  * <h2>Where to go from here?</h2>
  75  * <p>
  76  * Most of the time you'd want to populate new type definitions in a {@link JCodeModel}.
  77  * See {@link #_class(String, ClassType)}.
  78  */
  79 public final class JCodeModel {
  80 
  81     /** The packages that this JCodeWriter contains. */
  82     private final HashMap<String,JPackage> packages = new HashMap<>();
  83 
  84     /** Java module in {@code module-info.java} file. */
  85     private JModule module;
  86 
  87     /** All JReferencedClasses are pooled here. */
  88     private final HashMap<Class<?>,JReferencedClass> refClasses = new HashMap<>();
  89 
  90 
  91     /** Obtains a reference to the special "null" type. */
  92     public final JNullType NULL = new JNullType(this);
  93     // primitive types
  94     public final JPrimitiveType VOID    = new JPrimitiveType(this,"void",   Void.class);
  95     public final JPrimitiveType BOOLEAN = new JPrimitiveType(this,"boolean",Boolean.class);
  96     public final JPrimitiveType BYTE    = new JPrimitiveType(this,"byte",   Byte.class);
  97     public final JPrimitiveType SHORT   = new JPrimitiveType(this,"short",  Short.class);
  98     public final JPrimitiveType CHAR    = new JPrimitiveType(this,"char",   Character.class);
  99     public final JPrimitiveType INT     = new JPrimitiveType(this,"int",    Integer.class);
 100     public final JPrimitiveType FLOAT   = new JPrimitiveType(this,"float",  Float.class);
 101     public final JPrimitiveType LONG    = new JPrimitiveType(this,"long",   Long.class);
 102     public final JPrimitiveType DOUBLE  = new JPrimitiveType(this,"double", Double.class);
 103 
 104     /**
 105      * If the flag is true, we will consider two classes "Foo" and "foo"
 106      * as a collision.
 107      */
 108     protected static final boolean isCaseSensitiveFileSystem = getFileSystemCaseSensitivity();
 109 
 110     private static boolean getFileSystemCaseSensitivity() {
 111         try {
 112             // let the system property override, in case the user really
 113             // wants to override.
 114             if( System.getProperty("com.sun.codemodel.internal.FileSystemCaseSensitive")!=null )
 115                 return true;
 116         } catch( Exception e ) {}
 117 
 118         // on Unix, it's case sensitive.
 119         return (File.separatorChar == '/');
 120     }
 121 
 122 
 123     public JCodeModel() {}
 124 
 125     /**
 126      * Add a package to the list of packages to be generated.
 127      *
 128      * @param name
 129      *        Name of the package. Use "" to indicate the root package.
 130      *
 131      * @return Newly generated package
 132      */
 133     public JPackage _package(String name) {
 134         JPackage p = packages.get(name);
 135         if (p == null) {
 136             p = new JPackage(name, this);
 137             packages.put(name, p);
 138         }
 139         return p;
 140     }
 141 
 142     /**
 143      * Creates and returns Java module to be generated.
 144      * @param name The Name of Java module.
 145      * @return New Java module.
 146      */
 147     public JModule _moduleInfo(final String name) {
 148         return module = new JModule(name);
 149     }
 150 
 151     /**
 152      * Returns existing Java module to be generated.
 153      * @return Java module or {@code null} if Java module was not created yet.
 154      */
 155     public JModule _getModuleInfo() {
 156         return module;
 157     }
 158 
 159     /**
 160      * Creates Java module instance and adds existing packages with classes to the Java module info.
 161      * Used to initialize and build Java module instance with existing packages content.
 162      * @param name The Name of Java module.
 163      * @param requires Requires directives to add.
 164      * @throws IllegalStateException when Java module instance was not initialized.
 165      */
 166     public void _prepareModuleInfo(final String name, final String ...requires) {
 167         _moduleInfo(name);
 168         _updateModuleInfo(requires);
 169     }
 170 
 171     /**
 172      * Adds existing packages with classes to the Java module info.
 173      * Java module instance must exist before calling this method.
 174      * Used to update Java module instance with existing packages content after it was prepared on client side.
 175      * @param requires Requires directives to add.
 176      * @throws IllegalStateException when Java module instance was not initialized.
 177      */
 178     public void _updateModuleInfo(final String ...requires) {
 179         if (module == null) {
 180             throw new IllegalStateException("Java module instance was not initialized yet.");
 181         }
 182         module._exports(packages.values(), false);
 183         module._requires(requires);
 184     }
 185 
 186     public final JPackage rootPackage() {
 187         return _package("");
 188     }
 189 
 190     /**
 191      * Returns an iterator that walks the packages defined using this code
 192      * writer.
 193      */
 194     public Iterator<JPackage> packages() {
 195         return packages.values().iterator();
 196     }
 197 
 198     /**
 199      * Creates a new generated class.
 200      *
 201      * @exception JClassAlreadyExistsException
 202      *      When the specified class/interface was already created.
 203      */
 204     public JDefinedClass _class(String fullyqualifiedName) throws JClassAlreadyExistsException {
 205         return _class(fullyqualifiedName,ClassType.CLASS);


 321     /**
 322      * A convenience method for <code>build(srcDir,resourceDir,System.out)</code>.
 323      */
 324     public void build( File srcDir, File resourceDir ) throws IOException {
 325         build(srcDir,resourceDir,System.out);
 326     }
 327 
 328     /**
 329      * A convenience method for <code>build(out,out)</code>.
 330      */
 331     public void build( CodeWriter out ) throws IOException {
 332         build(out,out);
 333     }
 334 
 335     /**
 336      * Generates Java source code.
 337      */
 338     public void build( CodeWriter source, CodeWriter resource ) throws IOException {
 339         JPackage[] pkgs = packages.values().toArray(new JPackage[packages.size()]);
 340         // avoid concurrent modification exception
 341         for( JPackage pkg : pkgs ) {
 342             pkg.build(source,resource);
 343         }
 344         if (module != null) {
 345             module.build(source);
 346         }
 347         source.close();
 348         resource.close();
 349     }
 350 
 351     /**
 352      * Returns the number of files to be generated if
 353      * {@link #build} is invoked now.
 354      */
 355     public int countArtifacts() {
 356         int r = 0;
 357         JPackage[] pkgs = packages.values().toArray(new JPackage[packages.size()]);
 358         // avoid concurrent modification exception
 359         for( JPackage pkg : pkgs )
 360             r += pkg.countArtifacts();
 361         return r;
 362     }
 363 
 364 
 365     /**
 366      * Obtains a reference to an existing class from its Class object.


< prev index next >