1 /*
2  * Copyright (c) 1998, 2007, 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 /*
27  * Licensed Materials - Property of IBM
28  * RMI-IIOP v1.0
29  * Copyright IBM Corp. 1998 1999  All Rights Reserved
30  *
31  */
32 
33 package sun.rmi.rmic.iiop;
34 
35 import sun.rmi.rmic.Main;
36 import sun.tools.java.ClassPath;
37 import java.io.OutputStream;
38 import sun.tools.java.ClassDefinition;
39 import sun.tools.java.ClassDeclaration;
40 import sun.tools.java.Identifier;
41 import sun.tools.java.ClassNotFound;
42 import java.util.HashSet;
43 import java.util.Hashtable;
44 import java.util.Enumeration;
45 import java.util.Iterator;
46 
47 /**
48  * BatchEnvironment for iiop extends rmic's version to add
49  * parse state.
50  */
51 public class BatchEnvironment extends sun.rmi.rmic.BatchEnvironment implements Constants {
52 
53     /*
54      * If the following flag is true, then the IDL generator can map
55      * the methods and constants of non-conforming types. However,
56      * this is very expensive, so the default should be false.
57      */
58     private boolean parseNonConforming = false;
59 
60     /**
61      * This flag indicates that the stubs and ties need to be generated without
62      * the package prefix (org.omg.stub).
63      */
64     private boolean standardPackage;
65 
66     /* Common objects used within package */
67 
68     HashSet alreadyChecked = new HashSet();
69     Hashtable allTypes = new Hashtable(3001, 0.5f);
70     Hashtable invalidTypes = new Hashtable(256, 0.5f);
71     DirectoryLoader loader = null;
72     ClassPathLoader classPathLoader = null;
73     Hashtable nameContexts = null;
74     Hashtable namesCache = new Hashtable();
75     NameContext modulesContext = new NameContext(false);
76 
77     ClassDefinition defRemote = null;
78     ClassDefinition defError = null;
79     ClassDefinition defException = null;
80     ClassDefinition defRemoteException = null;
81     ClassDefinition defCorbaObject = null;
82     ClassDefinition defSerializable = null;
83     ClassDefinition defExternalizable = null;
84     ClassDefinition defThrowable = null;
85     ClassDefinition defRuntimeException = null;
86     ClassDefinition defIDLEntity = null;
87     ClassDefinition defValueBase = null;
88 
89     sun.tools.java.Type typeRemoteException = null;
90     sun.tools.java.Type typeIOException = null;
91     sun.tools.java.Type typeException = null;
92     sun.tools.java.Type typeThrowable = null;
93 
94     ContextStack contextStack = null;
95 
96     /**
97      * Create a BatchEnvironment for rmic with the given class path,
98      * stream for messages and Main.
99      */
BatchEnvironment(OutputStream out, ClassPath path, Main main)100     public BatchEnvironment(OutputStream out, ClassPath path, Main main) {
101 
102         super(out,path,main);
103 
104         // Make sure we have our definitions...
105 
106         try {
107             defRemote =
108                 getClassDeclaration(idRemote).getClassDefinition(this);
109             defError =
110                 getClassDeclaration(idJavaLangError).getClassDefinition(this);
111             defException =
112                 getClassDeclaration(idJavaLangException).getClassDefinition(this);
113             defRemoteException =
114                 getClassDeclaration(idRemoteException).getClassDefinition(this);
115             defCorbaObject =
116                 getClassDeclaration(idCorbaObject).getClassDefinition(this);
117             defSerializable =
118                 getClassDeclaration(idJavaIoSerializable).getClassDefinition(this);
119             defRuntimeException =
120                 getClassDeclaration(idJavaLangRuntimeException).getClassDefinition(this);
121             defExternalizable =
122                 getClassDeclaration(idJavaIoExternalizable).getClassDefinition(this);
123             defThrowable=
124                 getClassDeclaration(idJavaLangThrowable).getClassDefinition(this);
125             defIDLEntity=
126                 getClassDeclaration(idIDLEntity).getClassDefinition(this);
127             defValueBase=
128                 getClassDeclaration(idValueBase).getClassDefinition(this);
129             typeRemoteException = defRemoteException.getClassDeclaration().getType();
130             typeException = defException.getClassDeclaration().getType();
131             typeIOException = getClassDeclaration(idJavaIoIOException).getType();
132             typeThrowable = getClassDeclaration(idJavaLangThrowable).getType();
133 
134             classPathLoader = new ClassPathLoader(path);
135 
136         } catch (ClassNotFound e) {
137             error(0, "rmic.class.not.found", e.name);
138             throw new Error();
139         }
140     }
141 
142     /**
143      * Return whether or not to parse non-conforming types.
144      */
getParseNonConforming()145     public boolean getParseNonConforming () {
146         return parseNonConforming;
147     }
148 
149     /**
150      * Set whether or not to parse non-conforming types.
151      */
setParseNonConforming(boolean parseEm)152     public void setParseNonConforming (boolean parseEm) {
153 
154         // If we are transitioning from not parsing to
155         // parsing, we need to throw out any previously
156         // parsed types...
157 
158         if (parseEm && !parseNonConforming) {
159             reset();
160         }
161 
162         parseNonConforming = parseEm;
163     }
164 
setStandardPackage(boolean standardPackage)165     void setStandardPackage(boolean standardPackage) {
166         this.standardPackage = standardPackage;
167     }
168 
getStandardPackage()169     boolean getStandardPackage() {
170         return standardPackage;
171     }
172 
173     /**
174      * Clear out any data from previous executions.
175      */
reset()176     public void reset () {
177 
178         // First, find all Type instances and call destroy()
179         // on them...
180 
181         for (Enumeration e = allTypes.elements() ; e.hasMoreElements() ;) {
182             Type type = (Type) e.nextElement();
183             type.destroy();
184         }
185 
186         for (Enumeration e = invalidTypes.keys() ; e.hasMoreElements() ;) {
187             Type type = (Type) e.nextElement();
188             type.destroy();
189         }
190 
191         for (Iterator e = alreadyChecked.iterator() ; e.hasNext() ;) {
192             Type type = (Type) e.next();
193             type.destroy();
194         }
195 
196         if (contextStack != null) contextStack.clear();
197 
198         // Remove and clear all NameContexts in the
199         // nameContexts cache...
200 
201         if (nameContexts != null) {
202             for (Enumeration e = nameContexts.elements() ; e.hasMoreElements() ;) {
203                 NameContext context = (NameContext) e.nextElement();
204                 context.clear();
205             }
206             nameContexts.clear();
207         }
208 
209         // Now remove all table entries...
210 
211         allTypes.clear();
212         invalidTypes.clear();
213         alreadyChecked.clear();
214         namesCache.clear();
215         modulesContext.clear();
216 
217         // Clean up remaining...
218         loader = null;
219         parseNonConforming = false;
220 
221         // REVISIT - can't clean up classPathLoader here
222     }
223 
224     /**
225      * Release resources, if any.
226      */
shutdown()227     public void shutdown() {
228         if (alreadyChecked != null) {
229             //System.out.println();
230             //System.out.println("allTypes.size() = "+ allTypes.size());
231             //System.out.println("    InstanceCount before reset = "+Type.instanceCount);
232             reset();
233             //System.out.println("    InstanceCount AFTER reset = "+Type.instanceCount);
234 
235             alreadyChecked = null;
236             allTypes = null;
237             invalidTypes = null;
238             nameContexts = null;
239             namesCache = null;
240             modulesContext = null;
241             defRemote = null;
242             defError = null;
243             defException = null;
244             defRemoteException = null;
245             defCorbaObject = null;
246             defSerializable = null;
247             defExternalizable = null;
248             defThrowable = null;
249             defRuntimeException = null;
250             defIDLEntity = null;
251             defValueBase = null;
252             typeRemoteException = null;
253             typeIOException = null;
254             typeException = null;
255             typeThrowable = null;
256 
257             super.shutdown();
258         }
259     }
260 }
261