X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.modeling%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fservices%2FComponentNamingStrategyBase.java;h=a669fb4650679aaac5cf8771f55df2048f222fdc;hb=0935b78fb5a162719de5dab404b7161de2e7e717;hp=0d9f1fe5260cc7e324cda88a62a4ebb7c188806e;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/services/ComponentNamingStrategyBase.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/services/ComponentNamingStrategyBase.java index 0d9f1fe52..a669fb465 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/services/ComponentNamingStrategyBase.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/services/ComponentNamingStrategyBase.java @@ -1,276 +1,276 @@ -package org.simantics.modeling.services; - -import java.nio.CharBuffer; -import java.util.Comparator; -import java.util.Formatter; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.TreeSet; - -import org.simantics.db.ReadGraph; -import org.simantics.db.Resource; -import org.simantics.db.exception.DatabaseException; - -/** - * An abstract base class that contains some helpers for implementing your own - * {@link ComponentNamingStrategy}. A default implementation is also provided - * for {@link #findFreshInstanceName(ReadGraph, Resource, Resource, Resource)} - * based on the Layer0 ontology HasGeneratedNamePrefix property. - * - * @author Tuukka Lehtonen - */ -public abstract class ComponentNamingStrategyBase implements ComponentNamingStrategy { - - protected static final boolean DEBUG_ALL = false; - protected static final boolean DEBUG_NAME_MATCHING = false | DEBUG_ALL; - - protected final String generatedNameFormat; - protected final boolean caseInsensitive; - - /** - * Base constructor for a naming strategy with the specified format as the - * generated name format. The format will receive two arguments: - *
    - *
  1. proposed name as {@link String}
  2. - *
  3. an {@link Integer} that attempts to make the name unique within a - * context
  4. - *
- * The simplest format specification utilizing both values is - * "%s %d", producing "FOO 1". Another example of a useful name - * format is "%s%04d", producing "FOO0001". Reordering the - * arguments is also possible, e.g. "%2$03d %1$s", producing - * "001 FOO". - * - *

- * See {@link Formatter} for the format specification and how to customize - * it. - * - *

- * This constructor will create a case-insensitive naming strategy. - * - * @param generatedNameFormat the format to use for generated names - */ - public ComponentNamingStrategyBase(String generatedNameFormat) { - this(generatedNameFormat, true); - } - - /** - * Base constructor for a naming strategy with the specified format as the - * generated name format. The format will receive two arguments: - *

    - *
  1. proposed name as {@link String}
  2. - *
  3. an {@link Integer} that attempts to make the name unique within a - * context
  4. - *
- * The simplest format specification utilizing both values is - * "%s %d", producing "FOO 1". Another example of a useful name - * format is "%s%04d", producing "FOO0001". Reordering the - * arguments is also possible, e.g. "%2$03d %1$s", producing - * "001 FOO". - * - *

- * See {@link Formatter} for the format specification and how to customize - * it. - * - * @param generatedNameFormat the format to use for generated names - * @param caseInsensitive controls whether the strategy shall be case-insensitive or not - */ - public ComponentNamingStrategyBase(String generatedNameFormat, boolean caseInsensitive) { - this.generatedNameFormat = generatedNameFormat; - this.caseInsensitive = caseInsensitive; - } - - @Override - public String findFreshInstanceName(ReadGraph graph, Resource configurationRoot, Resource container, - Resource componentType) throws NamingException, DatabaseException { - String proposition = ComponentNamingUtil.generateProposition(graph, container, componentType); - return validateInstanceName(graph, configurationRoot, container, componentType, proposition); - } - - @Override - public String validateInstanceName(ReadGraph graph, Resource configurationRoot, Resource container, - Resource componentType, String proposition) throws NamingException, DatabaseException { - return validateInstanceName(graph, configurationRoot, container, componentType, proposition, false); - } - - @Override - public List validateInstanceNames( - ReadGraph graph, - Resource configurationRoot, - List propositions, - boolean acceptProposition, - Set externallyReserved) - throws NamingException, DatabaseException - { - throw new UnsupportedOperationException(); - } - - protected Comparator getComparator() { - return getComparator(caseInsensitive); - } - - protected static Comparator getComparator(boolean caseInsensitive) { - return caseInsensitive ? CASE_INSENSITIVE_STRING_CHARBUFFER_COMPARATOR : CASE_SENSITIVE_STRING_CHARBUFFER_COMPARATOR; - } - - protected static final Comparator CASE_SENSITIVE_STRING_CHARBUFFER_COMPARATOR = new Comparator() { - @Override - public int compare(Object o1, Object o2) { - String s1 = null; - String s2 = null; - if (o1 instanceof String) - s1 = (String) o1; - if (o2 instanceof String) - s2 = (String) o2; - if (s1 != null && s2 != null) - return s1.compareTo((String) o2); - - if (s1 == null && s2 == null) - return 0; - - if (s1 == null && (o1 instanceof CharBuffer)) - return -compare(s2, (CharBuffer) o1); - if (s2 == null && (o2 instanceof CharBuffer)) - return compare(s1, (CharBuffer) o2); - - return 0; - } - int compare(String s, CharBuffer buf) { - int len1 = s.length(); - int len2 = buf.position(); - int n = Math.min(len1, len2); - int k = 0; - while (k < n) { - char c1 = s.charAt(k); - char c2 = buf.get(k); - if (c1 != c2) { - return c1 - c2; - } - k++; - } - return len1 - len2; - } - }; - - protected static final Comparator CASE_INSENSITIVE_STRING_CHARBUFFER_COMPARATOR = new Comparator() { - @Override - public int compare(Object o1, Object o2) { - String s1 = null; - String s2 = null; - if (o1 instanceof String) - s1 = (String) o1; - if (o2 instanceof String) - s2 = (String) o2; - if (s1 != null && s2 != null) - return s1.compareToIgnoreCase((String) o2); - - if (s1 == null && s2 == null) - return 0; - - if (s1 == null && (o1 instanceof CharBuffer)) - return -compare(s2, (CharBuffer) o1); - if (s2 == null && (o2 instanceof CharBuffer)) - return compare(s1, (CharBuffer) o2); - - return 0; - } - int compare(String s, CharBuffer buf) { - int len1 = s.length(); - int len2 = buf.position(); - int n = Math.min(len1, len2); - int k = 0; - while (k < n) { - char c1 = s.charAt(k); - char c2 = buf.get(k); - if (c1 != c2) { - c1 = Character.toUpperCase(c1); - c2 = Character.toUpperCase(c2); - if (c1 != c2) { - c1 = Character.toLowerCase(c1); - c2 = Character.toLowerCase(c2); - if (c1 != c2) { - return c1 - c2; - } - } - } - k++; - } - return len1 - len2; - } - }; - - protected Set findStartsWithMatches(Set matchUniverse, String proposition) { - Set result = new TreeSet(getComparator()); - if (matchUniverse.isEmpty()) - return result; - - for (String name : matchUniverse) - if (name.startsWith(proposition)) - result.add(name); - return result; - } - - protected Set findStartsWithMatches(Set matchUniverse, String proposition, Set result) { - if (matchUniverse.isEmpty()) - return result; - - for (String name : matchUniverse) - if (name.startsWith(proposition)) - result.add(name); - return result; - } - - protected String findFreshName(Set allReservedNames, Set allRequestedNames, String proposition, boolean acceptProposition) { - if (allReservedNames == null) - throw new NullPointerException("null reserved name set"); - if (proposition == null) - throw new NullPointerException("null proposition"); - - Set startsWithMatches = findStartsWithMatches(allReservedNames, proposition); - if (allRequestedNames != null) - findStartsWithMatches(allRequestedNames, proposition, startsWithMatches); - - return findFreshName(startsWithMatches, proposition, acceptProposition); - } - - protected String findFreshName(Set reserved, String proposition, boolean acceptProposition) { - return findFreshName(reserved, proposition, acceptProposition, generatedNameFormat); - } - - protected String findFreshName(Set reserved, String proposition, boolean acceptProposition, String nameFormat) { - if (proposition == null) - throw new NullPointerException("null proposition"); - - if (DEBUG_NAME_MATCHING) - System.out.println("Finding fresh proposed name '" + proposition + "' among matching reservations: " + reserved); - - if (acceptProposition && !reserved.contains(proposition)) - return proposition; - - // Trying to optimize away unnecessary allocation of new String instances - // when looking for fresh names for objects. - CharBuffer cb = CharBuffer.allocate(proposition.length() + 10); - cb.mark(); - - @SuppressWarnings("resource") - Formatter formatter = new Formatter(cb, Locale.US); - - //int i = reserved.size() + 1; - int i = 1; - for (;; ++i) { - cb.reset(); - formatter.format(nameFormat, proposition, i); - if (!reserved.contains(cb)) { - // Construct a String from the CharBuffer - cb.limit(cb.position()); - cb.rewind(); - String result = cb.toString(); - if (DEBUG_NAME_MATCHING) - System.out.println("\tfound fresh name: " + result); - return result; - } - } - } - +package org.simantics.modeling.services; + +import java.nio.CharBuffer; +import java.util.Comparator; +import java.util.Formatter; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.TreeSet; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; + +/** + * An abstract base class that contains some helpers for implementing your own + * {@link ComponentNamingStrategy}. A default implementation is also provided + * for {@link #findFreshInstanceName(ReadGraph, Resource, Resource, Resource)} + * based on the Layer0 ontology HasGeneratedNamePrefix property. + * + * @author Tuukka Lehtonen + */ +public abstract class ComponentNamingStrategyBase implements ComponentNamingStrategy { + + protected static final boolean DEBUG_ALL = false; + protected static final boolean DEBUG_NAME_MATCHING = false | DEBUG_ALL; + + protected final String generatedNameFormat; + protected final boolean caseInsensitive; + + /** + * Base constructor for a naming strategy with the specified format as the + * generated name format. The format will receive two arguments: + *
    + *
  1. proposed name as {@link String}
  2. + *
  3. an {@link Integer} that attempts to make the name unique within a + * context
  4. + *
+ * The simplest format specification utilizing both values is + * "%s %d", producing "FOO 1". Another example of a useful name + * format is "%s%04d", producing "FOO0001". Reordering the + * arguments is also possible, e.g. "%2$03d %1$s", producing + * "001 FOO". + * + *

+ * See {@link Formatter} for the format specification and how to customize + * it. + * + *

+ * This constructor will create a case-insensitive naming strategy. + * + * @param generatedNameFormat the format to use for generated names + */ + public ComponentNamingStrategyBase(String generatedNameFormat) { + this(generatedNameFormat, true); + } + + /** + * Base constructor for a naming strategy with the specified format as the + * generated name format. The format will receive two arguments: + *

    + *
  1. proposed name as {@link String}
  2. + *
  3. an {@link Integer} that attempts to make the name unique within a + * context
  4. + *
+ * The simplest format specification utilizing both values is + * "%s %d", producing "FOO 1". Another example of a useful name + * format is "%s%04d", producing "FOO0001". Reordering the + * arguments is also possible, e.g. "%2$03d %1$s", producing + * "001 FOO". + * + *

+ * See {@link Formatter} for the format specification and how to customize + * it. + * + * @param generatedNameFormat the format to use for generated names + * @param caseInsensitive controls whether the strategy shall be case-insensitive or not + */ + public ComponentNamingStrategyBase(String generatedNameFormat, boolean caseInsensitive) { + this.generatedNameFormat = generatedNameFormat; + this.caseInsensitive = caseInsensitive; + } + + @Override + public String findFreshInstanceName(ReadGraph graph, Resource configurationRoot, Resource container, + Resource componentType) throws NamingException, DatabaseException { + String proposition = ComponentNamingUtil.generateProposition(graph, container, componentType); + return validateInstanceName(graph, configurationRoot, container, componentType, proposition); + } + + @Override + public String validateInstanceName(ReadGraph graph, Resource configurationRoot, Resource container, + Resource componentType, String proposition) throws NamingException, DatabaseException { + return validateInstanceName(graph, configurationRoot, container, componentType, proposition, false); + } + + @Override + public List validateInstanceNames( + ReadGraph graph, + Resource configurationRoot, + List propositions, + boolean acceptProposition, + Set externallyReserved) + throws NamingException, DatabaseException + { + throw new UnsupportedOperationException(); + } + + protected Comparator getComparator() { + return getComparator(caseInsensitive); + } + + protected static Comparator getComparator(boolean caseInsensitive) { + return caseInsensitive ? CASE_INSENSITIVE_STRING_CHARBUFFER_COMPARATOR : CASE_SENSITIVE_STRING_CHARBUFFER_COMPARATOR; + } + + protected static final Comparator CASE_SENSITIVE_STRING_CHARBUFFER_COMPARATOR = new Comparator() { + @Override + public int compare(Object o1, Object o2) { + String s1 = null; + String s2 = null; + if (o1 instanceof String) + s1 = (String) o1; + if (o2 instanceof String) + s2 = (String) o2; + if (s1 != null && s2 != null) + return s1.compareTo((String) o2); + + if (s1 == null && s2 == null) + return 0; + + if (s1 == null && (o1 instanceof CharBuffer)) + return -compare(s2, (CharBuffer) o1); + if (s2 == null && (o2 instanceof CharBuffer)) + return compare(s1, (CharBuffer) o2); + + return 0; + } + int compare(String s, CharBuffer buf) { + int len1 = s.length(); + int len2 = buf.position(); + int n = Math.min(len1, len2); + int k = 0; + while (k < n) { + char c1 = s.charAt(k); + char c2 = buf.get(k); + if (c1 != c2) { + return c1 - c2; + } + k++; + } + return len1 - len2; + } + }; + + protected static final Comparator CASE_INSENSITIVE_STRING_CHARBUFFER_COMPARATOR = new Comparator() { + @Override + public int compare(Object o1, Object o2) { + String s1 = null; + String s2 = null; + if (o1 instanceof String) + s1 = (String) o1; + if (o2 instanceof String) + s2 = (String) o2; + if (s1 != null && s2 != null) + return s1.compareToIgnoreCase((String) o2); + + if (s1 == null && s2 == null) + return 0; + + if (s1 == null && (o1 instanceof CharBuffer)) + return -compare(s2, (CharBuffer) o1); + if (s2 == null && (o2 instanceof CharBuffer)) + return compare(s1, (CharBuffer) o2); + + return 0; + } + int compare(String s, CharBuffer buf) { + int len1 = s.length(); + int len2 = buf.position(); + int n = Math.min(len1, len2); + int k = 0; + while (k < n) { + char c1 = s.charAt(k); + char c2 = buf.get(k); + if (c1 != c2) { + c1 = Character.toUpperCase(c1); + c2 = Character.toUpperCase(c2); + if (c1 != c2) { + c1 = Character.toLowerCase(c1); + c2 = Character.toLowerCase(c2); + if (c1 != c2) { + return c1 - c2; + } + } + } + k++; + } + return len1 - len2; + } + }; + + protected Set findStartsWithMatches(Set matchUniverse, String proposition) { + Set result = new TreeSet(getComparator()); + if (matchUniverse.isEmpty()) + return result; + + for (String name : matchUniverse) + if (name.startsWith(proposition)) + result.add(name); + return result; + } + + protected Set findStartsWithMatches(Set matchUniverse, String proposition, Set result) { + if (matchUniverse.isEmpty()) + return result; + + for (String name : matchUniverse) + if (name.startsWith(proposition)) + result.add(name); + return result; + } + + protected String findFreshName(Set allReservedNames, Set allRequestedNames, String proposition, boolean acceptProposition) { + if (allReservedNames == null) + throw new NullPointerException("null reserved name set"); + if (proposition == null) + throw new NullPointerException("null proposition"); + + Set startsWithMatches = findStartsWithMatches(allReservedNames, proposition); + if (allRequestedNames != null) + findStartsWithMatches(allRequestedNames, proposition, startsWithMatches); + + return findFreshName(startsWithMatches, proposition, acceptProposition); + } + + protected String findFreshName(Set reserved, String proposition, boolean acceptProposition) { + return findFreshName(reserved, proposition, acceptProposition, generatedNameFormat); + } + + protected String findFreshName(Set reserved, String proposition, boolean acceptProposition, String nameFormat) { + if (proposition == null) + throw new NullPointerException("null proposition"); + + if (DEBUG_NAME_MATCHING) + System.out.println("Finding fresh proposed name '" + proposition + "' among matching reservations: " + reserved); + + if (acceptProposition && !reserved.contains(proposition)) + return proposition; + + // Trying to optimize away unnecessary allocation of new String instances + // when looking for fresh names for objects. + CharBuffer cb = CharBuffer.allocate(proposition.length() + 10); + cb.mark(); + + @SuppressWarnings("resource") + Formatter formatter = new Formatter(cb, Locale.US); + + //int i = reserved.size() + 1; + int i = 1; + for (;; ++i) { + cb.reset(); + formatter.format(nameFormat, proposition, i); + if (!reserved.contains(cb)) { + // Construct a String from the CharBuffer + cb.limit(cb.position()); + cb.rewind(); + String result = cb.toString(); + if (DEBUG_NAME_MATCHING) + System.out.println("\tfound fresh name: " + result); + return result; + } + } + } + } \ No newline at end of file