Source Code Cross Referenced for Imports.java in  » 6.0-JDK-Modules-sun » tools » sun » tools » java » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules sun » tools » sun.tools.java 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 1994-2003 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package sun.tools.java;
027:
028:        import java.util.Hashtable;
029:        import java.util.Vector;
030:        import java.util.Enumeration;
031:        import java.util.List;
032:        import java.util.Collections;
033:        import java.io.IOException;
034:
035:        /**
036:         * This class describes the classes and packages imported
037:         * from a source file. A Hashtable called bindings is maintained
038:         * to quickly map symbol names to classes. This table is flushed
039:         * everytime a new import is added.
040:         *
041:         * A class name is resolved as follows:
042:         *  - if it is a qualified name then return the corresponding class
043:         *  - if the name corresponds to an individually imported class then return that class
044:         *  - check if the class is defined in any of the imported packages,
045:         *    if it is then return it, make sure it is defined in only one package
046:         *  - assume that the class is defined in the current package
047:         *
048:         * WARNING: The contents of this source file are not part of any
049:         * supported API.  Code that depends on them does so at its own risk:
050:         * they are subject to change or removal without notice.
051:         */
052:
053:        public class Imports implements  Constants {
054:            /**
055:             * The current package, which is implicitly imported,
056:             * and has precedence over other imported packages.
057:             */
058:            Identifier currentPackage = idNull;
059:
060:            /**
061:             * A location for the current package declaration.  Used to
062:             * report errors against the current package.
063:             */
064:            long currentPackageWhere = 0;
065:
066:            /**
067:             * The imported classes, including memoized imports from packages.
068:             */
069:            Hashtable classes = new Hashtable();
070:
071:            /**
072:             * The imported package identifiers.  This will not contain duplicate
073:             * imports for the same package.  It will also not contain the
074:             * current package.
075:             */
076:            Vector packages = new Vector();
077:
078:            /**
079:             * The (originally) imported classes.
080:             * A vector of IdentifierToken.
081:             */
082:            Vector singles = new Vector();
083:
084:            /**
085:             * Are the import names checked yet?
086:             */
087:            protected int checked;
088:
089:            /**
090:             * Constructor, always import java.lang.
091:             */
092:            public Imports(Environment env) {
093:                addPackage(idJavaLang);
094:            }
095:
096:            /**
097:             * Check the names of the imports.
098:             */
099:            public synchronized void resolve(Environment env) {
100:                if (checked != 0) {
101:                    return;
102:                }
103:                checked = -1;
104:
105:                // After all class information has been read, now we can
106:                // safely inspect import information for errors.
107:                // If we did this before all parsing was finished,
108:                // we could get vicious circularities, since files can
109:                // import each others' classes.
110:
111:                // A note: the resolution of the package java.lang takes place
112:                // in the sun.tools.javac.BatchEnvironment#setExemptPackages().
113:
114:                // Make sure that the current package's name does not collide
115:                // with the name of an existing class. (bug 4101529)
116:                //
117:                // This change has been backed out because, on WIN32, it
118:                // failed to distinguish between java.awt.event and
119:                // java.awt.Event when looking for a directory.  We will
120:                // add this back in later.
121:                //
122:                // if (currentPackage != idNull) {
123:                //    Identifier resolvedName =
124:                //	env.resolvePackageQualifiedName(currentPackage);
125:                //   
126:                //   Identifier className = resolvedName.getTopName();
127:                //
128:                //   if (importable(className, env)) {
129:                //	// The name of the current package is also the name
130:                //	// of a class.
131:                //      env.error(currentPackageWhere, "package.class.conflict",
132:                // 		  currentPackage, className);
133:                //     }
134:                // }
135:
136:                Vector resolvedPackages = new Vector();
137:                for (Enumeration e = packages.elements(); e.hasMoreElements();) {
138:                    IdentifierToken t = (IdentifierToken) e.nextElement();
139:                    Identifier nm = t.getName();
140:                    long where = t.getWhere();
141:
142:                    // Check to see if this package is exempt from the "exists"
143:                    // check.  See the note in
144:                    // sun.tools.javac.BatchEnvironment#setExemptPackages()
145:                    // for more information.
146:                    if (env.isExemptPackage(nm)) {
147:                        resolvedPackages.addElement(t);
148:                        continue;
149:                    }
150:
151:                    // (Note: This code is moved from BatchParser.importPackage().)
152:                    try {
153:                        Identifier rnm = env.resolvePackageQualifiedName(nm);
154:                        if (importable(rnm, env)) {
155:                            // This name is a real class; better not be a package too.
156:                            if (env.getPackage(rnm.getTopName()).exists()) {
157:                                env.error(where, "class.and.package", rnm
158:                                        .getTopName());
159:                            }
160:                            // Pass an "inner" name to the imports.
161:                            if (!rnm.isInner())
162:                                rnm = Identifier.lookupInner(rnm, idNull);
163:                            nm = rnm;
164:                        } else if (!env.getPackage(nm).exists()) {
165:                            env.error(where, "package.not.found", nm, "import");
166:                        } else if (rnm.isInner()) {
167:                            // nm exists, and rnm.getTopName() is a parent package
168:                            env.error(where, "class.and.package", rnm
169:                                    .getTopName());
170:                        }
171:                        resolvedPackages.addElement(new IdentifierToken(where,
172:                                nm));
173:                    } catch (IOException ee) {
174:                        env.error(where, "io.exception", "import");
175:                    }
176:                }
177:                packages = resolvedPackages;
178:
179:                for (Enumeration e = singles.elements(); e.hasMoreElements();) {
180:                    IdentifierToken t = (IdentifierToken) e.nextElement();
181:                    Identifier nm = t.getName();
182:                    long where = t.getWhere();
183:                    Identifier pkg = nm.getQualifier();
184:
185:                    // (Note: This code is moved from BatchParser.importClass().)
186:                    nm = env.resolvePackageQualifiedName(nm);
187:                    if (!env.classExists(nm.getTopName())) {
188:                        env.error(where, "class.not.found", nm, "import");
189:                    }
190:
191:                    // (Note: This code is moved from Imports.addClass().)
192:                    Identifier snm = nm.getFlatName().getName();
193:
194:                    // make sure it isn't already imported explicitly
195:                    Identifier className = (Identifier) classes.get(snm);
196:                    if (className != null) {
197:                        Identifier f1 = Identifier.lookup(className
198:                                .getQualifier(), className.getFlatName());
199:                        Identifier f2 = Identifier.lookup(nm.getQualifier(), nm
200:                                .getFlatName());
201:                        if (!f1.equals(f2)) {
202:                            env.error(where, "ambig.class", nm, className);
203:                        }
204:                    }
205:                    classes.put(snm, nm);
206:
207:                    // The code here needs to check to see, if we
208:                    // are importing an inner class, that all of its
209:                    // enclosing classes are visible to us.  To check this,
210:                    // we need to construct a definition for the class.
211:                    // The code here used to call...
212:                    //
213:                    //     ClassDefinition def = env.getClassDefinition(nm);
214:                    //
215:                    // ...but that interfered with the basicCheck()'ing of
216:                    // interfaces in certain cases (bug no. 4086139).  Never
217:                    // fear.  Instead we load the class with a call to the 
218:                    // new getClassDefinitionNoCheck() which does no basicCheck() and
219:                    // lets us answer the questions we are interested in w/o
220:                    // interfering with the demand-driven nature of basicCheck().
221:
222:                    try {
223:                        // Get a declaration
224:                        ClassDeclaration decl = env.getClassDeclaration(nm);
225:
226:                        // Get the definition (no env argument)
227:                        ClassDefinition def = decl
228:                                .getClassDefinitionNoCheck(env);
229:
230:                        // Get the true name of the package containing this class.
231:                        // `pkg' from above is insufficient.  It includes the
232:                        // names of our enclosing classes.  Fix for 4086815.
233:                        Identifier importedPackage = def.getName()
234:                                .getQualifier();
235:
236:                        // Walk out the outerClass chain, ensuring that each level
237:                        // is visible from our perspective.
238:                        for (; def != null; def = def.getOuterClass()) {
239:                            if (def.isPrivate()
240:                                    || !(def.isPublic() || importedPackage
241:                                            .equals(currentPackage))) {
242:                                env.error(where, "cant.access.class", def);
243:                                break;
244:                            }
245:                        }
246:                    } catch (AmbiguousClass ee) {
247:                        env.error(where, "ambig.class", ee.name1, ee.name2);
248:                    } catch (ClassNotFound ee) {
249:                        env.error(where, "class.not.found", ee.name, "import");
250:                    }
251:                }
252:                checked = 1;
253:            }
254:
255:            /**
256:             * Lookup a class, given the current set of imports,
257:             * AmbiguousClass exception is thrown if the name can be
258:             * resolved in more than one way. A ClassNotFound exception
259:             * is thrown if the class is not found in the imported classes
260:             * and packages.
261:             */
262:            public synchronized Identifier resolve(Environment env,
263:                    Identifier nm) throws ClassNotFound {
264:                if (tracing)
265:                    env.dtEnter("Imports.resolve: " + nm);
266:
267:                // If the class has the special ambiguous prefix, then we will
268:                // get the original AmbiguousClass exception by removing the
269:                // prefix and proceeding in the normal fashion.
270:                // (part of solution for 4059855)
271:                if (nm.hasAmbigPrefix()) {
272:                    nm = nm.removeAmbigPrefix();
273:                }
274:
275:                if (nm.isQualified()) {
276:                    // Don't bother it is already qualified
277:                    if (tracing)
278:                        env.dtExit("Imports.resolve: QUALIFIED " + nm);
279:                    return nm;
280:                }
281:
282:                if (checked <= 0) {
283:                    checked = 0;
284:                    resolve(env);
285:                }
286:
287:                // Check if it was imported before
288:                Identifier className = (Identifier) classes.get(nm);
289:                if (className != null) {
290:                    if (tracing)
291:                        env
292:                                .dtExit("Imports.resolve: PREVIOUSLY IMPORTED "
293:                                        + nm);
294:                    return className;
295:                }
296:
297:                // Note: the section below has changed a bit during the fix
298:                // for bug 4093217.  The current package is no longer grouped
299:                // with the rest of the import-on-demands; it is now checked
300:                // separately.  Also, the list of import-on-demands is now
301:                // guarranteed to be duplicate-free, so the code below can afford
302:                // to be a bit simpler.
303:
304:                // First we look in the current package.  The current package
305:                // is given precedence over the rest of the import-on-demands,
306:                // which means, among other things, that a class in the current
307:                // package cannot be ambiguous.
308:                Identifier id = Identifier.lookup(currentPackage, nm);
309:                if (importable(id, env)) {
310:                    className = id;
311:                } else {
312:                    // If it isn't in the current package, try to find it in
313:                    // our import-on-demands.
314:                    Enumeration e = packages.elements();
315:                    while (e.hasMoreElements()) {
316:                        IdentifierToken t = (IdentifierToken) e.nextElement();
317:                        id = Identifier.lookup(t.getName(), nm);
318:
319:                        if (importable(id, env)) {
320:                            if (className == null) {
321:                                // We haven't found any other matching classes yet.
322:                                // Set className to what we've found and continue
323:                                // looking for an ambiguity.
324:                                className = id;
325:                            } else {
326:                                if (tracing)
327:                                    env.dtExit("Imports.resolve: AMBIGUOUS "
328:                                            + nm);
329:
330:                                // We've found an ambiguity.
331:                                throw new AmbiguousClass(className, id);
332:                            }
333:                        }
334:                    }
335:                }
336:
337:                // Make sure a class was found
338:                if (className == null) {
339:                    if (tracing)
340:                        env.dtExit("Imports.resolve: NOT FOUND " + nm);
341:                    throw new ClassNotFound(nm);
342:                }
343:
344:                // Remember the binding
345:                classes.put(nm, className);
346:                if (tracing)
347:                    env.dtExit("Imports.resolve: FIRST IMPORT " + nm);
348:                return className;
349:            }
350:
351:            /**
352:             * Check to see if 'id' names an importable class in `env'.
353:             * This method was made public and static for utility.
354:             */
355:            static public boolean importable(Identifier id, Environment env) {
356:                if (!id.isInner()) {
357:                    return env.classExists(id);
358:                } else if (!env.classExists(id.getTopName())) {
359:                    return false;
360:                } else {
361:                    // load the top class and look inside it
362:                    try {
363:                        // There used to be a call to...
364:                        //    env.getClassDeclaration(id.getTopName());
365:                        // ...here.  It has been replaced with the
366:                        // two statements below.  These should be functionally
367:                        // the same except for the fact that
368:                        // getClassDefinitionNoCheck() does not call
369:                        // basicCheck().  This allows us to avoid a circular
370:                        // need to do basicChecking that can arise with
371:                        // certain patterns of importing and inheritance.
372:                        // This is a fix for a variant of bug 4086139.
373:                        //
374:                        // Note: the special case code in env.getClassDefinition()
375:                        // which handles inner class names is not replicated below.
376:                        // This should be okay, as we are looking up id.getTopName(),
377:                        // not id.
378:                        ClassDeclaration decl = env.getClassDeclaration(id
379:                                .getTopName());
380:                        ClassDefinition c = decl.getClassDefinitionNoCheck(env);
381:
382:                        return c.innerClassExists(id.getFlatName().getTail());
383:                    } catch (ClassNotFound ee) {
384:                        return false;
385:                    }
386:                }
387:            }
388:
389:            /**
390:             * Suppose a resolve() call has failed.
391:             * This routine can be used silently to give a reasonable
392:             * default qualification (the current package) to the identifier.
393:             * This decision is recorded for future reference.
394:             */
395:            public synchronized Identifier forceResolve(Environment env,
396:                    Identifier nm) {
397:                if (nm.isQualified())
398:                    return nm;
399:
400:                Identifier className = (Identifier) classes.get(nm);
401:                if (className != null) {
402:                    return className;
403:                }
404:
405:                className = Identifier.lookup(currentPackage, nm);
406:
407:                classes.put(nm, className);
408:                return className;
409:            }
410:
411:            /**
412:             * Add a class import
413:             */
414:            public synchronized void addClass(IdentifierToken t) {
415:                singles.addElement(t);
416:            }
417:
418:            // for compatibility
419:            public void addClass(Identifier nm) throws AmbiguousClass {
420:                addClass(new IdentifierToken(nm));
421:            }
422:
423:            /**
424:             * Add a package import, or perhaps an inner class scope.
425:             * Ignore any duplicate imports.
426:             */
427:            public synchronized void addPackage(IdentifierToken t) {
428:                final Identifier name = t.getName();
429:
430:                // If this is a duplicate import for the current package,
431:                // ignore it.
432:                if (name == currentPackage) {
433:                    return;
434:                }
435:
436:                // If this is a duplicate of a package which has already been
437:                // added to the list, ignore it.
438:                final int size = packages.size();
439:                for (int i = 0; i < size; i++) {
440:                    if (name == ((IdentifierToken) packages.elementAt(i))
441:                            .getName()) {
442:                        return;
443:                    }
444:                }
445:
446:                // Add the package to the list.
447:                packages.addElement(t);
448:            }
449:
450:            // for compatibility
451:            public void addPackage(Identifier id) {
452:                addPackage(new IdentifierToken(id));
453:            }
454:
455:            /**
456:             * Specify the current package with an IdentifierToken.
457:             */
458:            public synchronized void setCurrentPackage(IdentifierToken t) {
459:                currentPackage = t.getName();
460:                currentPackageWhere = t.getWhere();
461:            }
462:
463:            /**
464:             * Specify the current package
465:             */
466:            public synchronized void setCurrentPackage(Identifier id) {
467:                currentPackage = id;
468:            }
469:
470:            /**
471:             * Report the current package
472:             */
473:            public Identifier getCurrentPackage() {
474:                return currentPackage;
475:            }
476:
477:            /**
478:             * Return an unmodifiable list of IdentifierToken representing 
479:             * packages specified as imports.
480:             */
481:            public List getImportedPackages() {
482:                return Collections.unmodifiableList(packages);
483:            }
484:
485:            /**
486:             * Return an unmodifiable list of IdentifierToken representing 
487:             * classes specified as imports.
488:             */
489:            public List getImportedClasses() {
490:                return Collections.unmodifiableList(singles);
491:            }
492:
493:            /**
494:             * Extend an environment with my resolve() method.
495:             */
496:            public Environment newEnvironment(Environment env) {
497:                return new ImportEnvironment(env, this );
498:            }
499:        }
500:
501:        final class ImportEnvironment extends Environment {
502:            Imports imports;
503:
504:            ImportEnvironment(Environment env, Imports imports) {
505:                super (env, env.getSource());
506:                this .imports = imports;
507:            }
508:
509:            public Identifier resolve(Identifier nm) throws ClassNotFound {
510:                return imports.resolve(this , nm);
511:            }
512:
513:            public Imports getImports() {
514:                return imports;
515:            }
516:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.