/******************************************************************************* * Copyright 2012 Pearson Education * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.semantictools.gwt.generator; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.HashSet; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class GwtTypeConfig { private static final String INCLUDE = "include"; private static final String EXCLUDE = "exclude"; private static final String USE_JAVASCRIPT_OBJECT = "useJavaScriptObject"; private Set<String> includes = new HashSet<String>(); private Set<String> useJavaScriptObject = new HashSet<String>(); private Set<String> excludeProperty = new HashSet<String>(); /** * Returns the set of types that are included for output. */ public Set<String> getIncludes() { return includes; } /** * Returns true if the specified type is included for output. */ public boolean includeType(String typeURI) { return includes.isEmpty() || includes.contains(typeURI); } public void addType(String typeURI) { includes.add(typeURI); } /** * Returns true if the specified property should be accessed as a JavaScriptObject * instead of a more specific type. */ public boolean useJavaScriptObject(String typeURI, String propertyLocalName) { return useJavaScriptObject.contains(typeURI + "!" + propertyLocalName); } /** * Returns true if the specified property is excluded from the specified type. */ public boolean excludeProperty(String typeURI, String propertyLocalName) { return excludeProperty.contains(typeURI + "!" + propertyLocalName); } /** * Load configuration properties from the given file. */ public void load(File file) throws IOException, ConfigParseException { String name = file.getName(); if (name.endsWith(".properties")) { parseProperties(file); } else if (name.endsWith(".xml")) { try { parseXml(file); } catch (ParserConfigurationException e) { throw new ConfigParseException(e); } catch (SAXException e) { throw new ConfigParseException(e); } } } private void parseProperties(File file) throws IOException { Properties properties = new Properties(); InputStream input = new FileInputStream(file); try { properties.load(input); parseProperties(properties); } finally { input.close(); } } private void parseXml(File file) throws IOException, ParserConfigurationException, SAXException { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); dbFactory.setNamespaceAware(true); DocumentBuilder builder = dbFactory.newDocumentBuilder(); Document doc = builder.parse(file); parseXml(doc); } private void parseXml(Document doc) { Element root = doc.getDocumentElement(); NodeList list = root.getChildNodes(); for (int i=0; i<list.getLength(); i++) { Node n = list.item(i); if (n instanceof Element) { Element e = (Element) n; String name = e.getTagName(); if (INCLUDE.equals(name)) { parseInclude(e); } } } } private void parseInclude(Element e) { NodeList list = e.getChildNodes(); for (int i=0; i<list.getLength(); i++) { Node n = list.item(i); if (n instanceof Element) { Element child = (Element) n; StringBuilder buffer = new StringBuilder(); buffer.append(child.getNamespaceURI()); buffer.append(child.getLocalName()); String uri = buffer.toString(); addType(uri); parseTypeConfig(uri, child); } } } private void parseTypeConfig(String typeURI, Element type) { NodeList list = type.getChildNodes(); for (int i=0; i<list.getLength(); i++) { Node n = list.item(i); String name = n.getNodeName(); if (USE_JAVASCRIPT_OBJECT.equals(name)) { parseUseJavaScriptObject(typeURI, (Element)n); } if (EXCLUDE.equals(name)) { parseExcludeProperties(typeURI, (Element) n); } } } private void parseExcludeProperties(String typeURI, Element container) { NodeList list = container.getChildNodes(); for (int i=0; i<list.getLength(); i++) { Node n = list.item(i); if (n instanceof Element) { Element e = (Element) n; String localName = e.getLocalName(); StringBuilder builder = new StringBuilder(); builder.append(typeURI); builder.append('!'); builder.append(localName); String path = builder.toString(); excludeProperty.add(path); } } } private void parseUseJavaScriptObject(String typeURI, Element container) { NodeList list = container.getChildNodes(); for (int i=0; i<list.getLength(); i++) { Node n = list.item(i); if (n instanceof Element) { Element e = (Element) n; String localName = e.getLocalName(); StringBuilder builder = new StringBuilder(); builder.append(typeURI); builder.append('!'); builder.append(localName); String path = builder.toString(); useJavaScriptObject.add(path); } } } /** * Scan the given directory and any subdirectories recursively for files * named "gwt.properties" and load those files into this configuration object. * @throws ConfigParseException */ public void scan(File dir) throws IOException, ConfigParseException { if (dir.isDirectory()) { File[] list = dir.listFiles(); for (int i=0; i<list.length; i++) { scan(list[i]); } } else if ( "gwt.properties".equals(dir.getName()) || "gwt.xml".equals(dir.getName()) ){ load(dir); } } private void parseProperties(Properties properties) { for (Map.Entry<Object, Object> entry : properties.entrySet() ) { String key = entry.getKey().toString(); String value = entry.getKey().toString(); if (INCLUDE.equals(key)) { setInclude(value); } } } private void setInclude(String value) { StringTokenizer tokens = new StringTokenizer(value, " \t\r\n"); while (tokens.hasMoreTokens()) { includeType(tokens.nextToken()); } } }