View Javadoc

1   package org.kite9.diagram.adl;
2   
3   import java.util.ArrayList;
4   import java.util.Collections;
5   import java.util.HashMap;
6   import java.util.HashSet;
7   import java.util.List;
8   import java.util.Map;
9   import java.util.Set;
10  
11  import org.kite9.diagram.adl.Symbol.SymbolShape;
12  
13  /***
14   * Helps in the creation of keys by making sure that symbols don't reuse the
15   * same code
16   * 
17   * @author robmoffat
18   * 
19   */
20  public class KeyHelper {
21  
22  	static class UsedKey {
23  
24  		SymbolShape shape;
25  
26  		char theChar;
27  
28  		@Override
29  		public boolean equals(Object arg0) {
30  			if (arg0 instanceof UsedKey) {
31  				UsedKey uk = (UsedKey) arg0;
32  				return this.shape.equals(uk.shape) && this.theChar == uk.theChar;
33  			} else {
34  				return false;
35  			}
36  
37  		}
38  
39  		public String toString() {
40  			return shape.name() + ":" + theChar;
41  		}
42  
43  		@Override
44  		public int hashCode() {
45  			return theChar + shape.hashCode();
46  		}
47  
48  	}
49  
50  	public List<Symbol> getUsedSymbols() {
51  		List<Symbol> out = new ArrayList<Symbol>(declared.values());
52  		Collections.sort(out);
53  		return out;
54  	}
55  
56  	Set<UsedKey> used = new HashSet<UsedKey>();
57  	Map<String, Symbol> declared = new HashMap<String, Symbol>();
58  
59  	public KeyHelper() {
60  	}
61  
62  	public Symbol createSymbol(String text) {
63  		return createSymbol(text, text);
64  	}
65  
66  	public Symbol createSymbol(String text, String characterOptions) {
67  		Symbol out = declared.get(text);
68  		if (out != null)
69  			return out;
70  
71  		if (characterOptions != null) {
72  			for (int i = 0; i < characterOptions.length(); i++) {
73  				char potential = Character.toUpperCase(characterOptions.charAt(i));
74  				Symbol s = findAvailableShape(text, potential);
75  				if (s != null)
76  					return s;
77  			}
78  		}
79  
80  		for (int i = 0; i < text.length(); i++) {
81  			char potential = Character.toUpperCase(text.charAt(i));
82  			Symbol s = findAvailableShape(text, potential);
83  			if (s != null)
84  				return s;
85  		}
86  
87  		// ok, nothing relevant. return first available symbol
88  		for (char c = 'A'; c <= 'Z'; c++) {
89  			Symbol s = findAvailableShape(text, c);
90  			if (s != null)
91  				return s;
92  		}
93  
94  		// no shapes left to add, something has gone very wrong!
95  		throw new IllegalStateException("There are no more keys to allocate! " + used.size() + " used already.");
96  	}
97  
98  	private Symbol findAvailableShape(String text, char potential) {
99  		for (SymbolShape shape : SymbolShape.values()) {
100 			Symbol out = findAvailableShape(text, potential, shape);
101 
102 			if (out != null) {
103 				declared.put(text, out);
104 				return out;
105 			}
106 		}
107 		return null;
108 	}
109 
110 	private Symbol findAvailableShape(String text, char potential, SymbolShape shape) {
111 		UsedKey option = new UsedKey();
112 		option.shape = shape;
113 		option.theChar = potential;
114 		if (!used.contains(option)) {
115 			Symbol s = new Symbol(text, potential, shape);
116 			used.add(option);
117 			return s;
118 		}
119 
120 		return null;
121 	}
122 
123 	public Symbol createSymbol(String value, char key, SymbolShape shape) {
124 		Symbol out = findAvailableShape(value, key, shape);
125 		if (out != null) {
126 			return out;
127 		}
128 		out = findAvailableShape(value, key);
129 		if (out != null) {
130 			return out;
131 		}
132 
133 		return createSymbol(value, null);
134 	}
135 
136 }