/** * Initializes default class loader. It inherits from classloader, which was used to load this * task, therefore build-in classes and resources are loaded automatically. * * <p>Notice: task's classpath has priority over default classpath, therefore we are able to * easily override resources (templates) */ protected void initClassloader() { // NOTICE: we should use the same classloader, which was used to load this task // otherwise we won't be able to cast instances // (that were loaded via different class loaders) // we are introducting workaround, // that tries to add classpath for current task to original class loader // and stores original classpath // after the task is executed, classpath is restored ClassLoader classLoader = getClass().getClassLoader(); if (classLoader instanceof AntClassLoader) { // add defined classpath AntClassLoader antClassLoader = (AntClassLoader) classLoader; antClassLoader.setParentFirst(false); antClassLoader.setProject(getProject()); savedClasspath = antClassLoader.getClasspath(); Path cp = getClasspath(); // add defined classpath to original path cp.add(new Path(getProject(), savedClasspath)); antClassLoader.setClassPath(cp); } else { // create new class loader classLoader = new AntClassLoader(getClass().getClassLoader(), getProject(), getClasspath(), false); } // set this class loader as new class loader for whole thread // ContextClassLoader is used in StringTemplate's PathGroupLoader and other classes Thread.currentThread().setContextClassLoader(classLoader); }
/** * Main entry point for this task. It creates transformation specified by classname attribute, * passes all parameters and executes it. * * @throws BuildException if an error occured */ @Override public void execute() throws BuildException { if (getClassname() == null) { throw new BuildException("Classname of transformation is not set."); } if (getSrcFile() != null && getSrcDir() != null) { throw new BuildException("Both srcFile and srcDir were set."); } if (getDestFile() != null && getDestDir() != null) { throw new BuildException("Both destFile and destDir were set."); } if (!resources.isEmpty() && (getSrcFile() != null || getSrcDir() != null)) { throw new BuildException("Resources can't be combined with srcFile or srcDir."); } initClassloader(); try { TransformationLoader loader = new TransformationLoader(Thread.currentThread().getContextClassLoader()); Transformation transObj = null; try { transObj = loader.getInstance(getClassname()); } catch (InstantiationException ex) { throw new BuildException("Transformation couldn't be instanciated", ex); } catch (IllegalAccessException ex) { throw new BuildException("Transformation couldn't be accessed", ex); } if (transObj == null) { throw new BuildException("Transformation " + getClassname() + " couldn't be loaded"); } List<MappedFile> files = getMappedFiles(); if (files.isEmpty()) { log( "No files specified, " + transObj.getClass().getSimpleName() + " skipped", Project.MSG_INFO); return; } for (MappedFile mf : files) { log("Mapped file " + mf.getFrom() + " to " + mf.getTo(), Project.MSG_VERBOSE); } transObj.setParam("baseDir", getProject().getBaseDir().getPath()); transObj.setMappedFiles(files); transObj.setParams(parameters); for (String key : parameters.keySet()) log( "Parsed parameter " + key + " = " + parameters.get(key) + " (" + parameters.get(key).getClass().getName() + ")", Project.MSG_VERBOSE); try { log( "Executing transformation " + transObj.getClass().getSimpleName() + " on " + mappedFiles.size() + " files"); transObj.execute(); } catch (TransformationException ex) { log("Transformation has failed", ex, Project.MSG_ERR); if (isFailonerror()) { throw new BuildException("Transformation has failed.", ex); } } } finally { restoreClassloader(); } }