com.adobe.xmp.path.XMPPath Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
The newest version!
// =================================================================================================
// ADOBE SYSTEMS INCORPORATED
// Copyright 2012 Adobe Systems Incorporated
// All Rights Reserved
//
// NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
// of the Adobe license agreement accompanying it.
// =================================================================================================
package com.adobe.xmp.path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
/**
* XMPPath
is a Class that provides an easy iterative description of a specific path into the XMP tree.
* Each {@link XMPPathSegment} represents one segment of the path into the XMP tree.
*/
public class XMPPath implements List
{
private List segments;
public enum Compare
{
DIFFERENT, EQUAL, ANCESTOR, DESCENDANT
}
/**
* Creates an empty XMPPath
object
*/
public XMPPath()
{
// ArrayList is supposed to be faster than Vector, especially for iterations
segments = new ArrayList();
}
/**
* Creates an XMPPath
object by parsing an XMP path String and creates one path segment
* for each detected segment in the path.
* @param path Path string to parse
* @param prefixContract A Map that contains the mapping between Namespaces and their prefixes.
* This must be provided to interpret the path correctly. The key must be the prefix and the value the namespace!
* @throws XMPPathParserException If the path has an invalid format or a prefix is found that is not defined in the prefixContract
*/
public static XMPPath parse(String path, Map prefixContract ) throws XMPPathParserException
{
return XMPPathParser.parse( path, prefixContract );
}
/**
* Serializes the XMPPath
object to a String representation.
* This will produce a long form of the path using the full namespace strings.
* @return String representation of the XMPPath
*/
public String serialize()
{
return serialize( null );
}
/**
* Serializes the XMPPath
object to a String representation.
* This produces a short form of the path using the prefixes provided by the contract.
* @param prefixContract A Map that contains the mapping between Namespaces and their prefixes.
* The key must be the prefix and the value the namespace!
* @return String representation of the XMPPath
*/
public String serialize( Map prefixContract )
{
StringBuffer result = new StringBuffer();
boolean firstSegment = true;
for( XMPPathSegment segment : segments )
{
String prefix = null;
if( prefixContract != null)
{
for( Entry entry : prefixContract.entrySet() )
{
if( entry.getValue().equals( segment.getNamespace() ) )
{
prefix = entry.getKey();
}
}
}
// if no prefix is available, use the full namespace string
if(prefix == null)
{
prefix = segment.getNamespace();
}
switch( segment.getType() )
{
case PROPERTY:
if( ! firstSegment )
{
result.append( "/" );
}
result.append( prefix + ":" + segment.getName());
break;
case ARRAY_INDEX:
result.append( "[" + segment.getIndex() + "]" );
break;
case QUALIFIER:
if( ! firstSegment )
{
result.append( "/" );
}
result.append( "@" + prefix + ":" + segment.getName() );
break;
case QUALIFIER_SELECTOR:
result.append( "[?" + prefix + ":" + segment.getName() + "=\"" + segment.getValue() + "\"]" );
break;
}
if( firstSegment )
{
firstSegment = false;
}
}
return result.toString();
}
public int size()
{
return segments.size();
}
public boolean isEmpty()
{
return segments.isEmpty();
}
public boolean contains(Object o)
{
return segments.contains( o );
}
public Iterator iterator()
{
return segments.iterator();
}
public Object[] toArray()
{
return segments.toArray();
}
public T[] toArray(T[] a)
{
return segments.toArray( a );
}
public boolean add(XMPPathSegment e)
{
return segments.add( e );
}
public boolean remove(Object o)
{
return segments.remove( o );
}
public boolean containsAll(Collection> c)
{
return segments.containsAll( c );
}
public boolean addAll(Collection extends XMPPathSegment> c)
{
return segments.addAll( c );
}
public boolean addAll(int index, Collection extends XMPPathSegment> c)
{
return segments.addAll( index, c );
}
public boolean removeAll(Collection> c)
{
return segments.removeAll( c );
}
public boolean retainAll(Collection> c)
{
return segments.retainAll( c );
}
public void clear()
{
segments.clear();
}
public XMPPathSegment get(int index)
{
return segments.get( index );
}
public XMPPathSegment set(int index, XMPPathSegment element)
{
return segments.set( index, element );
}
public void add(int index, XMPPathSegment element)
{
segments.add( index, element );
}
public XMPPathSegment remove(int index)
{
return segments.remove( index );
}
public int indexOf(Object o)
{
return segments.indexOf( o );
}
public int lastIndexOf(Object o)
{
return segments.lastIndexOf( o );
}
public ListIterator listIterator()
{
return segments.listIterator();
}
public ListIterator listIterator(int index)
{
return segments.listIterator( index );
}
public List subList(int fromIndex, int toIndex)
{
return segments.subList( fromIndex, toIndex );
}
/**
* Compares the provided path with this path.
*
* @param path the path to compare with
* @return The paths are equal if both have the same size and each segment is EQUAL.
* If the provided path is a subpath of this path, ANCESTOR is returned.
* If the provided path is an ancestor of this path, DESCENDANT is returned.
* In all other cases the paths are DIFFERENT.
* @throws IllegalArgumentException If path is null
*/
public Compare compare(XMPPath path)
{
if( path == null )
{
throw new IllegalArgumentException("path must not be null");
}
if( this.size() == 0 && path.size() == 0 )
{
return Compare.EQUAL;
}
else if( this.size() == 0 && path.size() != 0 ||
this.size() != 0 && path.size() == 0 )
{
return Compare.DIFFERENT;
}
ListIterator pathIter = this.listIterator();
ListIterator otherPathIter = path.listIterator();
while( pathIter.hasNext() )
{
if( otherPathIter.hasNext() )
{
if( ! pathIter.next().equals(otherPathIter.next()) )
{
return Compare.DIFFERENT;
}
}
else
{
return Compare.DESCENDANT;
}
}
if( otherPathIter.hasNext() )
{
return Compare.ANCESTOR;
}
return Compare.EQUAL;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((segments == null) ? 0 : segments.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
XMPPath other = (XMPPath) obj;
if (segments == null)
{
if (other.segments != null)
{
return false;
}
}
else if (!segments.equals(other.segments))
{
return false;
}
return true;
}
}