/* * Copyright 2011 JBoss Inc * * 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.drools.semantics.builder.model; import org.drools.semantics.utils.NameUtils; import org.jdom.Namespace; 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; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.HashMap; import java.util.Map; public class SemanticXSDModelImpl extends XSDModelImpl implements SemanticXSDModel { private String index; private Map<String,Document> bindings = new HashMap<String, Document>( ); private String individualFactory; private Map<Namespace,String> packageInfos; private String empireConfig; private String persistenceXml; public Document getBindings( String namespace ) { return bindings.containsKey( namespace )? bindings.get( namespace ) : null; } public boolean streamIndividualFactory( OutputStream os ) { try { os.write( individualFactory.getBytes() ); } catch (IOException e) { return false; } return true; } public void setBindings( String namespace, Document bindings ) { if ( this.bindings == null ) { this.bindings = new HashMap<String,Document>( 3 ); } this.bindings.put( namespace, bindings ); } public String getNamespacedPackageInfo( Namespace ns ) { return packageInfos.get( ns ); } public void addNamespacedPackageInfo( Namespace ns, String namespaceFix ) { if ( packageInfos == null ) { packageInfos = new HashMap<Namespace, String>( 3 ); } this.packageInfos.put( ns, namespaceFix ); } public boolean streamBindings( OutputStream os ) { try { for ( String ns : bindings.keySet() ) { os.write( compactXML( getBindings ( ns ) ).getBytes() ); } } catch ( Exception e ) { return false; } return true; } public boolean streamNamespacedPackageInfos( File folder ) { try { for ( Namespace ns : packageInfos.keySet() ) { String packageName = NameUtils.namespaceURIToPackage( ns.getURI() ); File out = new File( folder.getPath() + File.separator + packageName.replace( '.', File.separatorChar ) + File.separator + "package-info.java" ); if ( ! out.exists() ) { String fix = packageInfos.get( ns ); if ( ! out.getParentFile().exists() ) { out.getParentFile().mkdirs(); } FileOutputStream fos = new FileOutputStream( out ); fos.write( fix.getBytes() ); fos.flush(); fos.close(); } } } catch ( Exception e ) { e.printStackTrace(); return false; } return true; } public boolean streamEmpireConfig( OutputStream os ) { try { // System.out.println(" EMPIRE CONFIG" + getEmpireConfig() ); os.write( getEmpireConfig().getBytes() ); } catch ( Exception e ) { return false; } return true; } private String compactXML( Document dox ) throws IOException, ParserConfigurationException, SAXException, XPathExpressionException, TransformerException { // DocumentBuilderFactory doxFactory = DocumentBuilderFactory.newInstance(); // DocumentBuilder builder = doxFactory.newDocumentBuilder(); // InputSource is = new InputSource( new StringReader( source ) ); // Document dox = builder.parse( is ); // dox.normalize(); XPathFactory xpathFactory = XPathFactory.newInstance(); XPathExpression xpathExp = xpathFactory.newXPath().compile( "//text()[normalize-space(.) = '']"); NodeList emptyTextNodes = (NodeList) xpathExp.evaluate(dox, XPathConstants.NODESET); // Remove each empty text node from document. for (int i = 0; i < emptyTextNodes.getLength(); i++) { Node emptyTextNode = emptyTextNodes.item(i); emptyTextNode.getParentNode().removeChild(emptyTextNode); } TransformerFactory tFactory = TransformerFactory.newInstance(); tFactory.setAttribute( "indent-number", new Integer( 2 ) ); Transformer transformer = tFactory.newTransformer(); transformer.setOutputProperty( OutputKeys.INDENT, "yes" ); DOMSource domSrc = new DOMSource( dox ); ByteArrayOutputStream baos = new ByteArrayOutputStream(); StreamResult result = new StreamResult( baos ); transformer.transform( domSrc, result ); return new String( baos.toByteArray() ); } public boolean streamBindings( File folder ) { try { for ( String ns : prefixMap.keySet() ) { FileOutputStream os = null; Namespace namespace = prefixMap.get( ns ); if ( "xsd".equals( ns ) || "xsi".equals( ns ) ) { continue; } if ( "owl".equals( ns ) ) { os = new FileOutputStream( folder + File.separator + "global.xjb" ); } else { String path = folder.getPath() + File.separator + NameUtils.namespaceURIToPackage( namespace.getURI() ) + ".xjb"; File target = new File( path ); target = checkForBindingOverride( namespace, target ); os = new FileOutputStream( target ); } if ( os != null ) { Document bindings = getBindings( prefixMap.get( ns ).getURI() ); // System.out.println( compactXML( bindings ) ); String tgtSchemaLoc = schemaLocations.get( namespace ); checkSchemaLocationOverride( bindings, tgtSchemaLoc ); os.write( compactXML( bindings ).getBytes() ); os.flush(); os.close(); } } } catch ( Exception e ) { e.printStackTrace(); return false; } return true; } private void checkSchemaLocationOverride( Document bindings, String tgtSchemaLoc ) { if ( tgtSchemaLoc != null ) { tgtSchemaLoc = tgtSchemaLoc.substring( tgtSchemaLoc.lastIndexOf( File.separator ) + 1 ); NodeList bx = bindings.getElementsByTagName( "bindings" ); for ( int j = 0; j < bx.getLength(); j++ ) { Element bind = (Element) bx.item( j ); // if ( "/xsd:schema".equals( bind.getAttribute( "node" ) ) ) { if ( bind.hasAttribute( "schemaLocation" ) ) { String currSchemaLoc = bind.getAttribute( "schemaLocation" ); if ( ! currSchemaLoc.equals( tgtSchemaLoc ) ) { bind.setAttribute( "schemaLocation", tgtSchemaLoc ); } break; } } } } private File checkForBindingOverride( Namespace ns, File tgt ) { int j = 0; File target = tgt; String path = target.getPath(); while ( target.exists() ) { target = new File( path.replace( ".xjb", "_" + ( j++ ) + ".xjb" ) ); } return target; } public String getIndex() { return index; } public void setIndex(String index) { this.index = index; } public boolean streamIndex( OutputStream os ) { try { os.write( index.getBytes() ); } catch (IOException e) { return false; } return true; } public boolean streamPersistenceXml( OutputStream os ) { try { os.write( persistenceXml.getBytes() ); } catch (IOException e) { return false; } return true; } public String getIndividualFactory() { return individualFactory; } public void setIndividualFactory(String individualFactory) { this.individualFactory = individualFactory; } public String getEmpireConfig() { return empireConfig; } public void setEmpireConfig( String empireConfig ) { this.empireConfig = empireConfig; } public String getPersistenceXml() { return persistenceXml; } public void setPersistenceXml(String persistenceXml) { this.persistenceXml = persistenceXml; } }