1 package org.codehaus.mojo.jaxb2.schemageneration.postprocessing.schemaenhancement; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import org.codehaus.mojo.jaxb2.schemageneration.postprocessing.NodeProcessor; 23 import org.codehaus.mojo.jaxb2.shared.Validate; 24 import org.w3c.dom.Attr; 25 import org.w3c.dom.Element; 26 import org.w3c.dom.Node; 27 28 import javax.xml.XMLConstants; 29 import java.util.Map; 30 31 /** 32 * <p>NodeProcessor which alters the filename for generated XML schema files. 33 * The ChangeNamespacePrefixProcessor alters the following:</p> 34 * <dl> 35 * <dt>Schema Import Definitions</dt> 36 * <dd><xs:import namespace="http://some/namespace" schemaLocation="<strong>schema2.xsd</strong>"/> is 37 * altered to 38 * <xs:import namespace="http://some/namespace" schemaLocation="<strong>anotherFile.xsd</strong>"/></dd> 39 * </dl> 40 * 41 * @author <a href="mailto:lj@jguru.se">Lennart Jörelid</a> 42 * @since 1.4 43 */ 44 public class ChangeFilenameProcessor implements NodeProcessor { 45 46 // Constants 47 private static final String SCHEMA_LOCATION = "schemaLocation"; 48 private static final String IMPORT = "import"; 49 private static final String NAMESPACE = "namespace"; 50 51 // Internal state 52 private Map<String, String> namespaceUriToNewFilenameMap; 53 54 /** 55 * <p>Creates a new ChangeFilenameProcessor using the provided map relating namespace URIs 56 * to desired new file names.</p> 57 * 58 * @param namespaceUriToNewFilenameMap A map relating namespace URIs [key] to 59 * new/desired schema filenames [value]. 60 */ 61 public ChangeFilenameProcessor(final Map<String, String> namespaceUriToNewFilenameMap) { 62 63 // Check sanity 64 Validate.notNull(namespaceUriToNewFilenameMap, "namespaceUriToNewFilenameMap"); 65 66 // Assign internal state 67 this.namespaceUriToNewFilenameMap = namespaceUriToNewFilenameMap; 68 } 69 70 /** 71 * {@inheritDoc} 72 */ 73 public boolean accept(final Node aNode) { 74 return aNode instanceof Attr && isSchemaLocationAttributeForKnownNamespaceUri((Attr) aNode); 75 } 76 77 /** 78 * {@inheritDoc} 79 */ 80 public void process(final Node aNode) { 81 82 // Only attributes are permitted here. 83 Attr attribute = (Attr) aNode; 84 85 // Change the fileName. 86 String newFilename = namespaceUriToNewFilenameMap.get(getNamespace(attribute)); 87 attribute.setValue(newFilename); 88 } 89 90 // 91 // Private helpers 92 // 93 94 /** 95 * Discovers if the provided attribute is a schemaLocation definition, which should 96 * be changed by this ChangeFilenameProcessor. Such an attribute is on the form 97 * <code><xs:import namespace="http://a/registered/namespace" schemaLocation="schema1.xsd"/></code>. 98 * 99 * @param attribute the attribute to test. 100 * @return <code>true</code> if the provided attribute is a schemaLocation definition 101 * whose namespace is known to this ChangeFilenameProcessor. 102 */ 103 private boolean isSchemaLocationAttributeForKnownNamespaceUri(final Attr attribute) { 104 105 final Element parent = attribute.getOwnerElement(); 106 107 // <xs:import namespace="http://yet/another/namespace" schemaLocation="schema1.xsd"/> 108 return XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(parent.getNamespaceURI()) 109 && IMPORT.equalsIgnoreCase(parent.getLocalName()) 110 && namespaceUriToNewFilenameMap.containsKey(getNamespace(attribute)) 111 && SCHEMA_LOCATION.equals(attribute.getName()); 112 } 113 114 /** 115 * Retrieves the value of the "namespace" attribute found within the parent element of the provided attribute. 116 * 117 * @param attribute An attribute defined within the parent holding the "namespace" attribute. 118 * @return The value of the "namespace" attribute. 119 */ 120 private String getNamespace(final Attr attribute) { 121 final Element parent = attribute.getOwnerElement(); 122 return parent.getAttribute(NAMESPACE); 123 } 124 }