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