ASF Bugzilla – Attachment 17830 Details for
Bug 38844
ProjectHelper implementation that avoids re-parsing build.xml files
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
An implementation of ProjectHelper that avoids parsing of build.xml files.
CachingProjectHelper.java (text/plain), 9.75 KB, created by
David Green
on 2006-03-03 19:29:49 UTC
(
hide
)
Description:
An implementation of ProjectHelper that avoids parsing of build.xml files.
Filename:
MIME Type:
Creator:
David Green
Created:
2006-03-03 19:29:49 UTC
Size:
9.75 KB
patch
obsolete
>package com.maketechnologies.tools.rde.compiler.ant; > >import java.io.BufferedInputStream; >import java.io.File; >import java.io.FileInputStream; >import java.io.FileNotFoundException; >import java.io.IOException; >import java.io.InputStream; >import java.io.UnsupportedEncodingException; >import java.lang.reflect.InvocationHandler; >import java.lang.reflect.Method; >import java.lang.reflect.Proxy; >import java.net.URL; >import java.util.ArrayList; >import java.util.List; >import java.util.Map; >import java.util.concurrent.ConcurrentHashMap; > >import org.apache.tools.ant.BuildException; >import org.apache.tools.ant.Location; >import org.apache.tools.ant.Project; >import org.apache.tools.ant.helper.AntXMLContext; >import org.apache.tools.ant.helper.ProjectHelper2; >import org.apache.tools.ant.util.FileUtils; >import org.apache.tools.ant.util.JAXPUtils; >import org.xml.sax.Attributes; >import org.xml.sax.ContentHandler; >import org.xml.sax.DTDHandler; >import org.xml.sax.EntityResolver; >import org.xml.sax.ErrorHandler; >import org.xml.sax.InputSource; >import org.xml.sax.Locator; >import org.xml.sax.SAXException; >import org.xml.sax.SAXParseException; >import org.xml.sax.XMLReader; >import org.xml.sax.ext.Locator2; >import org.xml.sax.ext.Locator2Impl; >import org.xml.sax.helpers.AttributesImpl; >import org.xml.sax.helpers.LocatorImpl; > >/** > * A project helper that caches the results of parsing Ant files, so that > * <code><ant/></code> and <code><antcall/></code> don't need to > * re-parse the project file. > * > * @author dgreen > * > */ >public class CachingProjectHelper extends ProjectHelper2 { > > private static final Class[] DEFAULT_HANDLER_INTERFACES = new Class[] { EntityResolver.class, DTDHandler.class, ContentHandler.class, ErrorHandler.class }; > > private static FileUtils fileUtils = FileUtils.newFileUtils(); > > private static Map<File, Recording> _recordings = new ConcurrentHashMap<File, Recording>(); > > private static class RecordedEvent { > > private Method _method; > > private Object[] _args; > > private Throwable _throw; > > public RecordedEvent(Method method, Object[] args) { > _method = method; > _args = args; > if (_args != null && _args.length == 1 && _args[0] instanceof SAXParseException && method.getName().equals("fatalError")) { > _throw = (SAXParseException) args[0]; > } > } > > public void playback(Object target) throws Throwable { >// System.out.print("Playback " + _method.getName() + " values="); >// if (_args != null) { >// int x = 0; >// for (Object o : _args) { >// if (x > 0) { >// System.out.print(", "); >// } >// ++x; >// System.out.print(o); >// } >// } >// System.out.println(); > _method.invoke(target, _args); > if (_throw != null) { > throw _throw; > } > } > } > > private static class Recording { > private static final Integer ZERO = new Integer(0); > private List<RecordedEvent> _recordedEvents = new ArrayList<RecordedEvent>(500); > > public void record(Method method, Object[] args) { > convertArgs(args); > _recordedEvents.add(new RecordedEvent(method, args)); > } > > public void playback(Object target) throws Throwable { > try { > for (RecordedEvent event : _recordedEvents) { > event.playback(target); > } > } catch (java.lang.reflect.InvocationTargetException ite) { > throw ite.getCause(); > } > } > > private void convertArgs(Object[] args) { > if (args != null) { > if (args.length == 3 && args[0] instanceof char[] && args[1] instanceof Integer && args[2] instanceof Integer) { > int length = ((Integer)args[2]).intValue(); > int start = ((Integer)args[1]).intValue(); > char[] buf = new char[length]; > System.arraycopy(args[0], start, buf, 0, length); > args[0] = buf; > args[1] = ZERO; > } else { > for (int x = 0; x < args.length; ++x) { > if (args[x] instanceof Locator2) { > args[x] = new Locator2Impl((Locator) args[x]); > } else if (args[x] instanceof Locator) { > args[x] = new LocatorImpl((Locator) args[x]); > } else if (args[x] instanceof Attributes) { > args[x] = new AttributesImpl((Attributes) args[x]); > } > } > } > } > } > > } > > private static class RecordingHandler implements InvocationHandler { > private AntXMLContext context; > > private Recording _recording = new Recording(); > > private RecordingHandler(AntXMLContext context) { > this.context = context; > } > > public Recording getRecording() { > return _recording; > } > > public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { > if (method.getName().equals("resolveEntity")) { > return resolveEntity((String) args[0], (String) args[1]); > } else { > _recording.record(method, args); > return null; > } > } > > public InputSource resolveEntity(String publicId, String systemId) { > > context.getProject().log("resolving systemId: " + systemId, Project.MSG_VERBOSE); > > if (systemId.startsWith("file:")) { > String path = fileUtils.fromURI(systemId); > > File file = new File(path); > if (!file.isAbsolute()) { > file = fileUtils.resolveFile(context.getBuildFileParent(), path); > } > try { > InputSource inputSource = new InputSource(new FileInputStream(file)); > inputSource.setSystemId(fileUtils.toURI(file.getAbsolutePath())); > return inputSource; > } catch (FileNotFoundException fne) { > context.getProject().log(file.getAbsolutePath() + " could not be found", Project.MSG_WARN); > } > > } > // use default if not file or file not found > return null; > } > > } > > public CachingProjectHelper() { > > } > > private Recording createRecording(File buildFile, Project project, AntXMLContext context) throws BuildException { > > InputStream inputStream = null; > InputSource inputSource = null; > > try { > /** > * SAX 2 style parser used to parse the given file. > */ > XMLReader parser = JAXPUtils.getNamespaceXMLReader(); > > String uri = null; > uri = fileUtils.toURI(buildFile.getAbsolutePath()); > inputStream = new BufferedInputStream(new FileInputStream(buildFile)); > > inputSource = new InputSource(inputStream); > if (uri != null) { > inputSource.setSystemId(uri); > } > project.log("parsing buildfile " + buildFile.getName() + " with URI = " + uri, Project.MSG_VERBOSE); > > RecordingHandler recordingHandler = new RecordingHandler(context); > Object handler = Proxy.newProxyInstance(recordingHandler.getClass().getClassLoader(), DEFAULT_HANDLER_INTERFACES, recordingHandler); > > parser.setContentHandler((ContentHandler) handler); > parser.setEntityResolver((EntityResolver) handler); > parser.setErrorHandler((ErrorHandler) handler); > parser.setDTDHandler((DTDHandler) handler); > parser.parse(inputSource); > > return recordingHandler.getRecording(); > > } catch (SAXParseException exc) { > Location location = new Location(exc.getSystemId(), exc.getLineNumber(), exc.getColumnNumber()); > > Throwable t = exc.getException(); > if (t instanceof BuildException) { > BuildException be = (BuildException) t; > if (be.getLocation() == Location.UNKNOWN_LOCATION) { > be.setLocation(location); > } > throw be; > } else if (t == null) { > t = exc; > } > > throw new BuildException(exc.getMessage(), t, location); > } catch (SAXException exc) { > Throwable t = exc.getException(); > if (t instanceof BuildException) { > throw (BuildException) t; > } else if (t == null) { > t = exc; > } > throw new BuildException(exc.getMessage(), t); > } catch (FileNotFoundException exc) { > throw new BuildException(exc); > } catch (UnsupportedEncodingException exc) { > throw new BuildException("Encoding of project file " + buildFile.getName() + " is invalid.", exc); > } catch (IOException exc) { > throw new BuildException("Error reading project file " + buildFile.getName() + ": " + exc.getMessage(), exc); > } finally { > if (inputStream != null) { > try { > inputStream.close(); > } catch (IOException ioe) { > // ignore this > } > } > } > } > > private Recording getRecording(File file, Project project, AntXMLContext context) throws BuildException { > Recording recording = _recordings.get(file); > if (recording == null) { > recording = createRecording(file, project, context); > if (recording != null) { > _recordings.put(file, recording); > } > } > return recording; > } > > public void parse(Project project, Object source, RootHandler handler) throws BuildException { > > AntXMLContext context = (AntXMLContext) project.getReference("ant.parsing.context"); > if (context == null) { > throw new IllegalStateException(); > } > > if (source instanceof File) { > File buildFile = (File) source; > > buildFile = fileUtils.normalize(buildFile.getAbsolutePath()); > context.setBuildFile(buildFile); > > Recording recording = getRecording(buildFile, project, context); > try { > recording.playback(handler); > } catch (SAXParseException parseException) { > Location location = new Location(parseException.getSystemId(), parseException.getLineNumber(), parseException.getColumnNumber()); > > Throwable t = parseException.getException(); > if (t instanceof BuildException) { > BuildException be = (BuildException) t; > if (be.getLocation() == Location.UNKNOWN_LOCATION) { > be.setLocation(location); > } > throw be; > } else if (t == null) { > t = parseException; > } > > throw new BuildException(parseException.getMessage(), t, location); > } catch (Throwable t) { > if (t instanceof BuildException) { > throw (BuildException) t; > } > throw new BuildException(t); > } > } else if (source instanceof URL) { > super.parse(project, source, handler); > } > > } > > /** > * Clear the recordings cache. > * > */ > public static void clear() { > _recordings.clear(); > } > >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 38844
: 17830