]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/flag/PermutativeFlagLabelingScheme.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / flag / PermutativeFlagLabelingScheme.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.diagram.flag;\r
13 \r
14 import java.nio.CharBuffer;\r
15 import java.util.Arrays;\r
16 import java.util.Set;\r
17 import java.util.TreeSet;\r
18 \r
19 import org.simantics.databoard.Bindings;\r
20 import org.simantics.db.ReadGraph;\r
21 import org.simantics.db.Resource;\r
22 import org.simantics.db.common.primitiverequest.OrderedSet;\r
23 import org.simantics.db.common.utils.NameUtils;\r
24 import org.simantics.db.exception.DatabaseException;\r
25 import org.simantics.diagram.stubs.DiagramResource;\r
26 import org.simantics.layer0.Layer0;\r
27 \r
28 /**\r
29  * @author Tuukka Lehtonen\r
30  */\r
31 public class PermutativeFlagLabelingScheme implements FlagLabelingScheme {\r
32 \r
33     protected String initialValue;\r
34     protected char   min;\r
35     protected char   max;\r
36 \r
37     /**\r
38      * @param initialValue\r
39      * @param min\r
40      * @param max\r
41      */\r
42     public PermutativeFlagLabelingScheme(String initialValue, char min, char max) {\r
43         this.initialValue = initialValue;\r
44         this.min = min;\r
45         this.max = max;\r
46     }\r
47 \r
48     /**\r
49      * Support for graph adapter construction. Only uses the first character of\r
50      * both min and max parameters.\r
51      * \r
52      * @param initialValue\r
53      * @param min\r
54      * @param max\r
55      */\r
56     public PermutativeFlagLabelingScheme(String initialValue, String min, String max) {\r
57         this.initialValue = initialValue;\r
58         this.min = min.charAt(0);\r
59         this.max = max.charAt(0);\r
60     }\r
61 \r
62     protected Set<String> getUsedLabels(ReadGraph graph, Resource diagram) throws DatabaseException {\r
63         DiagramResource DIA = DiagramResource.getInstance(graph);\r
64         Layer0 L0 = Layer0.getInstance(graph);\r
65         Set<String> used = new TreeSet<String>(NameUtils.STRING_CHARBUFFER_COMPARATOR);\r
66         for (Resource element : graph.syncRequest(new OrderedSet(diagram))) {\r
67             if (graph.isInstanceOf(element, DIA.Flag)) {\r
68                 String label = graph.getPossibleRelatedValue(element, L0.HasLabel, Bindings.STRING);\r
69                 if (label != null && !label.isEmpty())\r
70                     used.add(label);\r
71             }\r
72         }\r
73         return used;\r
74     }\r
75 \r
76     @Override\r
77     public String generateLabel(ReadGraph graph, Resource diagram) throws DatabaseException {\r
78         CharBuffer cb = CharBuffer.allocate(10);\r
79         Set<String> used = getUsedLabels(graph, diagram);\r
80         initialValue(cb);\r
81         cb.limit(cb.position());\r
82         while (used.contains(cb)) {\r
83             permutate(cb);\r
84             cb.position(cb.limit());\r
85         }\r
86         cb.rewind();\r
87         return cb.toString();\r
88     }\r
89 \r
90     protected void initialValue(CharBuffer cb) {\r
91         cb.append(initialValue);\r
92     }\r
93 \r
94     protected void permutate(CharBuffer cb) {\r
95         permutate(cb, min, max);\r
96     }\r
97 \r
98     /**\r
99      * Takes an input char buffer and modifies it so that its last character is\r
100      * set to the next value within the range [min,max]. If a character is\r
101      * already equal to max, this check and modify process is continued towards\r
102      * the beginning of the buffer until a character less than max is found. In\r
103      * the case where all characters are already equal to max, the buffer is set\r
104      * to size + 1 min characters, thus expanding the permutation space.\r
105      * \r
106      * For example permutating the string "AA" produces a sequence "AB", "AC",\r
107      * "AD", ..., "AZ", "BA", "BB", ...\r
108      */\r
109     protected void permutate(CharBuffer str, char min, char max) {\r
110         // Produce the next permutation of an [{min}-{max}]* character sequence.\r
111         int s = str.limit();\r
112         char[] chars = str.array();\r
113         for (int i = s - 1; i >= 0; --i) {\r
114             if (chars[i] < max) {\r
115                 chars[i]++;\r
116                 for (int j = i + 1; j < s; ++j)\r
117                     chars[j] = min;\r
118                 return;\r
119             }\r
120         }\r
121         // all permutations already in use, add more characters.\r
122         str.limit(s + 1);\r
123         Arrays.fill(chars, 0, s + 1, min);\r
124     }\r
125 \r
126 }