001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.client.base.category;
019:
020: import java.util.ArrayList;
021: import java.util.Collections;
022: import java.util.Comparator;
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.StringTokenizer;
028: import java.util.Vector;
029: import java.util.logging.Level;
030: import java.util.logging.Logger;
031:
032: import de.finix.contelligent.client.base.Description;
033: import de.finix.contelligent.client.base.resource.ContelligentResource;
034: import de.finix.contelligent.client.base.resource.ContelligentResourceReference;
035: import de.finix.contelligent.client.i18n.Resources;
036:
037: public class ContelligentCategoryManager {
038: private static Logger logger = Logger
039: .getLogger(ContelligentCategoryManager.class.getName());
040:
041: private final static char IDENTIFIER_SEPARATOR = ':';
042:
043: private static ContelligentCategoryManager categoryManager = null;
044:
045: private List<ContelligentCategory> definedCategories = new Vector<ContelligentCategory>();
046:
047: private static CategoryComparator categoryComparator = new CategoryComparator();
048:
049: public static String createUniqueCategoryIdentifier(
050: List<ContelligentCategory> sensitiveCategories,
051: Map categoryMap) {
052: // sort categories by name
053: Collections.sort(sensitiveCategories, categoryComparator);
054: // concat category names
055: StringBuffer identifier = new StringBuffer(255);
056: for (Iterator i = sensitiveCategories.iterator(); i.hasNext();) {
057: ContelligentCategory category = (ContelligentCategory) i
058: .next();
059: String categoryValue = ContelligentCategoryManager
060: .getInstance()
061: .getCategoryByName(category.getName())
062: .getDefaultValue();
063: if (categoryMap != null
064: && categoryMap.containsKey(category.getName())) {
065: categoryValue = (String) categoryMap.get(category
066: .getName());
067: }
068: if (categoryValue != null) {
069: identifier.append(IDENTIFIER_SEPARATOR);
070: identifier.append(categoryValue);
071: }
072: }
073: return identifier.toString();
074: }
075:
076: private static void getSensitveCategoryCombinations(
077: Map<String, Map<String, String>> combinations,
078: Map<String, String> categoryMap,
079: List<ContelligentCategory> sensitiveCategories,
080: List<ContelligentCategory> globalCategories) {
081: if (sensitiveCategories.size() == 0) {
082: String identifier = createUniqueCategoryIdentifier(
083: globalCategories, categoryMap);
084: Map<String, String> map = new HashMap<String, String>();
085: map.putAll(categoryMap);
086: combinations.put(identifier, map);
087: } else {
088: ContelligentCategory category = (ContelligentCategory) sensitiveCategories
089: .get(0);
090:
091: List<ContelligentCategory> newSensitiveCategories = new ArrayList<ContelligentCategory>(
092: sensitiveCategories);
093: newSensitiveCategories.remove(category);
094:
095: String name = category.getName();
096: String[] values = category.getSupportedValues();
097: for (int j = 0; j < values.length; j++) {
098: String categoryValue = values[j];
099: categoryMap.put(name, categoryValue);
100: getSensitveCategoryCombinations(combinations,
101: categoryMap, newSensitiveCategories,
102: globalCategories);
103: }
104: }
105: }
106:
107: public static Map getSensitveCategoryCombinations(
108: List<ContelligentCategory> sensitiveCategories) {
109: synchronized (sensitiveCategories) {
110: Collections.sort(sensitiveCategories, categoryComparator);
111: Map<String, String> categoryMap = new HashMap<String, String>();
112: Map<String, Map<String, String>> combinations = new HashMap<String, Map<String, String>>(); // a map of identifier (String)
113: // -> categoryMap (Map)
114: getSensitveCategoryCombinations(combinations, categoryMap,
115: sensitiveCategories, sensitiveCategories);
116: return combinations;
117: }
118: }
119:
120: /** Creates a new instance of CategoryManager */
121: private ContelligentCategoryManager() {
122: }
123:
124: /**
125: * This method creates a categoryManager instance if there is none and
126: * returns it. - singleton -
127: */
128: public static ContelligentCategoryManager getInstance() {
129: if (categoryManager == null) {
130: categoryManager = new ContelligentCategoryManager();
131: }
132: return categoryManager;
133: }
134:
135: public void addCategory(ContelligentCategory category) {
136: definedCategories.add(category);
137: }
138:
139: public ContelligentCategory[] getDefinedCategories() {
140: return (ContelligentCategory[]) definedCategories
141: .toArray(new ContelligentCategory[] {});
142: }
143:
144: public ContelligentCategory getCategoryByName(String name) {
145: for (Iterator i = definedCategories.iterator(); i.hasNext();) {
146: ContelligentCategory category = (ContelligentCategory) i
147: .next();
148: if (category.equals(name)) {
149: return category;
150: }
151: }
152: return null;
153: }
154:
155: public boolean isCategoryDefined(ContelligentCategory category) {
156: for (Iterator i = definedCategories.iterator(); i.hasNext();) {
157: ContelligentCategory compare = (ContelligentCategory) i
158: .next();
159: if (compare.equals(category)) {
160: return true;
161: }
162: }
163: return false;
164: }
165:
166: public String getCategoryTitleByName(String name) {
167: ContelligentCategory category = getCategoryByName(name);
168: if (category == null)
169: return name;
170: name = category.getName();
171: Description description = category.getDescription(Resources
172: .getLocale());
173: if (description != null) {
174: name = description.getTitle();
175: }
176: return name;
177: }
178:
179: public void completeCategoryToResourceMapping(
180: List<ContelligentCategory> sensitiveCategories,
181: Map<String, Object> categoryToResourceMap) {
182: if (sensitiveCategories.size() > 0) {
183: Collections.sort(sensitiveCategories, categoryComparator);
184: // create all possible identifiers
185:
186: String original;
187: do {
188: original = null;
189: String fallback = null;
190: String prefix = null;
191: for (Iterator i = categoryToResourceMap.keySet()
192: .iterator(); i.hasNext();) {
193: fallback = (String) i.next();
194: if (fallback.indexOf(IDENTIFIER_SEPARATOR) != -1) {
195: prefix = fallback.substring(0, fallback
196: .indexOf(IDENTIFIER_SEPARATOR));
197: if ((original = findOriginal(
198: sensitiveCategories, prefix, fallback
199: .substring(prefix.length()),
200: categoryToResourceMap)) != null) {
201: break;
202: }
203: }
204: }
205: if (original != null) {
206: Object object = categoryToResourceMap.get(fallback);
207: if (object instanceof ContelligentResource) {
208: ContelligentResource resource = (ContelligentResource) object;
209: object = new ContelligentResourceReference(
210: fallback, resource);
211: }
212: categoryToResourceMap
213: .put(prefix + original, object);
214: logger.log(Level.FINE, "Add new mapping: '"
215: + prefix + original
216: + "', it gets the same object as '"
217: + fallback + "'");
218: }
219: } while (original != null);
220: }
221: }
222:
223: private String findOriginal(List sensitiveCategories,
224: String prefix, String combination, Map categoryToResourceMap) {
225: StringTokenizer tokenizer = new StringTokenizer(combination,
226: String.valueOf(IDENTIFIER_SEPARATOR));
227: List<String> tokenList = new Vector<String>();
228: while (tokenizer.hasMoreTokens()) {
229: tokenList.add(tokenizer.nextToken());
230: }
231: String[] tokens = (String[]) tokenList
232: .toArray(new String[tokenList.size()]);
233: for (int i = 0; i < tokens.length; i++) {
234: String token = tokens[i];
235: ContelligentCategory currentCategory = getCategoryByName(((ContelligentCategory) sensitiveCategories
236: .get(i)).getName());
237: if (currentCategory != null) {
238: String[] possibleValues = currentCategory
239: .getSupportedValues();
240: for (int j = 0; j < possibleValues.length; j++) {
241: if (!possibleValues[j].equals(token)) {
242: String fallback = currentCategory
243: .getFallbackValue(possibleValues[j]);
244: if (fallback != null && fallback.equals(token)) {
245: // test if this is an original for some existing
246: // combination
247: StringBuffer combinationBuffer = new StringBuffer(
248: 255);
249: int k = 0;
250: for (k = 0; k < sensitiveCategories.size(); k++) {
251: combinationBuffer
252: .append(IDENTIFIER_SEPARATOR);
253: // build combination
254: if (k != i) {
255: combinationBuffer.append(tokens[k]);
256: } else {
257: combinationBuffer
258: .append(possibleValues[j]);
259: }
260: }
261: // check if combination is in map
262: String newCombination = combinationBuffer
263: .toString();
264: if (!categoryToResourceMap
265: .containsKey(prefix
266: + newCombination.toString())) {
267: // new fallback found
268: return newCombination;
269: }
270: }
271: }
272: }
273: }
274: }
275: return null;
276: }
277:
278: private final static class CategoryComparator implements
279: Comparator<ContelligentCategory> {
280: public int compare(ContelligentCategory o1,
281: ContelligentCategory o2) {
282: return o1.getName().compareTo(o2.getName());
283: }
284:
285: public boolean equals(Object obj) {
286: if (obj == this ) {
287: return true;
288: }
289:
290: return false;
291: }
292:
293: public int hashCode() {
294: return -1;
295: }
296:
297: }
298: }
|