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;
019:
020: import java.io.IOException;
021: import java.io.Serializable;
022: import java.io.StringWriter;
023: import java.util.ArrayList;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Locale;
028: import java.util.Map;
029: import java.util.StringTokenizer;
030: import java.util.logging.Level;
031: import java.util.logging.Logger;
032:
033: import javax.swing.ImageIcon;
034:
035: import de.finix.contelligent.client.gui.GUIDescription;
036: import de.finix.contelligent.client.i18n.Resources;
037: import de.finix.contelligent.client.modules.preferences.PreferencesModule;
038: import de.zeigermann.xml.XMLWriter;
039:
040: public class Type implements Serializable {
041:
042: private static Logger logger = Logger.getLogger(Type.class
043: .getName());
044:
045: public final static String COMPONENT = "contelligent.core.ContelligentComponent";
046:
047: public final static String CONTAINER = "contelligent.core.Container";
048:
049: public final static String CATEGORY = "contelligent.core.Category";
050:
051: public final static String FOLDER = "contelligent.core.Folder";
052:
053: public final static String CONTEXT = "contelligent.core.Context";
054:
055: public final static String SORTED_FOLDER = "contelligent.core.SortedFolder";
056:
057: public final static String LARGE_FOLDER = "contelligent.core.Masswebcontainercontext";
058:
059: public final static String TEXT = "contelligent.core.Text";
060:
061: public final static String ACTION = "contelligent.core.Action";
062:
063: public final static String PAGE = "contelligent.website.Page";
064:
065: public final static String LINK = "contelligent.core.Link";
066:
067: public final static String USER = "contelligent.core.User";
068:
069: public final static String ROLE = "contelligent.core.Role";
070:
071: // public final static String TASK = "WfTask";
072: // XXX from website package
073: public final static String PAGES_FOLDER = "contelligent.website.PagesFolder";
074:
075: // XXX from website package
076: public final static String HTTP_LINK = "contelligent.website.HttpLink";
077:
078: public final static String ERROR = "__ERROR";
079:
080: private String name, typeGroup, super TypeName, gui, iconPath;
081:
082: private ImageIcon icon;
083:
084: private boolean needsSecureTransfer;
085:
086: /**
087: * If this is a sub-type and it just restricts a super-type classImpl is
088: * null. If it extends a super-type or is a new super-type classImpl is
089: * not-null.
090: */
091: private String classImpl;
092:
093: /** a map containing (String/TypeProperty) pairs */
094: private Map<String, TypeProperty> propertyMap = new HashMap<String, TypeProperty>();
095:
096: private Map<String, TypeProperty> effectivePropertyMap = new HashMap<String, TypeProperty>();
097:
098: /** Contains all descriptions in all languages. Language is the key */
099: private Map<String, Description> descriptionMap = new HashMap<String, Description>();
100:
101: private String blueprintPath;
102:
103: /**
104: * Creates a new <code>Type</code> instance. If classImpl is null, this
105: * type is expected to restrict an existing super-type specified by
106: * superTypeName. Should only be called by {@link TypeFactory}.
107: *
108: * @exception TypeCreationException
109: * if an error occurs
110: */
111: protected Type(String name, String icon, String gui,
112: boolean needsSecureTransfer, String typeGroup,
113: String super TypeName, String classImpl,
114: Map<String, TypeProperty> propertyMap, String blueprintPath)
115: throws TypeCreationException {
116: if (name == null
117: || typeGroup == null
118: || ((super TypeName == null && classImpl == null) || propertyMap == null)
119: && blueprintPath == null) {
120: throw new TypeCreationException(Resources
121: .getLocalString("type_parameter_missing"));
122: }
123: this .name = name;
124: this .gui = gui;
125: this .iconPath = icon;
126: this .needsSecureTransfer = needsSecureTransfer;
127: this .typeGroup = typeGroup;
128: this .super TypeName = super TypeName;
129: this .classImpl = classImpl;
130: this .propertyMap = propertyMap;
131: this .effectivePropertyMap.putAll(propertyMap);
132: this .blueprintPath = blueprintPath;
133: }
134:
135: /** Creates a simple type for a blueprint. */
136: public Type(String name, String super TypeName, String blueprintPath)
137: throws TypeCreationException {
138: this (name, null, null, false, "blueprint", super TypeName, null,
139: new HashMap(), blueprintPath);
140: }
141:
142: public boolean allowsSubcomponents() {
143: return (instanceOf(FOLDER) || instanceOf(CONTAINER));
144: }
145:
146: public boolean isBlueprint() {
147: return blueprintPath != null;
148: }
149:
150: public String getIconPath() {
151: return iconPath;
152: }
153:
154: public void setIconPath(String iconPath) {
155: this .iconPath = iconPath;
156: }
157:
158: public ImageIcon getIcon() {
159: if (icon == null) {
160: preloadIcon();
161: }
162: return icon;
163: }
164:
165: public void preloadIcon() {
166: if (icon == null) {
167: if (iconPath != null && iconPath.trim().length() > 0) {
168: icon = Resources.getIcon(iconPath);
169: } else {
170: // get icon from super type...
171: try {
172: icon = TypeFactory.getInstance().getType(
173: super TypeName).getIcon();
174: } catch (TypeNotFoundException e) {
175: icon = Resources.componentNotFoundIcon;
176: }
177: }
178: }
179: }
180:
181: public String getName() {
182: return name;
183: }
184:
185: // FIXME: Should return GUIDescription if available on server side!
186: public String getGUI() {
187: if (gui == null) {
188: if (super TypeName == null) {
189: return null;
190: } else {
191: // recursive request to supertype...
192: try {
193: return TypeFactory.getInstance().getType(
194: super TypeName).getGUI();
195: } catch (TypeNotFoundException e) {
196: logger.log(Level.SEVERE,
197: "Could not resolve super type");
198: return null;
199: }
200: }
201: } else {
202: return gui;
203: }
204: }
205:
206: // FIXME: no description available yet...
207: public List<GUIDescription> getGUIDescriptions() {
208: List<GUIDescription> guiDescriptions = new ArrayList<GUIDescription>();
209: if (getGUI().indexOf(',') > 0) {
210: StringTokenizer tokenizer = new StringTokenizer(gui, ",");
211: while (tokenizer.hasMoreTokens()) {
212: guiDescriptions.add(new GUIDescription(tokenizer
213: .nextToken()));
214: }
215: } else {
216: guiDescriptions.add(new GUIDescription(getGUI()));
217: }
218: return guiDescriptions;
219: }
220:
221: public void setGUI(String gui) {
222: this .gui = gui;
223: }
224:
225: public String getBlueprintPath() {
226: return blueprintPath;
227: }
228:
229: public void setBlueprintPath(String blueprintPath) {
230: this .blueprintPath = blueprintPath;
231: }
232:
233: public String getTypeGroup() {
234: return typeGroup;
235: }
236:
237: public void setTypeGroup(String typeGroup) {
238: this .typeGroup = typeGroup;
239: }
240:
241: public String getClassImpl() {
242: return classImpl;
243: }
244:
245: public void setClassImpl(String classImpl) {
246: this .classImpl = classImpl;
247: }
248:
249: public String getSuperTypeName() {
250: return super TypeName;
251: }
252:
253: public void setSuperTypeName(String super TypeName) {
254: this .super TypeName = super TypeName;
255: }
256:
257: public Map<String, TypeProperty> getPropertyMap() {
258: return propertyMap;
259: }
260:
261: public Map<String, TypeProperty> getEffectivePropertyMap() {
262: return effectivePropertyMap;
263: }
264:
265: public boolean isPropertyInherited(String name) {
266: if (propertyMap.containsKey(name)) {
267: logger.log(Level.FINEST, "Property '" + name
268: + "' of type '" + getName()
269: + "' is in property map");
270: return false;
271: }
272: logger.log(Level.FINEST, "Property '" + name + "' of type '"
273: + getName() + "' is not in property map");
274: return true;
275: }
276:
277: public boolean hasProperty(String name) {
278: if (effectivePropertyMap.containsKey(name)) {
279: return true;
280: }
281: return false;
282: }
283:
284: public TypeProperty getProperty(String name)
285: throws TypePropertyNotFoundException {
286: if (!effectivePropertyMap.containsKey(name)) {
287: throw new TypePropertyNotFoundException(Resources
288: .getLocalString("type_property_not_found",
289: new String[] { name, getName() }));
290: }
291:
292: return (TypeProperty) effectivePropertyMap.get(name);
293: }
294:
295: public String getPropertyValue(String name)
296: throws TypePropertyNotFoundException {
297: if (!effectivePropertyMap.containsKey(name)) {
298: throw new TypePropertyNotFoundException(Resources
299: .getLocalString("type_property_not_found",
300: new String[] { name, getName() }));
301: }
302:
303: return ((TypeProperty) effectivePropertyMap.get(name))
304: .getValue();
305: }
306:
307: public void addInheritedProperties(
308: Map<String, TypeProperty> propertyMap) {
309: this .effectivePropertyMap.putAll(propertyMap);
310: }
311:
312: public boolean instanceOf(String typeName) {
313: if (name.equals(typeName)) {
314: return true;
315: }
316: if (super TypeName == null) {
317: return false;
318: } else {
319: // recursive request to supertype...
320: try {
321: return TypeFactory.getInstance().getType(super TypeName)
322: .instanceOf(typeName);
323: } catch (TypeNotFoundException e) {
324: // serverside configuration error
325: e.printStackTrace();
326: }
327: }
328: return false;
329: }
330:
331: public String hierarchy() {
332: StringBuffer hierarchy = new StringBuffer();
333: hierarchy.append(getName());
334: hierarchy(getSuperTypeName(), hierarchy);
335: return hierarchy.toString();
336: }
337:
338: public void hierarchy(String super TypeName, StringBuffer hierarchy) {
339: if (super TypeName == null)
340: return;
341: // recursive request to supertype...
342: hierarchy.append("\u00a0<br>\u00a0");
343: hierarchy.append(super TypeName);
344: try {
345: hierarchy(TypeFactory.getInstance().getType(super TypeName)
346: .getSuperTypeName(), hierarchy);
347: } catch (TypeNotFoundException e) {
348: // serverside configuration error
349: e.printStackTrace();
350: }
351: }
352:
353: public String toString() {
354: return ("[Type name=" + name + ", classImpl=" + classImpl
355: + ", super=" + super TypeName + "]");
356: }
357:
358: public void addDescription(String lang, String title, String text,
359: String helpURL) {
360: descriptionMap.put(lang, new Description(lang, title, text,
361: helpURL));
362: }
363:
364: public Description getDescription(String lang) {
365: if (descriptionMap.containsKey(lang)) {
366: return (Description) descriptionMap.get(lang);
367: } else if (descriptionMap.containsKey(PreferencesModule
368: .getDefaultLanguage())) {
369: return (Description) descriptionMap.get(PreferencesModule
370: .getDefaultLanguage());
371: }
372: return null;
373: }
374:
375: public String getDescriptionText(String lang) {
376: Description description = getDescription(lang);
377: return (description != null ? description.getText() : "");
378: }
379:
380: public Description getDescription(Locale locale) {
381: return getDescription(locale.getLanguage());
382: }
383:
384: public Map<String, Description> getDescriptions() {
385: return descriptionMap;
386: }
387:
388: public void addDescription(String key, Description description) {
389: descriptionMap.put(key, description);
390: }
391:
392: public void writeToXML(XMLWriter xmlWriter) throws IOException {
393: xmlWriter.writeStartTag(XMLWriter.createStartTag("type",
394: new String[][] { { "name", getName() },
395: { "group", getTypeGroup() },
396: { "classImpl", getClassImpl() },
397: { "blueprintPath", getBlueprintPath() } }));
398:
399: // XXX do not check if this is an extending or restricting type as only
400: // restricted types can be created in client
401: xmlWriter.writeEmptyElement(XMLWriter.createEmptyTag(
402: "restricts", "type", getSuperTypeName()));
403:
404: xmlWriter
405: .writeStartTag(XMLWriter
406: .createStartTag(
407: "meta-info",
408: new String[][] {
409: { "gui", getGUI() },
410: { "icon", getIconPath() },
411: {
412: "needsSecureTransfer",
413: String
414: .valueOf(needsSecureTransfer) } }));
415:
416: for (Iterator iterator = descriptionMap.values().iterator(); iterator
417: .hasNext();) {
418: Description description = (Description) iterator.next();
419: description.writeToXML(xmlWriter);
420: }
421: xmlWriter.writeEndTag("</meta-info>");
422:
423: for (Iterator iterator = propertyMap.values().iterator(); iterator
424: .hasNext();) {
425: TypeProperty property = (TypeProperty) iterator.next();
426: property.writeToXML(xmlWriter);
427: }
428: xmlWriter.writeEndTag("</type>");
429: }
430:
431: public String toXML() {
432: StringWriter sw = new StringWriter();
433: try {
434: XMLWriter xmlWriter = new XMLWriter(sw);
435: writeToXML(xmlWriter);
436: xmlWriter.flush();
437: return sw.toString();
438: } catch (IOException ioe) {
439: logger.log(Level.SEVERE, "Could not convert type to XML",
440: ioe);
441: return null;
442: }
443: }
444:
445: }
|