|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.api.web.dd; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.lang.ref.WeakReference; import org.netbeans.modules.web.dd.impl.WebAppProxy; import org.openide.filesystems.*; import org.xml.sax.*; import java.util.Map; import org.openide.util.NbBundle; import java.net.URL; /** * Provides access to Deployment Descriptor root ({@link org.netbeans.api.web.dd.WebApp} object) * * @author Milan Kuchtiak */ public final class DDProvider { private static DDProvider ddProvider; private Map ddMap; private Map baseBeanMap; private Map errorMap; private FCA fileChangeListener; private static final String EXCEPTION_PREFIX="version:"; //NOI18N /** Creates a new instance of WebModule */ private DDProvider() { ddMap=new java.util.HashMap(5); baseBeanMap=new java.util.HashMap(5); errorMap=new java.util.HashMap(5); fileChangeListener = new FCA (); } /** * Accessor method for DDProvider singleton * @return DDProvider object */ public static synchronized DDProvider getDefault() { if (ddProvider==null) ddProvider = new DDProvider(); return ddProvider; } /** * Returns the root of deployment descriptor bean graph for given file object. * The method is useful for clints planning to read only the deployment descriptor * or to listen to the changes. * @param fo FileObject representing the web.xml file * @return WebApp object - root of the deployment descriptor bean graph */ public WebApp getDDRoot(FileObject fo) throws java.io.IOException { WebAppProxy webApp = getFromCache (fo); if (webApp!=null) return webApp; fo.addFileChangeListener(fileChangeListener); String version=null; SAXParseException error = null; try { WebApp original = getOriginalFromCache (fo); if (original == null) { version = getVersion(fo.getInputStream()); // preparsing error = parse(fo); original = createWebApp(fo.getInputStream(), version); baseBeanMap.put(fo.getURL(), new WeakReference (original)); } else { version = original.getVersion (); error = (SAXParseException) errorMap.get (fo.getURL ()); } webApp=new WebAppProxy(original,version); if (error!=null) { webApp.setStatus(WebApp.STATE_INVALID_PARSABLE); webApp.setError(error); } } catch (SAXException ex) { webApp = new WebAppProxy(null,version); webApp.setStatus(WebApp.STATE_INVALID_UNPARSABLE); if (ex instanceof SAXParseException) { webApp.setError((SAXParseException)ex); } else if ( ex.getException() instanceof SAXParseException) { webApp.setError((SAXParseException)ex.getException()); } } ddMap.put(fo.getURL(), new WeakReference (webApp)); return webApp; } /** * Returns the root of deployment descriptor bean graph for given file object. * The method is useful for clients planning to modify the deployment descriptor. * Finally the {@link org.netbeans.api.web.dd.WebApp#write(org.openide.filesystems.FileObject)} should be used * for writing the changes. * @param fo FileObject representing the web.xml file * @return WebApp object - root of the deployment descriptor bean graph */ public WebApp getDDRootCopy(FileObject fo) throws java.io.IOException { return (WebApp)getDDRoot(fo).clone(); } private WebAppProxy getFromCache (FileObject fo) throws java.io.IOException { WeakReference wr = (WeakReference) ddMap.get(fo.getURL ()); if (wr == null) { return null; } WebAppProxy webApp = (WebAppProxy) wr.get (); if (webApp == null) { ddMap.remove (fo.getURL ()); } return webApp; } private WebApp getOriginalFromCache (FileObject fo) throws java.io.IOException { WeakReference wr = (WeakReference) baseBeanMap.get(fo.getURL ()); if (wr == null) { return null; } WebApp webApp = (WebApp) wr.get (); if (webApp == null) { baseBeanMap.remove (fo.getURL ()); errorMap.remove (fo.getURL ()); if (ddMap.get (fo.getURL ()) == null) { } } return webApp; } /** * Returns the root of deployment descriptor bean graph for java.io.File object. * * @param f File representing the web.xml file * @return WebApp object - root of the deployment descriptor bean graph */ public WebApp getDDRoot(File f) throws IOException, SAXException { return createWebApp(new FileInputStream(f), getVersion(new FileInputStream(f))); } /** Convenient method for getting the BaseBean object from CommonDDBean object. * The j2eeserver module needs BaseBean to implement jsr88 API. * This is a temporary workaround until the implementation of jsr88 moves into ddapi * or the implementation in j2eeserver gets changed. * @deprecated do not use - temporary workaround that exposes the schema2beans implementation */ public org.netbeans.modules.schema2beans.BaseBean getBaseBean(org.netbeans.api.web.dd.common.CommonDDBean bean) { if (bean instanceof org.netbeans.modules.schema2beans.BaseBean) return (org.netbeans.modules.schema2beans.BaseBean)bean; else if (bean instanceof WebAppProxy) return (org.netbeans.modules.schema2beans.BaseBean) ((WebAppProxy)bean).getOriginal(); return null; } private static WebApp createWebApp(java.io.InputStream is, String version) throws java.io.IOException { if (WebApp.VERSION_2_3.equals(version)) { return org.netbeans.modules.web.dd.impl.model_2_3.WebApp.createGraph(is); } else { return org.netbeans.modules.web.dd.impl.model_2_4.WebApp.createGraph(is); } } /** Parsing just for detecting the version SAX parser used */ private static String getVersion(java.io.InputStream is) throws java.io.IOException, SAXException { javax.xml.parsers.SAXParserFactory fact = javax.xml.parsers.SAXParserFactory.newInstance(); fact.setValidating(false); try { javax.xml.parsers.SAXParser parser = fact.newSAXParser(); XMLReader reader = parser.getXMLReader(); reader.setContentHandler(new VersionHandler()); reader.setEntityResolver(DDResolver.getInstance()); try { reader.parse(new InputSource(is)); } catch (SAXException ex) { is.close(); String message = ex.getMessage(); if (message!=null && message.startsWith(EXCEPTION_PREFIX)) return message.substring(EXCEPTION_PREFIX.length()); else throw new SAXException(NbBundle.getMessage(DDProvider.class, "MSG_cannotParse"),ex); } is.close(); throw new SAXException(NbBundle.getMessage(DDProvider.class, "MSG_cannotFindRoot")); } catch(javax.xml.parsers.ParserConfigurationException ex) { throw new SAXException(NbBundle.getMessage(DDProvider.class, "MSG_parserProblem"),ex); } } private static class VersionHandler extends org.xml.sax.helpers.DefaultHandler { public void startElement(String uri, String localName, String rawName, Attributes atts) throws SAXException { if ("web-app".equals(rawName)) { //NOI18N String version = atts.getValue("version"); //NOI18N throw new SAXException(EXCEPTION_PREFIX+(version==null?WebApp.VERSION_2_3:version)); } } } private static class DDResolver implements EntityResolver { static DDResolver resolver; static synchronized DDResolver getInstance() { if (resolver==null) { resolver=new DDResolver(); } return resolver; } public InputSource resolveEntity (String publicId, String systemId) { String resource=null; // return a proper input source if ("-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN".equals(publicId)) { //NOI18N resource="/org/netbeans/modules/web/dd/impl/resources/web-app_2_3.dtd"; //NOI18N } else if ("-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN".equals(publicId)) { //NOI18N resource="/org/netbeans/modules/web/dd/impl/resources/web-app_2_2.dtd"; //NOI18N } else if ("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd".equals(systemId)) { resource="/org/netbeans/modules/web/dd/impl/resources/web-app_2_4.xsd"; //NOI18N } if (resource==null) return null; java.net.URL url = this.getClass().getResource(resource); return new InputSource(url.toString()); } } private static class ErrorHandler implements org.xml.sax.ErrorHandler { private int errorType=-1; SAXParseException error; public void warning(org.xml.sax.SAXParseException sAXParseException) throws org.xml.sax.SAXException { if (errorType<0) { errorType=0; error=sAXParseException; } //throw sAXParseException; } public void error(org.xml.sax.SAXParseException sAXParseException) throws org.xml.sax.SAXException { if (errorType<1) { errorType=1; error=sAXParseException; } //throw sAXParseException; } public void fatalError(org.xml.sax.SAXParseException sAXParseException) throws org.xml.sax.SAXException { errorType=2; throw sAXParseException; } public int getErrorType() { return errorType; } public SAXParseException getError() { return error; } } public SAXParseException parse (FileObject fo) throws org.xml.sax.SAXException, java.io.IOException { DDProvider.ErrorHandler errorHandler = new DDProvider.ErrorHandler(); try { XMLReader reader = new org.apache.xerces.parsers.SAXParser(); reader.setErrorHandler(errorHandler); reader.setEntityResolver(DDProvider.DDResolver.getInstance()); reader.setFeature("http://apache.org/xml/features/validation/schema", true); // NOI18N reader.setFeature("http://xml.org/sax/features/validation", true); // NOI18N reader.setFeature("http://xml.org/sax/features/namespaces", true); // NOI18N reader.parse(new InputSource(fo.getInputStream())); SAXParseException error = errorHandler.getError(); if (error!=null) return error; } catch (SAXException ex) { throw ex; } return null; } private class FCA extends FileChangeAdapter { public void fileChanged(FileEvent evt) { FileObject fo=evt.getFile(); try { WebAppProxy webApp = getFromCache (fo); WebApp orig = getOriginalFromCache (fo); if (webApp!=null) { String version = null; try { version = getVersion(fo.getInputStream()); // preparsing SAXParseException error = parse(fo); if (error!=null) { webApp.setError(error); webApp.setStatus(WebApp.STATE_INVALID_PARSABLE); } else { webApp.setError(null); webApp.setStatus(WebApp.STATE_VALID); } WebApp original = createWebApp(fo.getInputStream(), version); baseBeanMap.put(fo.getURL(), new WeakReference (original)); errorMap.put(fo.getURL(), webApp.getError ()); // replacing original file in proxy WebApp if (!version.equals(webApp.getVersion())) { webApp.setOriginal(original); } else {// the same version // replacing original file in proxy WebApp if (webApp.getOriginal()==null) { webApp.setOriginal(original); } else { webApp.getOriginal().merge(original,WebApp.MERGE_UPDATE); } } } catch (SAXException ex) { if (ex instanceof SAXParseException) { webApp.setError((SAXParseException)ex); } else if ( ex.getException() instanceof SAXParseException) { webApp.setError((SAXParseException)ex.getException()); } webApp.setStatus(WebApp.STATE_INVALID_UNPARSABLE); webApp.setOriginal(null); webApp.setProxyVersion(version); } } else if (orig != null) { String version = null; try { version = getVersion(fo.getInputStream()); WebApp original = createWebApp(fo.getInputStream(), version); if (original.getClass().equals (orig.getClass())) { orig.merge(original,WebApp.MERGE_UPDATE); } else { baseBeanMap.put(fo.getURL(), new WeakReference (original)); } } catch (SAXException ex) { baseBeanMap.remove(fo.getURL()); } } } catch (java.io.IOException ex){} } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.