/** * Copyright 2015 Santhosh Kumar Tekuri * * The JLibs authors license this file to you 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 jlibs.xml.sax.helpers; import jlibs.core.lang.Util; import jlibs.xml.Namespaces; import org.xml.sax.helpers.NamespaceSupport; import javax.xml.namespace.QName; import java.util.Enumeration; import java.util.Properties; /** * @author Santhosh Kumar T */ public class MyNamespaceSupport extends NamespaceSupport{ private Properties suggested; public MyNamespaceSupport(){ this(Namespaces.getSuggested()); } public MyNamespaceSupport(Properties suggested){ this.suggested = suggested; } /** * This method is used to override the prefix generated by * {@link #declarePrefix(String)}, to your own choice. * * <p> if the suggested prefix already exists, then it will * generate new prefix, from suggested prefix by appending * a number */ public void suggestPrefix(String prefix, String uri){ suggested.put(uri, prefix); } /** * Return one of the prefixes mapped to a Namespace URI. * * <p>If more than one prefix is currently mapped to the same * URI, this method will make an arbitrary selection; * * <p>Unlike {@link #getPrefix(String)} this method, this returns empty * prefix if the given uri is bound to default prefix. */ public String findPrefix(String uri){ if(uri==null) uri = ""; String prefix = getPrefix(uri); if(prefix==null){ String defaultURI = getURI(""); if(defaultURI==null) defaultURI = ""; if(Util.equals(uri, defaultURI)) prefix = ""; } return prefix; } public String findURI(String prefix){ if(prefix==null) return ""; String uri = getURI(prefix); if(uri==null){ if(prefix.isEmpty()) return ""; } return uri; } private String suggestPrefix = "ns"; public String getSuggestPrefix(){ return suggestPrefix; } public void setSuggestPrefix(String suggestPrefix){ this.suggestPrefix = suggestPrefix; } /** * generated a new prefix and binds it to given uri. * * <p>you can customize the generated prefix using {@link #suggestPrefix(String, String)} */ public String declarePrefix(String uri){ String prefix = findPrefix(uri); if(prefix==null){ if(uri.isEmpty()) prefix = ""; // non-empty prefix cannot be used for empty namespace else{ prefix = suggested.getProperty(uri, suggestPrefix); if(getURI(prefix)!=null){ if(prefix.isEmpty()) prefix = "ns"; int i = 1; String _prefix; while(true){ _prefix = prefix + i; if(getURI(_prefix)==null){ prefix = _prefix; break; } i++; } } } declarePrefix(prefix, uri); } return prefix; } @Override @SuppressWarnings({"unchecked"}) public Enumeration<String> getPrefixes(String uri){ return super.getPrefixes(uri); } @Override @SuppressWarnings({"unchecked"}) public Enumeration<String> getPrefixes(){ return super.getPrefixes(); } @Override @SuppressWarnings({"unchecked"}) public Enumeration<String> getDeclaredPrefixes(){ return super.getDeclaredPrefixes(); } public boolean isDeclaredPrefix(String prefix){ Enumeration declaredPrefixes = getDeclaredPrefixes(); while(declaredPrefixes.hasMoreElements()){ if(prefix.equals(declaredPrefixes.nextElement())) return true; } return false; } public QName toQName(String qname){ String prefix = ""; String localName = qname; int colon = qname.indexOf(':'); if(colon!=-1){ prefix = qname.substring(0, colon); localName = qname.substring(colon+1); } String uri = findURI(prefix); if(uri==null) throw new IllegalArgumentException("prefix \""+prefix+"\" is not bound to any uri"); return new QName(uri, localName, prefix); } public String toQName(String uri, String localName){ String prefix = findPrefix(uri); if(prefix==null) throw new IllegalArgumentException("no prefix found for uri \""+uri+"\""); return "".equals(prefix) ? localName : prefix+':'+localName; } /*-------------------------------------------------[ SAX Population ]---------------------------------------------------*/ private boolean needNewContext; public void startDocument(){ reset(); needNewContext = true; } public void startPrefixMapping(String prefix, String uri){ if(needNewContext){ pushContext(); needNewContext = false; } declarePrefix(prefix, uri); } public String startPrefixMapping(String uri){ if(needNewContext){ pushContext(); needNewContext = false; } return declarePrefix(uri); } public void startElement(){ if(needNewContext) pushContext(); needNewContext = true; } public void endElement(){ popContext(); } public static void main(String[] args){ MyNamespaceSupport ns = new MyNamespaceSupport(); System.out.println(ns.declarePrefix("http://www.sonoasystems.com/schemas/2007/8/3/sci/")); System.out.println(ns.declarePrefix("http://www.sonoasystems.com/schemas/2007/8/7/sci/")); System.out.println(ns.declarePrefix("http://com")); System.out.println(ns.declarePrefix("http://google.org")); } }