package org.xenei.jdbc4sparql.iface.name; import java.util.Comparator; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang3.builder.CompareToBuilder; import org.apache.commons.lang3.builder.EqualsBuilder; import org.xenei.jdbc4sparql.impl.NameUtils; /** * A name for an item in a JDBC query. This name wraps an FQName for the * underlying object with an FQName used in the query. The FQName used in the * query may contain NULLs. * */ public abstract class ItemName implements GUIDObject { /** * Compaes ItemNames. */ public static Comparator<ItemName> COMPARATOR = new Comparator<ItemName>() { @Override public int compare(final ItemName arg0, final ItemName arg1) { return new CompareToBuilder() .append(arg0.getCatalog(), arg1.getCatalog()) .append(arg0.getSchema(), arg1.getSchema()) .append(arg0.getTable(), arg1.getTable()) .append(arg0.getColumn(), arg1.getColumn()).toComparison(); } }; /** * Filters an ExtendedIterator for items that match this name using the * compare filter. * * @author claude * * @param <T> * and ItemName implementation. */ public static class Filter<T extends ItemName> extends com.hp.hpl.jena.util.iterator.Filter<T> { private final ItemName compareTo; public Filter(final ItemName compareTo) { this.compareTo = compareTo; } @Override public boolean accept(final T o) { return COMPARATOR.compare(o, compareTo) == 0; }; } /** * Verify that a segment is not null. Similar to FQNameImpl.verifyOK except * that it does not check for the presence of the JDBC or SPARQL "Dot" * characters. Used in constructors to verify values. * * @param value * value. * @param segment * the segment we are checking. * @return the value * @Throws IllegalArgumentException if a null value is passed */ public static String checkNotNull(final String value, final String segment) throws IllegalArgumentException { if (value == null) { throw new IllegalArgumentException(String.format( "Segment %s may not be null", segment)); } return value; } // the base name for the object. private final FQName fqName; // the bitmap of the used segments. private NameSegments usedSegments; // if true then this object reports its name as it's GUID. private boolean useGUID; /** * A wild item name. All display segments are null so it matches all other * item names. */ public static final ItemName WILD = new ItemName("", "", "", "", NameSegments.WILD) { @Override protected String createName(final String separator) { return getShortName(); } @Override public String getShortName() { return "Wild Name"; } @Override public void setUsedSegments(final NameSegments usedSegments) { throw new UnsupportedOperationException( "WILD may not change used segments"); // do nothing } @Override public ItemName clone(final NameSegments segs) { return WILD; } }; /** * Constructor. Creates an Item name with the associated name segments and a * Column name segment pattern. None of the column segments may be null. * * @param catalog * @param schema * @param table * @param column * @throws IllegalArgumentException */ protected ItemName(final String catalog, final String schema, final String table, final String column) throws IllegalArgumentException { this(catalog, schema, table, column, NameSegments.COLUMN); } /** * Constructor. Creates an ItemName with the associated name segments and * segment pattern. None of the arguments may be null. * * @param catalog * @param schema * @param table * @param column * @param segs * @throws IllegalArgumentException */ protected ItemName(final String catalog, final String schema, final String table, final String column, final NameSegments segs) throws IllegalArgumentException { fqName = new FQNameImpl(catalog, schema, table, column); if (segs == null) { throw new IllegalArgumentException("segs may not be null."); } this.usedSegments = segs; } /** * Constructor. Creates an ItemName from the base name of the provided name * as along with the segments. none of the values may be null. * * @param name * The base name * @param segments * Then name segments. * @throws IllegalArgumentException */ protected ItemName(final ItemName name, final NameSegments segments) throws IllegalArgumentException { if (name == null) { throw new IllegalArgumentException("name may not be null."); } if (segments == null) { throw new IllegalArgumentException("segments may not be null."); } this.fqName = name.fqName; this.useGUID = name.useGUID; this.usedSegments = segments; } /** * Constructor. Creates an ItemName from a FQName and a name segments. None * of the values may be null. * * @param name * THe FQName for the base name. * @param segments * The name segments. * @throws IllegalArgumentException */ protected ItemName(final FQName name, final NameSegments segments) throws IllegalArgumentException { this.fqName = name; this.usedSegments = segments; } /** * If set true this item will refer to itself by its GUID. * * @param state */ public void setUseGUID(final boolean state) { this.useGUID = state; } /** * Change the used segments. This effectively changes the name of the object * as seen in the query. * * @param usedSegments * the name segments to use. */ public void setUsedSegments(final NameSegments usedSegments) { this.usedSegments = usedSegments; } /** * Get the namesegments. * * @return The current name segments. */ public NameSegments getUsedSegments() { return usedSegments; } /** * create the fully qualified name for this item. * * @param separator * The string to use between name segments * @return The fully qualified name */ abstract protected String createName(final String separator); /** * Get the base name for this item name. * * @return */ protected FQName getFQName() { return fqName; } /** * Get the column name string * * @return */ public String getColumn() { return usedSegments.getColumn(fqName); } /** * Get the name in JDBC format * * @return */ public String getDBName() { return useGUID ? getGUID() : createName(NameUtils.DB_DOT); } /** * Get the catalog name segment. * * @return The catalog name string. */ public String getCatalog() { return usedSegments.getCatalog(fqName); } /** * Get the schema segment of the name. * * @return the schema segment string. */ public String getSchema() { return usedSegments.getSchema(fqName); } /** * Get the shrot name. This is the last name segment generally used by the * ItemName type. (e.g. the columnName for a column object). * * @return the short name for the object. */ abstract public String getShortName(); /** * Get the complete name in SPARQL format * * @return */ public String getSPARQLName() { return useGUID ? getGUID() : createName(NameUtils.SPARQL_DOT); } /** * Get the name as a UUID of the base name. * * @return the UUID based name */ @Override public String getGUID() { return fqName.getGUID(); } /** * Get the table portion of the complete name. * * @return the table name string */ public String getTable() { return usedSegments.getTable(fqName); } /** * See if any displayed name segment is the wild value (null). * * @return true if this has a wildcard (null) segment */ public boolean hasWild() { return (getCatalog() == null) || (getSchema() == null) || (getTable() == null) || (getColumn() == null); } /** * See if this is the wild card. * * @return true if this is a complete wildcard name (e.g. all segments are * null) */ public boolean isWild() { return (getCatalog() == null) && (getSchema() == null) && (getTable() == null) && (getColumn() == null); } /** * See if we are using the GUID as the name. * * @return true if GUID is used as the name. */ public boolean isUseGUID() { return useGUID; } /** * check if this matches that. * * AND the usedSegments from this ItemName with the usedSegments from that * ItemName. Any values that are then selected are compared from both * ItemNames. * * @param that * the other ItemName. * @return true if they match, false otherwise. */ public boolean matches(final ItemName that) { if (that == null) { return false; } final NameSegments matchSegs = usedSegments.and(that.getUsedSegments()); final EqualsBuilder eb = new EqualsBuilder(); if (matchSegs.isCatalog()) { eb.append(matchSegs.getCatalog(this.fqName), matchSegs.getCatalog(that.getFQName())); } if (matchSegs.isSchema()) { eb.append(matchSegs.getSchema(this.fqName), matchSegs.getSchema(that.getFQName())); } if (matchSegs.isTable()) { eb.append(matchSegs.getTable(this.fqName), matchSegs.getTable(that.getFQName())); } if (matchSegs.isColumn()) { eb.append(matchSegs.getColumn(this.fqName), matchSegs.getColumn(that.getFQName())); } return eb.isEquals(); } @Override public String toString() { if (isWild()) { return "Wildcard Name"; } return StringUtils.defaultIfBlank(getDBName(), "Blank Name"); } @Override public int hashCode() { return getGUID().hashCode(); } /** * Items are equal if their sparqlNames are equal. */ @Override public boolean equals(final Object o) { return (o instanceof ItemName) ? getSPARQLName().equals( ((ItemName) o).getSPARQLName()) : false; } /** * Clone this name but change the segments being used. * * @param segs * @return */ abstract public ItemName clone(NameSegments segs); }