001: /*
002: * Project: AMODA - Abstract Modeled Application
003: * Class: de.gulden.framework.amoda.generic.metadata.GenericMetadata
004: * Version: snapshot-beautyj-1.1
005: *
006: * Date: 2004-09-29
007: *
008: * This is a snapshot version of the AMODA 0.2 development branch,
009: * it is not released as a seperate version.
010: * For AMODA, see http://amoda.berlios.de/.
011: *
012: * This is licensed under the GNU Lesser General Public License (LGPL)
013: * and comes with NO WARRANTY.
014: *
015: * Author: Jens Gulden
016: * Email: amoda@jensgulden.de
017: */
018:
019: package de.gulden.framework.amoda.generic.metadata;
020:
021: import de.gulden.framework.amoda.generic.data.*;
022: import de.gulden.framework.amoda.model.core.*;
023: import de.gulden.framework.amoda.model.metadata.*;
024: import de.gulden.framework.amoda.model.metadata.Metadata;
025: import de.gulden.util.Toolbox;
026: import de.gulden.util.xml.*;
027: import de.gulden.util.xml.XMLToolbox;
028: import de.gulden.util.xml.serializer.*;
029: import de.gulden.util.xml.serializer.XMLSerializableActive;
030: import java.lang.*;
031: import java.net.*;
032: import java.util.*;
033: import javax.swing.*;
034: import org.w3c.dom.*;
035:
036: /**
037: * Class GenericMetadata.
038: *
039: * @author Jens Gulden
040: * @version snapshot-beautyj-1.1
041: */
042: public class GenericMetadata implements Metadata, XMLSerializableActive {
043:
044: // ------------------------------------------------------------------------
045: // --- fields ---
046: // ------------------------------------------------------------------------
047:
048: protected static Hashtable titlesCache = new Hashtable();
049:
050: protected static Hashtable iconsCache = new Hashtable();
051:
052: protected Hashtable metadataEntries;
053:
054: protected GenericMetadataSchema genericMetadataSchema;
055:
056: public Collection genericMetadataEntry = new ArrayList();
057:
058: // ------------------------------------------------------------------------
059: // --- constructor ---
060: // ------------------------------------------------------------------------
061:
062: public GenericMetadata() {
063: metadataEntries = new Hashtable();
064: }
065:
066: // ------------------------------------------------------------------------
067: // --- methods ---
068: // ------------------------------------------------------------------------
069:
070: public GenericMetadataSchema getGenericMetadataSchema() {
071: return genericMetadataSchema;
072: }
073:
074: public void setGenericMetadataSchema(
075: GenericMetadataSchema genericMetadataSchema) {
076: this .genericMetadataSchema = genericMetadataSchema;
077: }
078:
079: public Collection getGenericMetadataEntrys() {
080: return genericMetadataEntry;
081: }
082:
083: public void addGenericMetadataEntry(
084: GenericMetadataEntry genericMetadataEntry) {
085: if (!this .genericMetadataEntry.contains(genericMetadataEntry)) {
086: this .genericMetadataEntry.add(genericMetadataEntry);
087: genericMetadataEntry.setGenericMetadata(this );
088: }
089: }
090:
091: public void removeGenericMetadataEntry(
092: GenericMetadataEntry genericMetadataEntry) {
093: boolean removed = this .genericMetadataEntry
094: .remove(genericMetadataEntry);
095: if (removed)
096: genericMetadataEntry
097: .setGenericMetadata((GenericMetadata) null);
098: }
099:
100: public String get(String name) {
101: return get(name, "");
102: }
103:
104: public String get(String name, String def) {
105: // never returns null, if not found, returns ""
106: GenericMetadataEntry entry = (GenericMetadataEntry) getEntry(name);
107: if (entry != null) {
108: String s = entry.getString();
109: if (s != null) {
110: s = s.trim();
111: s = replaceMultipleBlanksWithLineBreaks(s);
112: return s;
113: } else {
114: return def;
115: }
116: } else {
117: return def;
118: }
119: }
120:
121: public Collection getEntries() {
122: return getGenericMetadataEntrys();
123: }
124:
125: public MetadataEntry getEntry(String name) {
126: return (MetadataEntry) metadataEntries.get(name);
127: }
128:
129: public String toString() {
130: StringBuffer sb = new StringBuffer();
131: for (Iterator it = getEntries().iterator(); it.hasNext();) {
132: MetadataEntry entry = (MetadataEntry) it.next();
133: sb
134: .append(entry.toString()
135: + de.gulden.framework.amoda.generic.core.GenericApplicationEnvironment.NL);
136: }
137: return sb.toString();
138: }
139:
140: public void set(String name, Object value) {
141: GenericMetadataEntry m = new GenericMetadataEntry(name, value);
142: addEntry(m);
143: }
144:
145: public Element xmlSerialize(Document document,
146: XMLSerializer serializer) {
147: throw new Error("NOT IMPLEMENTED");
148: }
149:
150: public void xmlDeserialize(Element element, XMLSerializer serializer)
151: throws XMLException {
152: Element schemaTag = XMLToolbox.getChild(element,
153: "metadata-schema");
154: if (schemaTag != null) {
155: GenericMetadataSchema schema = new GenericMetadataSchema();
156: serializer.xmlDeserialize(schema, schemaTag);
157: setGenericMetadataSchema(schema);
158: }
159: // allow any tag as child, treating tag-name as key and tag-content as value
160: Element e = XMLToolbox.getFirstChild(element);
161: while (e != null) {
162: String name = e.getTagName();
163: String source = e.getAttribute("source"); // may be null
164: String valueStr = XMLToolbox.getText(e);
165: if (Toolbox.empty(valueStr)) {
166: valueStr = XMLToolbox.getLangstring(e);
167: }
168: if (!Toolbox.empty(valueStr)) {
169: GenericMetadataEntry m = new GenericMetadataEntry();
170: m.setName(name);
171: m.setSource(source);
172: m.parseString(valueStr);
173: this .addEntry(m);
174: }
175: e = XMLToolbox.getNextSibling(e);
176: }
177: }
178:
179: public MetadataSchema getSchema() {
180: return getGenericMetadataSchema();
181: }
182:
183: protected void addEntry(GenericMetadataEntry entry) {
184: addGenericMetadataEntry(entry);
185: metadataEntries.put(entry.getName(), entry);
186: }
187:
188: // ------------------------------------------------------------------------
189: // --- static methods ---
190: // ------------------------------------------------------------------------
191:
192: public static String findTitle(ApplicationMember member) {
193: String title = (String) titlesCache.get(member);
194: if (title == null) { // not cached yet
195: // title given?
196: title = member.getMetadata().get("title");
197: if (Toolbox.isEmpty(title)) {
198: // no: at least try to find via id
199: if (member instanceof de.gulden.framework.amoda.generic.core.GenericApplicationMemberAbstract) {
200: de.gulden.framework.amoda.generic.core.GenericApplicationMemberAbstract m = (de.gulden.framework.amoda.generic.core.GenericApplicationMemberAbstract) member;
201: String id = m.getId();
202: de.gulden.framework.amoda.model.data.CompositeGroup parent = m
203: .getParent();
204: if (parent != null) {
205: String parentId = parent.getId();
206: if (id.startsWith(parentId + ".")) { // special: if parent's name is first part, remove
207: id = id.substring(parentId.length() + 1);
208: }
209: }
210: title = Toolbox.capitalize(id).replace('-', ' ')
211: .replace('_', ' ').replace('.', ' ');
212: }
213: }
214: titlesCache.put(member, title);
215: }
216: return title;
217: }
218:
219: public static ImageIcon findIcon(ApplicationMember member) {
220: ImageIcon icon = (ImageIcon) iconsCache.get(member);
221: if (icon == null) { // not cached yet
222: java.net.URL url = findIconResource(member);
223: if (url != null) {
224: icon = new ImageIcon(url);
225: iconsCache.put(member, icon);
226: }
227: }
228: return icon;
229: }
230:
231: public static URL findIconResource(ApplicationMember member) {
232: java.net.URL url = null;
233: // icon-resource explicitly given?
234: String icon = member.getMetadata().get("icon").trim();
235: String base = member.getApplication().getOptions().getString(
236: "resource-base-icons");
237: if (!base.endsWith("/")) {
238: base += "/";
239: }
240: if (!Toolbox.empty(icon)) {
241: if (!icon.startsWith("/")) { // not absolute
242: icon = base + icon;
243: }
244: url = member.getClass().getResource(icon);
245: }
246: // no: at least try to find via id
247: if (member instanceof de.gulden.framework.amoda.generic.core.GenericApplicationMemberAbstract) {
248: de.gulden.framework.amoda.generic.core.GenericApplicationMemberAbstract m = (de.gulden.framework.amoda.generic.core.GenericApplicationMemberAbstract) member;
249: icon = base + m.getId() + ".png";
250: url = member.getClass().getResource(icon);
251: if (url == null) {
252: icon = base + m.getId() + ".gif";
253: url = member.getClass().getResource(icon);
254: }
255: if (url == null) {
256: icon = base + m.getId() + ".bmp";
257: url = member.getClass().getResource(icon);
258: }
259: if (url == null) {
260: icon = base + m.getId() + ".jpg";
261: url = member.getClass().getResource(icon);
262: }
263: }
264: return url;
265: }
266:
267: protected static String replaceMultipleBlanksWithLineBreaks(String s) {
268: int pos = 0;
269: char prev = 'X';
270: int startblank = -1;
271: while (pos < s.length()) {
272: char c = s.charAt(pos);
273: if (Character.isWhitespace(c)) {
274: if (!Character.isWhitespace(prev)) {
275: startblank = pos;
276: }
277: } else { // no whitespace
278: if (Character.isWhitespace(prev)) { // but prev was
279: if ((pos - startblank) > 1) { // more than one
280: return s.substring(0, startblank)
281: + "\n"
282: + replaceMultipleBlanksWithLineBreaks(s
283: .substring(pos));
284: }
285: }
286: }
287: prev = c;
288: pos++;
289: }
290: if (Character.isWhitespace(prev)) { // last one still was whitespace
291: if ((pos - startblank) > 1) { // more than one
292: return s.substring(0, startblank) + "\n";
293: }
294: }
295: return s;
296: }
297:
298: } // end GenericMetadata
|