jlibs.xml.ClarkName Maven / Gradle / Ivy
/**
* 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;
import jlibs.core.lang.StringUtil;
import jlibs.core.util.NonNullIterator;
import java.util.Iterator;
/**
* This class contains utilties to work with ClarkName.
*
* ClarkName is string representation of {@link javax.xml.namespace.QName} and
* defined by James Clark.
*
*
* System.out.println(ClarkName.valueOf("htpp://namespace1", "elem1")); // prints "{http://namespace1}elem1"
* System.out.println(ClarkName.valueOf("", "elem2")); // prints "elem2"
*
* The {@code String} returned by {@link #valueOf(String, String)} is compatible with {@link javax.xml.namespace.QName#toString()}.
*
* To get {@code namespace} and {@code localPart} back from {@code clarkName}, use {@link #split(String)}:
*
* String clarkName = ClarkName.valueOf("htpp://namespace1", "elem1");
* String str[] = ClarkName.split(clarkName);
* System.out.println(str[0]); // prints "http://namespace1"
* System.out.println(str[2]); // prints "elem1"
*
* ClarkPath:
*
* Suppose you want to save location of particular element in xpath form.
* For example:
*
* ns1:elem1/ns2:elem2/ns2:elem3
* where
* ns1="http://namespace1"
* ns2="http://namespace2"
* ns3="http://namespace3"
*
* You can convert into raw xpath by inlining namespaces into xpath:
*
* {http://namespace1}elem1/{http://namespace2}elem2/{http://namespace1}elem3
*
* This form will be easier to save to some file and restore it back.
* {@code ClarkName} provides handy method to split such paths.
*
* String clarkPath = "{http://namespace1}elem1/{http://namespace2}elem2/{http://namespace1}elem3";
* Iterator clarkNames = ClarkName.iterator(clarkPath);
*
*
* @author Santhosh Kumar T
*/
public class ClarkName{
/**
* Returns string representation as defined by James Clark.
*
* This is same as {@code String} returned by {@link javax.xml.namespace.QName#toString()}.
*
* @param namespace namespace, can be null
* @param localPart localpart
*
* @return clarkName
*/
public static String valueOf(String namespace, String localPart){
return StringUtil.isEmpty(namespace) ? localPart : '{'+namespace+'}'+localPart;
}
/**
* Splits given {@code clarkName} to {@code namespace} and {@code localPart}
*
* @param clarkName clarkName to be split
*
* @return {@code String} array of size {@code 2}.
* First item is {@code namespace} and second item is {@code localPart}.
*/
public static String[] split(String clarkName){
int end = clarkName.lastIndexOf('}');
if(end==-1)
return new String[]{ "", clarkName };
else
return new String[]{ clarkName.substring(1, end), clarkName.substring(end+1) };
}
/**
* Tokenizes given {@code clarkPath} into {@code clarkNames}.
*
* {@code clarkPath} is a sequence of {@code clarkNames} separated by {@code /}.
* Example:
*
* {http://namespace1}elem1/{http://namespace2}elem2/{http://namespace1}elem3
*
*
* @param clarkPath clarkPath to be tokenized
*
* @return {@code String} Iterator containing the {@code clarkNames}
*/
public static Iterator iterator(final String clarkPath){
return new NonNullIterator(){
int from = 0;
@Override
protected String findNext(){
if(from==clarkPath.length())
return null;
int searchFrom = from;
if(clarkPath.charAt(from)=='{'){
searchFrom = clarkPath.indexOf('}', from);
if(searchFrom==-1)
throw new IllegalArgumentException("no matching brace for brace at "+from);
}
int slash = clarkPath.indexOf('/', searchFrom);
int curFrom = from;
if(slash==-1){
from = clarkPath.length();
return clarkPath.substring(curFrom);
}else{
from = slash+1;
return clarkPath.substring(curFrom, slash);
}
}
};
}
}