Source Code Cross Referenced for ComponentHelper.java in  » Build » ANT » org » apache » tools » ant » 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 » Build » ANT » org.apache.tools.ant 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         *
0017:         */
0018:
0019:        package org.apache.tools.ant;
0020:
0021:        import java.lang.reflect.Method;
0022:        import java.lang.reflect.Modifier;
0023:        import java.lang.reflect.InvocationTargetException;
0024:        import java.io.InputStream;
0025:        import java.io.IOException;
0026:        import java.io.File;
0027:        import java.io.StringWriter;
0028:        import java.io.PrintWriter;
0029:        import java.util.Enumeration;
0030:        import java.util.Hashtable;
0031:        import java.util.HashSet;
0032:        import java.util.Iterator;
0033:        import java.util.Properties;
0034:        import java.util.Set;
0035:        import java.util.Stack;
0036:
0037:        import org.apache.tools.ant.taskdefs.Typedef;
0038:        import org.apache.tools.ant.taskdefs.Definer;
0039:        import org.apache.tools.ant.launch.Launcher;
0040:        import org.apache.tools.ant.util.FileUtils;
0041:
0042:        /**
0043:         * Component creation and configuration.
0044:         *
0045:         * The class is based around handing component
0046:         * definitions in an AntTypeTable.
0047:         *
0048:         * The old task/type methods have been kept
0049:         * for backward compatibly.
0050:         * Project will just delegate its calls to this class.
0051:         *
0052:         * A very simple hook mechanism is provided that allows users to plug
0053:         * in custom code. It is also possible to replace the default behavior
0054:         * ( for example in an app embedding ant )
0055:         *
0056:         * @since Ant1.6
0057:         */
0058:        public class ComponentHelper {
0059:            /** Map from component name to anttypedefinition */
0060:            private AntTypeTable antTypeTable;
0061:
0062:            /** Map of tasks generated from antTypeTable */
0063:            private Hashtable taskClassDefinitions = new Hashtable();
0064:            /** flag to rebuild taskClassDefinitions */
0065:            private boolean rebuildTaskClassDefinitions = true;
0066:
0067:            /** Map of types generated from antTypeTable */
0068:            private Hashtable typeClassDefinitions = new Hashtable();
0069:            /** flag to rebuild typeClassDefinitions */
0070:            private boolean rebuildTypeClassDefinitions = true;
0071:
0072:            /** Set of namespaces that have been checked for antlibs */
0073:            private Set checkedNamespaces = new HashSet();
0074:
0075:            /**
0076:             * Stack of antlib contexts used to resolve definitions while
0077:             *   processing antlib
0078:             */
0079:            private Stack antLibStack = new Stack();
0080:            /** current antlib uri */
0081:            private String antLibCurrentUri = null;
0082:
0083:            /**
0084:             * this does not appear to be used anywhere in the Ant codebase
0085:             * even via its accessors
0086:             */
0087:            private ComponentHelper next;
0088:
0089:            /**
0090:             * Project that owns a component helper
0091:             */
0092:            private Project project;
0093:
0094:            /**
0095:             * Error string when the file taskdefs/defaults.properties cannot be found
0096:             */
0097:            private static final String ERROR_NO_TASK_LIST_LOAD = "Can't load default task list";
0098:            /**
0099:             * Error string when the typedefs/defaults.properties cannot be found
0100:             */
0101:            private static final String ERROR_NO_TYPE_LIST_LOAD = "Can't load default type list";
0102:
0103:            /**
0104:             * reference under which we register ourselves with a project -{@value}
0105:             */
0106:            public static final String COMPONENT_HELPER_REFERENCE = "ant.ComponentHelper";
0107:
0108:            /**
0109:             * string used to control build.syspath policy {@value}
0110:             */
0111:            private static final String BUILD_SYSCLASSPATH_ONLY = "only";
0112:
0113:            /**
0114:             * special name of ant's property task -{@value}. There is some
0115:             * contrived work here to enable this early.
0116:             */
0117:            private static final String ANT_PROPERTY_TASK = "property";
0118:
0119:            // {tasks, types}
0120:            private static Properties[] defaultDefinitions = new Properties[2];
0121:
0122:            /**
0123:             * Find a project component for a specific project, creating
0124:             * it if it does not exist.
0125:             * @param project the project.
0126:             * @return the project component for a specific project.
0127:             */
0128:            public static ComponentHelper getComponentHelper(Project project) {
0129:                if (project == null) {
0130:                    return null;
0131:                }
0132:                // Singleton for now, it may change ( per/classloader )
0133:                ComponentHelper ph = (ComponentHelper) project
0134:                        .getReference(COMPONENT_HELPER_REFERENCE);
0135:                if (ph != null) {
0136:                    return ph;
0137:                }
0138:                ph = new ComponentHelper();
0139:                ph.setProject(project);
0140:
0141:                project.addReference(COMPONENT_HELPER_REFERENCE, ph);
0142:                return ph;
0143:            }
0144:
0145:            /**
0146:             * Creates a new ComponentHelper instance.
0147:             */
0148:            protected ComponentHelper() {
0149:            }
0150:
0151:            /**
0152:             * Set the next chained component helper.
0153:             *
0154:             * @param next the next chained component helper.
0155:             */
0156:            public void setNext(ComponentHelper next) {
0157:                this .next = next;
0158:            }
0159:
0160:            /**
0161:             * Get the next chained component helper.
0162:             *
0163:             * @return the next chained component helper.
0164:             */
0165:            public ComponentHelper getNext() {
0166:                return next;
0167:            }
0168:
0169:            /**
0170:             * Sets the project for this component helper.
0171:             *
0172:             * @param project the project for this helper.
0173:             */
0174:            public void setProject(Project project) {
0175:                this .project = project;
0176:                antTypeTable = new AntTypeTable(project);
0177:            }
0178:
0179:            /**
0180:             * Used with creating child projects. Each child
0181:             * project inherits the component definitions
0182:             * from its parent.
0183:             * @param helper the component helper of the parent project.
0184:             */
0185:            public void initSubProject(ComponentHelper helper) {
0186:                // add the types of the parent project
0187:                AntTypeTable typeTable = helper.antTypeTable;
0188:                for (Iterator i = typeTable.values().iterator(); i.hasNext();) {
0189:                    AntTypeDefinition def = (AntTypeDefinition) i.next();
0190:                    antTypeTable.put(def.getName(), def);
0191:                }
0192:                // add the parsed namespaces of the parent project
0193:                for (Iterator i = helper.checkedNamespaces.iterator(); i
0194:                        .hasNext();) {
0195:                    checkedNamespaces.add(i.next());
0196:                }
0197:            }
0198:
0199:            /**
0200:             * Factory method to create the components.
0201:             *
0202:             * This should be called by UnknownElement.
0203:             *
0204:             * @param ue The Unknown Element creating this component.
0205:             * @param ns Namespace URI. Also available as ue.getNamespace().
0206:             * @param componentType The component type,
0207:             *                       Also available as ue.getComponentName().
0208:             * @return the created component.
0209:             * @throws BuildException if an error occurs.
0210:             */
0211:            public Object createComponent(UnknownElement ue, String ns,
0212:                    String componentType) throws BuildException {
0213:                Object component = createComponent(componentType);
0214:                if (component instanceof  Task) {
0215:                    Task task = (Task) component;
0216:                    task.setLocation(ue.getLocation());
0217:                    task.setTaskType(componentType);
0218:                    task.setTaskName(ue.getTaskName());
0219:                    task.setOwningTarget(ue.getOwningTarget());
0220:                    task.init();
0221:                }
0222:                return component;
0223:            }
0224:
0225:            /**
0226:             * Create an object for a component.
0227:             *
0228:             * @param componentName the name of the component, if
0229:             *                      the component is in a namespace, the
0230:             *                      name is prefixed with the namespace uri and ":".
0231:             * @return the class if found or null if not.
0232:             */
0233:            public Object createComponent(String componentName) {
0234:                AntTypeDefinition def = getDefinition(componentName);
0235:                return (def == null) ? null : def.create(project);
0236:            }
0237:
0238:            /**
0239:             * Return the class of the component name.
0240:             *
0241:             * @param componentName the name of the component, if
0242:             *                      the component is in a namespace, the
0243:             *                      name is prefixed with the namespace uri and ":".
0244:             * @return the class if found or null if not.
0245:             */
0246:            public Class getComponentClass(String componentName) {
0247:                AntTypeDefinition def = getDefinition(componentName);
0248:                return (def == null) ? null : def.getExposedClass(project);
0249:            }
0250:
0251:            /**
0252:             * Return the antTypeDefinition for a componentName.
0253:             * @param componentName the name of the component.
0254:             * @return the ant definition or null if not present.
0255:             */
0256:            public AntTypeDefinition getDefinition(String componentName) {
0257:                checkNamespace(componentName);
0258:                return antTypeTable.getDefinition(componentName);
0259:            }
0260:
0261:            /**
0262:             * This method is initialization code implementing the original ant component
0263:             * loading from /org/apache/tools/ant/taskdefs/default.properties
0264:             * and /org/apache/tools/ant/types/default.properties.
0265:             */
0266:            public void initDefaultDefinitions() {
0267:                initTasks();
0268:                initTypes();
0269:            }
0270:
0271:            /**
0272:             * Adds a new task definition to the project.
0273:             * Attempting to override an existing definition with an
0274:             * equivalent one (i.e. with the same classname) results in
0275:             * a verbose log message. Attempting to override an existing definition
0276:             * with a different one results in a warning log message.
0277:             *
0278:             * @param taskName The name of the task to add.
0279:             *                 Must not be <code>null</code>.
0280:             * @param taskClass The full name of the class implementing the task.
0281:             *                  Must not be <code>null</code>.
0282:             *
0283:             * @exception BuildException if the class is unsuitable for being an Ant
0284:             *                           task. An error level message is logged before
0285:             *                           this exception is thrown.
0286:             *
0287:             * @see #checkTaskClass(Class)
0288:             */
0289:            public void addTaskDefinition(String taskName, Class taskClass) {
0290:                checkTaskClass(taskClass);
0291:                AntTypeDefinition def = new AntTypeDefinition();
0292:                def.setName(taskName);
0293:                def.setClassLoader(taskClass.getClassLoader());
0294:                def.setClass(taskClass);
0295:                def.setAdapterClass(TaskAdapter.class);
0296:                def.setClassName(taskClass.getName());
0297:                def.setAdaptToClass(Task.class);
0298:                updateDataTypeDefinition(def);
0299:            }
0300:
0301:            /**
0302:             * Checks whether or not a class is suitable for serving as Ant task.
0303:             * Ant task implementation classes must be public, concrete, and have
0304:             * a no-arg constructor.
0305:             *
0306:             * @param taskClass The class to be checked.
0307:             *                  Must not be <code>null</code>.
0308:             *
0309:             * @exception BuildException if the class is unsuitable for being an Ant
0310:             *                           task. An error level message is logged before
0311:             *                           this exception is thrown.
0312:             */
0313:            public void checkTaskClass(final Class taskClass)
0314:                    throws BuildException {
0315:                if (!Modifier.isPublic(taskClass.getModifiers())) {
0316:                    final String message = taskClass + " is not public";
0317:                    project.log(message, Project.MSG_ERR);
0318:                    throw new BuildException(message);
0319:                }
0320:                if (Modifier.isAbstract(taskClass.getModifiers())) {
0321:                    final String message = taskClass + " is abstract";
0322:                    project.log(message, Project.MSG_ERR);
0323:                    throw new BuildException(message);
0324:                }
0325:                try {
0326:                    taskClass.getConstructor((Class[]) null);
0327:                    // don't have to check for public, since
0328:                    // getConstructor finds public constructors only.
0329:                } catch (NoSuchMethodException e) {
0330:                    final String message = "No public no-arg constructor in "
0331:                            + taskClass;
0332:                    project.log(message, Project.MSG_ERR);
0333:                    throw new BuildException(message);
0334:                }
0335:                if (!Task.class.isAssignableFrom(taskClass)) {
0336:                    TaskAdapter.checkTaskClass(taskClass, project);
0337:                }
0338:            }
0339:
0340:            /**
0341:             * Returns the current task definition hashtable. The returned hashtable is
0342:             * "live" and so should not be modified.
0343:             *
0344:             * @return a map of from task name to implementing class
0345:             *         (String to Class).
0346:             */
0347:            public Hashtable getTaskDefinitions() {
0348:                synchronized (taskClassDefinitions) {
0349:                    synchronized (antTypeTable) {
0350:                        if (rebuildTaskClassDefinitions) {
0351:                            taskClassDefinitions.clear();
0352:                            for (Iterator i = antTypeTable.keySet().iterator(); i
0353:                                    .hasNext();) {
0354:                                String name = (String) i.next();
0355:                                Class clazz = antTypeTable
0356:                                        .getExposedClass(name);
0357:                                if (clazz == null) {
0358:                                    continue;
0359:                                }
0360:                                if (Task.class.isAssignableFrom(clazz)) {
0361:                                    taskClassDefinitions.put(name, antTypeTable
0362:                                            .getTypeClass(name));
0363:                                }
0364:                            }
0365:                            rebuildTaskClassDefinitions = false;
0366:                        }
0367:                    }
0368:                }
0369:                return taskClassDefinitions;
0370:            }
0371:
0372:            /**
0373:             * Returns the current type definition hashtable. The returned hashtable is
0374:             * "live" and so should not be modified.
0375:             *
0376:             * @return a map of from type name to implementing class
0377:             *         (String to Class).
0378:             */
0379:            public Hashtable getDataTypeDefinitions() {
0380:                synchronized (typeClassDefinitions) {
0381:                    synchronized (antTypeTable) {
0382:                        if (rebuildTypeClassDefinitions) {
0383:                            typeClassDefinitions.clear();
0384:                            for (Iterator i = antTypeTable.keySet().iterator(); i
0385:                                    .hasNext();) {
0386:                                String name = (String) i.next();
0387:                                Class clazz = antTypeTable
0388:                                        .getExposedClass(name);
0389:                                if (clazz == null) {
0390:                                    continue;
0391:                                }
0392:                                if (!(Task.class.isAssignableFrom(clazz))) {
0393:                                    typeClassDefinitions.put(name, antTypeTable
0394:                                            .getTypeClass(name));
0395:                                }
0396:                            }
0397:                            rebuildTypeClassDefinitions = false;
0398:                        }
0399:                    }
0400:                }
0401:                return typeClassDefinitions;
0402:            }
0403:
0404:            /**
0405:             * Adds a new datatype definition.
0406:             * Attempting to override an existing definition with an
0407:             * equivalent one (i.e. with the same classname) results in
0408:             * a verbose log message. Attempting to override an existing definition
0409:             * with a different one results in a warning log message, but the
0410:             * definition is changed.
0411:             *
0412:             * @param typeName The name of the datatype.
0413:             *                 Must not be <code>null</code>.
0414:             * @param typeClass The full name of the class implementing the datatype.
0415:             *                  Must not be <code>null</code>.
0416:             */
0417:            public void addDataTypeDefinition(String typeName, Class typeClass) {
0418:                AntTypeDefinition def = new AntTypeDefinition();
0419:                def.setName(typeName);
0420:                def.setClass(typeClass);
0421:                updateDataTypeDefinition(def);
0422:                project.log(" +User datatype: " + typeName + "     "
0423:                        + typeClass.getName(), Project.MSG_DEBUG);
0424:            }
0425:
0426:            /**
0427:             * Describe <code>addDataTypeDefinition</code> method here.
0428:             *
0429:             * @param def an <code>AntTypeDefinition</code> value.
0430:             */
0431:            public void addDataTypeDefinition(AntTypeDefinition def) {
0432:                updateDataTypeDefinition(def);
0433:            }
0434:
0435:            /**
0436:             * Returns the current datatype definition hashtable. The returned
0437:             * hashtable is "live" and so should not be modified.
0438:             *
0439:             * @return a map of from datatype name to implementing class
0440:             *         (String to Class).
0441:             */
0442:            public Hashtable getAntTypeTable() {
0443:                return antTypeTable;
0444:            }
0445:
0446:            /**
0447:             * Creates a new instance of a task.
0448:             *
0449:             *  Called from Project.createTask(), which can be called by tasks.
0450:             *
0451:             * @param taskType The name of the task to create an instance of.
0452:             *                 Must not be <code>null</code>.
0453:             *
0454:             * @return an instance of the specified task, or <code>null</code> if
0455:             *         the task name is not recognised.
0456:             *
0457:             * @exception BuildException if the task name is recognised but task
0458:             *                           creation fails.
0459:             */
0460:            public Task createTask(String taskType) throws BuildException {
0461:                Task task = createNewTask(taskType);
0462:                if (task == null && taskType.equals(ANT_PROPERTY_TASK)) {
0463:                    // quick fix for Ant.java use of property before
0464:                    // initializing the project
0465:                    addTaskDefinition(ANT_PROPERTY_TASK,
0466:                            org.apache.tools.ant.taskdefs.Property.class);
0467:                    task = createNewTask(taskType);
0468:                }
0469:                return task;
0470:            }
0471:
0472:            /**
0473:             * Creates a new instance of a task.
0474:             * @since ant1.6
0475:             * @param taskType The name of the task to create an instance of.
0476:             *                 Must not be <code>null</code>.
0477:             *
0478:             * @return an instance of the specified task, or <code>null</code> if
0479:             *         the task name is not recognised.
0480:             *
0481:             * @exception BuildException if the task name is recognised but task
0482:             *                           creation fails.
0483:             */
0484:            private Task createNewTask(String taskType) throws BuildException {
0485:                Class c = getComponentClass(taskType);
0486:                if (c == null || !(Task.class.isAssignableFrom(c))) {
0487:                    return null;
0488:                }
0489:                Object obj = createComponent(taskType);
0490:                if (obj == null) {
0491:                    return null;
0492:                }
0493:                if (!(obj instanceof  Task)) {
0494:                    throw new BuildException("Expected a Task from '"
0495:                            + taskType + "' but got an instance of "
0496:                            + obj.getClass().getName() + " instead");
0497:                }
0498:                Task task = (Task) obj;
0499:                task.setTaskType(taskType);
0500:
0501:                // set default value, can be changed by the user
0502:                task.setTaskName(taskType);
0503:
0504:                project.log("   +Task: " + taskType, Project.MSG_DEBUG);
0505:                return task;
0506:            }
0507:
0508:            /**
0509:             * Creates a new instance of a data type.
0510:             *
0511:             * @param typeName The name of the data type to create an instance of.
0512:             *                 Must not be <code>null</code>.
0513:             *
0514:             * @return an instance of the specified data type, or <code>null</code> if
0515:             *         the data type name is not recognised.
0516:             *
0517:             * @exception BuildException if the data type name is recognised but
0518:             *                           instance creation fails.
0519:             */
0520:            public Object createDataType(String typeName) throws BuildException {
0521:                return createComponent(typeName);
0522:            }
0523:
0524:            /**
0525:             * Returns a description of the type of the given element.
0526:             * <p>
0527:             * This is useful for logging purposes.
0528:             *
0529:             * @param element The element to describe.
0530:             *                Must not be <code>null</code>.
0531:             *
0532:             * @return a description of the element type.
0533:             *
0534:             * @since Ant 1.6
0535:             */
0536:            public String getElementName(Object element) {
0537:                return getElementName(element, false);
0538:            }
0539:
0540:            /**
0541:             * Returns a description of the type of the given element.
0542:             * <p>
0543:             * This is useful for logging purposes.
0544:             *
0545:             * @param o     The element to describe.
0546:             *              Must not be <code>null</code>.
0547:             * @param brief whether to use a brief description.
0548:             * @return a description of the element type.
0549:             *
0550:             * @since Ant 1.7
0551:             */
0552:            public String getElementName(Object o, boolean brief) {
0553:                //  PR: I do not know what to do if the object class
0554:                //      has multiple defines
0555:                //      but this is for logging only...
0556:                Class elementClass = o.getClass();
0557:                String elementClassname = elementClass.getName();
0558:                for (Iterator i = antTypeTable.values().iterator(); i.hasNext();) {
0559:                    AntTypeDefinition def = (AntTypeDefinition) i.next();
0560:                    if (elementClassname.equals(def.getClassName())
0561:                            && (elementClass == def.getExposedClass(project))) {
0562:                        String name = def.getName();
0563:                        return brief ? name : "The <" + name + "> type";
0564:                    }
0565:                }
0566:                return getUnmappedElementName(o.getClass(), brief);
0567:            }
0568:
0569:            /**
0570:             * Convenient way to get some element name even when you may not have a
0571:             * Project context.
0572:             * @param p       The optional Project instance.
0573:             * @param o       The element to describe.
0574:             *                Must not be <code>null</code>.
0575:             * @param brief   whether to use a brief description.
0576:             * @return a description of the element type.
0577:             * @since Ant 1.7
0578:             */
0579:            public static String getElementName(Project p, Object o,
0580:                    boolean brief) {
0581:                if (p == null) {
0582:                    p = getProject(o);
0583:                }
0584:                return p == null ? getUnmappedElementName(o.getClass(), brief)
0585:                        : getComponentHelper(p).getElementName(o, brief);
0586:            }
0587:
0588:            private static String getUnmappedElementName(Class c, boolean brief) {
0589:                if (brief) {
0590:                    String name = c.getName();
0591:                    return name.substring(name.lastIndexOf('.') + 1);
0592:                }
0593:                return c.toString();
0594:            }
0595:
0596:            private static Project getProject(Object o) {
0597:                if (o instanceof  ProjectComponent) {
0598:                    return ((ProjectComponent) o).getProject();
0599:                }
0600:                try {
0601:                    Method m = o.getClass().getMethod("getProject",
0602:                            (Class[]) null);
0603:                    if (Project.class == m.getReturnType()) {
0604:                        return (Project) m.invoke(o, (Object[]) null);
0605:                    }
0606:                } catch (Exception e) {
0607:                    //too bad
0608:                }
0609:                return null;
0610:            }
0611:
0612:            /**
0613:             * Check if definition is a valid definition--it may be a
0614:             * definition of an optional task that does not exist.
0615:             * @param def the definition to test.
0616:             * @return true if exposed type of definition is present.
0617:             */
0618:            private boolean validDefinition(AntTypeDefinition def) {
0619:                return !(def.getTypeClass(project) == null || def
0620:                        .getExposedClass(project) == null);
0621:            }
0622:
0623:            /**
0624:             * Check if two definitions are the same.
0625:             * @param def  the new definition.
0626:             * @param old the old definition.
0627:             * @return true if the two definitions are the same.
0628:             */
0629:            private boolean sameDefinition(AntTypeDefinition def,
0630:                    AntTypeDefinition old) {
0631:                boolean defValid = validDefinition(def);
0632:                boolean sameValidity = (defValid == validDefinition(old));
0633:                //must have same validity; then if they are valid they must also be the same:
0634:                return sameValidity
0635:                        && (!defValid || def.sameDefinition(old, project));
0636:            }
0637:
0638:            /**
0639:             * Update the component definition table with a new or
0640:             * modified definition.
0641:             * @param def the definition to update or insert.
0642:             */
0643:            private void updateDataTypeDefinition(AntTypeDefinition def) {
0644:                String name = def.getName();
0645:                synchronized (antTypeTable) {
0646:                    rebuildTaskClassDefinitions = true;
0647:                    rebuildTypeClassDefinitions = true;
0648:                    AntTypeDefinition old = antTypeTable.getDefinition(name);
0649:                    if (old != null) {
0650:                        if (sameDefinition(def, old)) {
0651:                            return;
0652:                        }
0653:                        Class oldClass = antTypeTable.getExposedClass(name);
0654:                        boolean isTask = (oldClass != null && Task.class
0655:                                .isAssignableFrom(oldClass));
0656:                        project
0657:                                .log("Trying to override old definition of "
0658:                                        + (isTask ? "task " : "datatype ")
0659:                                        + name, (def.similarDefinition(old,
0660:                                        project)) ? Project.MSG_VERBOSE
0661:                                        : Project.MSG_WARN);
0662:                    }
0663:                    project.log(
0664:                            " +Datatype " + name + " " + def.getClassName(),
0665:                            Project.MSG_DEBUG);
0666:                    antTypeTable.put(name, def);
0667:                }
0668:            }
0669:
0670:            /**
0671:             * Called at the start of processing an antlib.
0672:             * @param uri the uri that is associated with this antlib.
0673:             */
0674:            public void enterAntLib(String uri) {
0675:                antLibCurrentUri = uri;
0676:                antLibStack.push(uri);
0677:            }
0678:
0679:            /**
0680:             * @return the current antlib uri.
0681:             */
0682:            public String getCurrentAntlibUri() {
0683:                return antLibCurrentUri;
0684:            }
0685:
0686:            /**
0687:             * Called at the end of processing an antlib.
0688:             */
0689:            public void exitAntLib() {
0690:                antLibStack.pop();
0691:                antLibCurrentUri = (antLibStack.size() == 0) ? null
0692:                        : (String) antLibStack.peek();
0693:            }
0694:
0695:            /**
0696:             * Load ant's tasks.
0697:             */
0698:            private void initTasks() {
0699:                ClassLoader classLoader = getClassLoader(null);
0700:                Properties props = getDefaultDefinitions(false);
0701:                Enumeration e = props.propertyNames();
0702:                while (e.hasMoreElements()) {
0703:                    String name = (String) e.nextElement();
0704:                    String className = props.getProperty(name);
0705:                    AntTypeDefinition def = new AntTypeDefinition();
0706:                    def.setName(name);
0707:                    def.setClassName(className);
0708:                    def.setClassLoader(classLoader);
0709:                    def.setAdaptToClass(Task.class);
0710:                    def.setAdapterClass(TaskAdapter.class);
0711:                    antTypeTable.put(name, def);
0712:                }
0713:            }
0714:
0715:            private ClassLoader getClassLoader(ClassLoader classLoader) {
0716:                String buildSysclasspath = project
0717:                        .getProperty(MagicNames.BUILD_SYSCLASSPATH);
0718:                if (project.getCoreLoader() != null
0719:                        && !(BUILD_SYSCLASSPATH_ONLY.equals(buildSysclasspath))) {
0720:                    classLoader = project.getCoreLoader();
0721:                }
0722:                return classLoader;
0723:            }
0724:
0725:            /**
0726:             * Load default task or type definitions - just the names,
0727:             *  no class loading.
0728:             * Caches results between calls to reduce overhead.
0729:             * @param type true for typedefs, false for taskdefs
0730:             * @return a mapping from definition names to class names
0731:             * @throws BuildException if there was some problem loading
0732:             *                        or parsing the definitions list
0733:             */
0734:            private static synchronized Properties getDefaultDefinitions(
0735:                    boolean type) throws BuildException {
0736:                int idx = type ? 1 : 0;
0737:                if (defaultDefinitions[idx] == null) {
0738:                    String resource = type ? MagicNames.TYPEDEFS_PROPERTIES_RESOURCE
0739:                            : MagicNames.TASKDEF_PROPERTIES_RESOURCE;
0740:                    String errorString = type ? ERROR_NO_TYPE_LIST_LOAD
0741:                            : ERROR_NO_TASK_LIST_LOAD;
0742:                    InputStream in = null;
0743:                    try {
0744:                        in = ComponentHelper.class
0745:                                .getResourceAsStream(resource);
0746:                        if (in == null) {
0747:                            throw new BuildException(errorString);
0748:                        }
0749:                        Properties p = new Properties();
0750:                        p.load(in);
0751:                        defaultDefinitions[idx] = p;
0752:                    } catch (IOException e) {
0753:                        throw new BuildException(errorString, e);
0754:                    } finally {
0755:                        FileUtils.close(in);
0756:                    }
0757:                }
0758:                return defaultDefinitions[idx];
0759:            }
0760:
0761:            /**
0762:             * Load ant's datatypes.
0763:             */
0764:            private void initTypes() {
0765:                ClassLoader classLoader = getClassLoader(null);
0766:                Properties props = getDefaultDefinitions(true);
0767:                Enumeration e = props.propertyNames();
0768:                while (e.hasMoreElements()) {
0769:                    String name = (String) e.nextElement();
0770:                    String className = props.getProperty(name);
0771:                    AntTypeDefinition def = new AntTypeDefinition();
0772:                    def.setName(name);
0773:                    def.setClassName(className);
0774:                    def.setClassLoader(classLoader);
0775:                    antTypeTable.put(name, def);
0776:                }
0777:            }
0778:
0779:            /**
0780:             * Called for each component name, check if the
0781:             * associated URI has been examined for antlibs.
0782:             */
0783:            private synchronized void checkNamespace(String componentName) {
0784:                String uri = ProjectHelper
0785:                        .extractUriFromComponentName(componentName);
0786:                if ("".equals(uri)) {
0787:                    uri = ProjectHelper.ANT_CORE_URI;
0788:                }
0789:                if (!uri.startsWith(ProjectHelper.ANTLIB_URI)) {
0790:                    return; // namespace that does not contain antlib
0791:                }
0792:                if (checkedNamespaces.contains(uri)) {
0793:                    return; // Already processed
0794:                }
0795:                checkedNamespaces.add(uri);
0796:                Typedef definer = new Typedef();
0797:                definer.setProject(project);
0798:                definer.init();
0799:                definer.setURI(uri);
0800:                //there to stop error messages being "null"
0801:                definer.setTaskName(uri);
0802:                //if this is left out, bad things happen. like all build files break
0803:                //on the first element encountered.
0804:                definer.setResource(Definer.makeResourceFromURI(uri));
0805:                // a fishing expedition :- ignore errors if antlib not present
0806:                definer.setOnError(new Typedef.OnError(
0807:                        Typedef.OnError.POLICY_IGNORE));
0808:                definer.execute();
0809:            }
0810:
0811:            /**
0812:             * Handler called to do decent diagnosis on instantiation failure.
0813:             * @param componentName component name.
0814:             * @param type component type, used in error messages
0815:             * @return a string containing as much diagnostics info as possible.
0816:             */
0817:            public String diagnoseCreationFailure(String componentName,
0818:                    String type) {
0819:                StringWriter errorText = new StringWriter();
0820:                PrintWriter out = new PrintWriter(errorText);
0821:                out.println("Problem: failed to create " + type + " "
0822:                        + componentName);
0823:                //class of problem
0824:                boolean lowlevel = false;
0825:                boolean jars = false;
0826:                boolean definitions = false;
0827:                boolean antTask;
0828:                String home = System.getProperty(Launcher.USER_HOMEDIR);
0829:                File libDir = new File(home, Launcher.USER_LIBDIR);
0830:                String antHomeLib;
0831:                boolean probablyIDE = false;
0832:                String anthome = System.getProperty(MagicNames.ANT_HOME);
0833:                if (anthome != null) {
0834:                    File antHomeLibDir = new File(anthome, "lib");
0835:                    antHomeLib = antHomeLibDir.getAbsolutePath();
0836:                } else {
0837:                    //running under an IDE that doesn't set ANT_HOME
0838:                    probablyIDE = true;
0839:                    antHomeLib = "ANT_HOME" + File.separatorChar + "lib";
0840:                }
0841:                StringBuffer dirListingText = new StringBuffer();
0842:                final String tab = "        -";
0843:                dirListingText.append(tab);
0844:                dirListingText.append(antHomeLib);
0845:                dirListingText.append('\n');
0846:                if (probablyIDE) {
0847:                    dirListingText.append(tab);
0848:                    dirListingText.append("the IDE Ant configuration dialogs");
0849:                } else {
0850:                    dirListingText.append(tab);
0851:                    dirListingText.append(libDir);
0852:                    dirListingText.append('\n');
0853:                    dirListingText.append(tab);
0854:                    dirListingText
0855:                            .append("a directory added on the command line with the -lib argument");
0856:                }
0857:
0858:                String dirListing = dirListingText.toString();
0859:
0860:                //look up the name
0861:                AntTypeDefinition def = getDefinition(componentName);
0862:                if (def == null) {
0863:                    //not a known type
0864:                    boolean isAntlib = componentName
0865:                            .indexOf(MagicNames.ANTLIB_PREFIX) == 0;
0866:                    out.println("Cause: The name is undefined.");
0867:                    out.println("Action: Check the spelling.");
0868:                    out
0869:                            .println("Action: Check that any custom tasks/types have been declared.");
0870:                    out.println("Action: Check that any <presetdef>/<macrodef>"
0871:                            + " declarations have taken place.");
0872:                    if (isAntlib) {
0873:                        out.println();
0874:                        out
0875:                                .println("This appears to be an antlib declaration. ");
0876:                        out
0877:                                .println("Action: Check that the implementing library exists in one of:");
0878:                        out.println(dirListing);
0879:                    }
0880:                    definitions = true;
0881:                } else {
0882:                    //we are defined, so it is an instantiation problem
0883:                    final String classname = def.getClassName();
0884:                    antTask = classname.startsWith("org.apache.tools.ant.");
0885:                    boolean optional = classname
0886:                            .startsWith("org.apache.tools.ant.taskdefs.optional");
0887:                    optional |= classname
0888:                            .startsWith("org.apache.tools.ant.types.optional");
0889:
0890:                    //start with instantiating the class.
0891:                    Class clazz = null;
0892:                    try {
0893:                        clazz = def.innerGetTypeClass();
0894:                    } catch (ClassNotFoundException e) {
0895:                        out.println("Cause: the class " + classname
0896:                                + " was not found.");
0897:                        jars = true;
0898:                        if (optional) {
0899:                            out
0900:                                    .println("        This looks like one of Ant's optional components.");
0901:                            out
0902:                                    .println("Action: Check that the appropriate optional JAR exists in");
0903:                            out.println(dirListing);
0904:                        } else {
0905:                            out
0906:                                    .println("Action: Check that the component has been correctly declared");
0907:                            out
0908:                                    .println("        and that the implementing JAR is in one of:");
0909:                            out.println(dirListing);
0910:                            definitions = true;
0911:                        }
0912:                    } catch (NoClassDefFoundError ncdfe) {
0913:                        jars = true;
0914:                        out.println("Cause: Could not load a dependent class "
0915:                                + ncdfe.getMessage());
0916:                        if (optional) {
0917:                            out
0918:                                    .println("       It is not enough to have Ant's optional JARs");
0919:                            out
0920:                                    .println("       you need the JAR files that the"
0921:                                            + " optional tasks depend upon.");
0922:                            out
0923:                                    .println("       Ant's optional task dependencies are"
0924:                                            + " listed in the manual.");
0925:                        } else {
0926:                            out
0927:                                    .println("       This class may be in a separate JAR"
0928:                                            + " that is not installed.");
0929:                        }
0930:                        out
0931:                                .println("Action: Determine what extra JAR files are"
0932:                                        + " needed, and place them in one of:");
0933:                        out.println(dirListing);
0934:                    }
0935:                    //here we successfully loaded the class or failed.
0936:                    if (clazz != null) {
0937:                        //success: proceed with more steps
0938:                        try {
0939:                            def.innerCreateAndSet(clazz, project);
0940:                            //hey, there is nothing wrong with us
0941:                            out.println("The component could be instantiated.");
0942:                        } catch (NoSuchMethodException e) {
0943:                            lowlevel = true;
0944:                            out.println("Cause: The class " + classname
0945:                                    + " has no compatible constructor.");
0946:
0947:                        } catch (InstantiationException e) {
0948:                            lowlevel = true;
0949:                            out
0950:                                    .println("Cause: The class "
0951:                                            + classname
0952:                                            + " is abstract and cannot be instantiated.");
0953:                        } catch (IllegalAccessException e) {
0954:                            lowlevel = true;
0955:                            out.println("Cause: The constructor for "
0956:                                    + classname
0957:                                    + " is private and cannot be invoked.");
0958:                        } catch (InvocationTargetException ex) {
0959:                            lowlevel = true;
0960:                            Throwable t = ex.getTargetException();
0961:                            out
0962:                                    .println("Cause: The constructor threw the exception");
0963:                            out.println(t.toString());
0964:                            t.printStackTrace(out);
0965:                        } catch (NoClassDefFoundError ncdfe) {
0966:                            jars = true;
0967:                            out.println("Cause:  A class needed by class "
0968:                                    + classname + " cannot be found: ");
0969:                            out.println("       " + ncdfe.getMessage());
0970:                            out
0971:                                    .println("Action: Determine what extra JAR files are"
0972:                                            + " needed, and place them in:");
0973:                            out.println(dirListing);
0974:                        }
0975:                    }
0976:                    out.println();
0977:                    out.println("Do not panic, this is a common problem.");
0978:                    if (definitions) {
0979:                        out
0980:                                .println("It may just be a typographical error in the build file "
0981:                                        + "or the task/type declaration.");
0982:                    }
0983:                    if (jars) {
0984:                        out.println("The commonest cause is a missing JAR.");
0985:                    }
0986:                    if (lowlevel) {
0987:                        out
0988:                                .println("This is quite a low level problem, which may need "
0989:                                        + "consultation with the author of the task.");
0990:                        if (antTask) {
0991:                            out
0992:                                    .println("This may be the Ant team. Please file a "
0993:                                            + "defect or contact the developer team.");
0994:                        } else {
0995:                            out
0996:                                    .println("This does not appear to be a task bundled with Ant.");
0997:                            out
0998:                                    .println("Please take it up with the supplier of the third-party "
0999:                                            + type + ".");
1000:                            out
1001:                                    .println("If you have written it yourself, you probably have a bug to fix.");
1002:                        }
1003:                    } else {
1004:                        out.println();
1005:                        out
1006:                                .println("This is not a bug; it is a configuration problem");
1007:                    }
1008:                }
1009:                out.flush();
1010:                out.close();
1011:                return errorText.toString();
1012:            }
1013:
1014:            /**
1015:             * Map that contains the component definitions.
1016:             */
1017:            private static class AntTypeTable extends Hashtable {
1018:                private Project project;
1019:
1020:                AntTypeTable(Project project) {
1021:                    this .project = project;
1022:                }
1023:
1024:                AntTypeDefinition getDefinition(String key) {
1025:                    return (AntTypeDefinition) (super .get(key));
1026:                }
1027:
1028:                public Object get(Object key) {
1029:                    return getTypeClass((String) key);
1030:                }
1031:
1032:                Object create(String name) {
1033:                    AntTypeDefinition def = getDefinition(name);
1034:                    return (def == null) ? null : def.create(project);
1035:                }
1036:
1037:                Class getTypeClass(String name) {
1038:                    AntTypeDefinition def = getDefinition(name);
1039:                    return (def == null) ? null : def.getTypeClass(project);
1040:                }
1041:
1042:                Class getExposedClass(String name) {
1043:                    AntTypeDefinition def = getDefinition(name);
1044:                    return (def == null) ? null : def.getExposedClass(project);
1045:                }
1046:
1047:                public boolean contains(Object clazz) {
1048:                    boolean found = false;
1049:                    if (clazz instanceof  Class) {
1050:                        for (Iterator i = values().iterator(); i.hasNext()
1051:                                && !found;) {
1052:                            found |= (((AntTypeDefinition) (i.next()))
1053:                                    .getExposedClass(project) == clazz);
1054:                        }
1055:                    }
1056:                    return found;
1057:                }
1058:
1059:                public boolean containsValue(Object value) {
1060:                    return contains(value);
1061:                }
1062:            }
1063:
1064:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.