/* * Copyright (C) 2009-2011 University of Dundee & Open Microscopy Environment. * All rights reserved. * * Use is subject to license terms supplied in LICENSE.txt */ package ome.util; import java.text.Collator; import java.text.RuleBasedCollator; import java.util.ArrayList; import java.util.List; import java.util.Locale; /** * This class represents an LSID as used by the OME-XML data model. * * @author Chris Allan <callan at blackcat dot ca> * */ public class LSID { /** Concrete Java class which qualifies the type of object. */ private Class klass; /** Indexes within the OME-XML data model. */ private int[] indexes; /** The LSID as a string. */ private String asString; /** Our hash code. */ private int hashCode; /** * The collator that we use to alphabetically sort by class name * within a given level of the OME-XML hierarchy. */ private final RuleBasedCollator stringComparator = (RuleBasedCollator) Collator.getInstance(Locale.ENGLISH); /** * Default constructor. * @param klass Concrete Java class which qualifies the type of object * this LSID represents. * @param indexes Indexes for this LSID within the OME-XML data model. */ public LSID(Class klass, int... indexes) { this.klass = klass; this.indexes = indexes; asString = klass.getName(); for (int index : indexes) { asString = asString + ":" + index; } hashCode = asString.hashCode(); } /** * Constructor for non-standard LSIDs. * @param asString The LSID as a string. */ public LSID(String asString) { this.asString = asString; hashCode = asString.hashCode(); } /** * Constructor for standard LSIDs that should be parsed. * @param asString The LSID as a string. * @param parse Whether or not to parse the LSID. */ public LSID(String asString, boolean parse) { this.asString = asString; hashCode = asString.hashCode(); if (parse) { klass = parseJavaClass(); indexes = parseIndexes(); } } /** * Returns the Java class which qualifies the type of object this * LSID represents. * @return See above. */ public Class getJavaClass() { return klass; } /** * Attempts to parse and return the concrete Java class for the LSID from * the LSID's string representation. * @return See above. <code>null</code> if the concrete class cannot be * parsed. */ public Class parseJavaClass() { int colonIndex = asString.indexOf(":"); if (colonIndex > -1) { try { return Class.forName(asString.substring(0, colonIndex)); } catch (ClassNotFoundException e) { // No-op. We return null below. } } return null; } /** * Attempts to parse and return the indexes for the LSID parsed from the * LSID's string representation. * @return See above. */ public int[] parseIndexes() { List<Integer> indexList = new ArrayList<Integer>(); int colonIndex = asString.indexOf(":"); while (colonIndex > - 1) { int nextIndex = asString.indexOf(":", colonIndex + 1); if (nextIndex > -1) { String s = asString.substring(colonIndex + 1, nextIndex); indexList.add(Integer.parseInt(s)); colonIndex = nextIndex; } else { String s = asString.substring(colonIndex + 1); indexList.add(Integer.parseInt(s)); break; } } int[] toReturn = new int[indexList.size()]; for (int i = 0; i < indexList.size(); i++) { toReturn[i] = indexList.get(i); } return toReturn; } /** * Returns the indexes for this LSID within the OME-XML data model. * @return See above. */ public int[] getIndexes() { return indexes; } @Override public String toString() { return asString; } @Override public int hashCode() { return hashCode; } @Override public boolean equals(Object obj) { if (obj instanceof LSID) { LSID comparator = (LSID) obj; Class comparatorClass = comparator.getJavaClass(); if (comparatorClass == null || klass == null) { return stringComparator.compare(asString, obj.toString()) == 0; } if (comparatorClass.equals(klass)) { int[] comparatorIndexes = comparator.getIndexes(); if (indexes.length != comparatorIndexes.length) { // Handle cases where a given LSID class may have // multiple paths with different index counts. return false; } for (int i = 0; i < indexes.length; i++) { if (indexes[i] != comparatorIndexes[i]) { return false; } } return true; } return false; } return super.equals(obj); } }