001: /*******************************************************************************
002: * Copyright (c) 2003, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.core.text.bundle;
011:
012: import java.util.ArrayList;
013: import java.util.Enumeration;
014: import java.util.Iterator;
015: import java.util.Set;
016: import java.util.TreeMap;
017:
018: import org.eclipse.osgi.util.ManifestElement;
019: import org.eclipse.pde.internal.core.bundle.BundleObject;
020: import org.eclipse.pde.internal.core.ibundle.IBundleModel;
021: import org.osgi.framework.BundleException;
022:
023: public class PDEManifestElement extends BundleObject {
024:
025: private static final long serialVersionUID = 1L;
026:
027: protected String[] fValueComponents;
028: protected TreeMap fAttributes;
029: protected TreeMap fDirectives;
030:
031: protected transient ManifestHeader fHeader;
032:
033: public PDEManifestElement(ManifestHeader header, String value) {
034: setHeader(header);
035: setValue(value);
036: setModel(fHeader.getBundle().getModel());
037: }
038:
039: protected PDEManifestElement(ManifestHeader header,
040: ManifestElement manifestElement) {
041: setHeader(header);
042: init(manifestElement);
043: setModel(fHeader.getBundle().getModel());
044: }
045:
046: public String[] getValueComponents() {
047: return fValueComponents;
048: }
049:
050: protected void setValueComponents(String[] valueComponents) {
051: fValueComponents = valueComponents;
052: }
053:
054: public String[] getAttributes(String key) {
055: return getTableValues(fAttributes, key);
056: }
057:
058: public String getAttribute(String key) {
059: return getTableValue(fAttributes, key);
060: }
061:
062: public Set getKeys() {
063: return getTableKeys(fAttributes);
064: }
065:
066: public void addAttribute(String key, String value) {
067: fAttributes = addTableValue(fAttributes, key, value);
068: }
069:
070: public void setAttribute(String key, String value) {
071: fAttributes = setTableValue(fAttributes, key, value);
072: }
073:
074: public String getDirective(String key) {
075: return getTableValue(fDirectives, key);
076: }
077:
078: public String[] getDirectives(String key) {
079: return getTableValues(fDirectives, key);
080: }
081:
082: public Set getDirectiveKeys() {
083: return getTableKeys(fDirectives);
084: }
085:
086: public void addDirective(String key, String value) {
087: fDirectives = addTableValue(fDirectives, key, value);
088: }
089:
090: public void setDirective(String key, String value) {
091: fDirectives = setTableValue(fDirectives, key, value);
092: }
093:
094: private String getTableValue(TreeMap table, String key) {
095: if (table == null)
096: return null;
097: Object result = table.get(key);
098: if (result == null)
099: return null;
100: if (result instanceof String)
101: return (String) result;
102:
103: ArrayList valueList = (ArrayList) result;
104: //return the last value
105: return (String) valueList.get(valueList.size() - 1);
106: }
107:
108: private String[] getTableValues(TreeMap table, String key) {
109: if (table == null)
110: return null;
111: Object result = table.get(key);
112: if (result == null)
113: return null;
114: if (result instanceof String)
115: return new String[] { (String) result };
116: ArrayList valueList = (ArrayList) result;
117: return (String[]) valueList
118: .toArray(new String[valueList.size()]);
119: }
120:
121: private Set getTableKeys(TreeMap table) {
122: if (table == null)
123: return null;
124: return table.keySet();
125: }
126:
127: private TreeMap addTableValue(TreeMap table, String key,
128: String value) {
129: if (table == null) {
130: table = new TreeMap();
131: }
132: Object curValue = table.get(key);
133: if (curValue != null) {
134: ArrayList newList;
135: // create a list to contain multiple values
136: if (curValue instanceof ArrayList) {
137: newList = (ArrayList) curValue;
138: } else {
139: newList = new ArrayList(5);
140: newList.add(curValue);
141: }
142: newList.add(value);
143: table.put(key, newList);
144: } else {
145: table.put(key, value);
146: }
147: return table;
148: }
149:
150: private TreeMap setTableValue(TreeMap table, String key,
151: String value) {
152: if (table == null) {
153: table = new TreeMap();
154: }
155: if (value == null || value.trim().length() == 0)
156: table.remove(key);
157: else {
158: table.put(key, value);
159: }
160: return table;
161: }
162:
163: public void setValue(String value) {
164: if (value == null) {
165: setValueComponents(new String[0]);
166: return;
167: }
168: try {
169: ManifestElement[] elements = ManifestElement.parseHeader(
170: fHeader.fName, value);
171: if (elements != null && elements.length > 0)
172: init(elements[0]);
173: } catch (BundleException e) {
174: }
175: }
176:
177: private void init(ManifestElement manifestElement) {
178: setValueComponents(manifestElement.getValueComponents());
179: Enumeration attKeys = manifestElement.getKeys();
180: if (attKeys != null) {
181: while (attKeys.hasMoreElements()) {
182: String attKey = (String) attKeys.nextElement();
183: String[] values = ManifestElement
184: .getArrayFromList(manifestElement
185: .getAttribute(attKey));
186: for (int i = 0; i < values.length; i++)
187: addAttribute(attKey, values[i]);
188: }
189: }
190: Enumeration dirKeys = manifestElement.getDirectiveKeys();
191: if (dirKeys != null) {
192: while (dirKeys.hasMoreElements()) {
193: String dirKey = (String) dirKeys.nextElement();
194: String[] values = ManifestElement
195: .getArrayFromList(manifestElement
196: .getDirective(dirKey));
197: for (int i = 0; i < values.length; i++)
198: addDirective(dirKey, values[i]);
199: }
200: }
201: }
202:
203: public String write() {
204: StringBuffer sb = new StringBuffer(getValue());
205: appendValuesToBuffer(sb, fAttributes);
206: appendValuesToBuffer(sb, fDirectives);
207: return sb.toString();
208: }
209:
210: public String getValue() {
211: StringBuffer sb = new StringBuffer();
212: if (fValueComponents == null)
213: return ""; //$NON-NLS-1$
214: for (int i = 0; i < fValueComponents.length; i++) {
215: if (i != 0)
216: sb.append("; "); //$NON-NLS-1$
217: sb.append(fValueComponents[i]);
218: }
219: return sb.toString();
220: }
221:
222: protected void appendValuesToBuffer(StringBuffer sb, TreeMap table) {
223: if (table == null)
224: return;
225: Iterator dkeys = table.keySet().iterator();
226: while (dkeys.hasNext()) {
227: String dkey = (String) dkeys.next();
228: Object value = table.get(dkey);
229: if (value == null)
230: continue;
231: sb.append(";"); //$NON-NLS-1$
232: sb.append(dkey);
233: sb.append(table.equals(fDirectives) ? ":=" : "="); //$NON-NLS-1$ //$NON-NLS-2$
234:
235: if (value instanceof String) {
236: boolean wrap = shouldWrap(value.toString());
237: if (wrap)
238: sb.append("\""); //$NON-NLS-1$
239: sb.append(value);
240: if (wrap)
241: sb.append("\""); //$NON-NLS-1$
242: } else if (value instanceof ArrayList) {
243: ArrayList values = (ArrayList) value;
244: boolean wrap = (values.size() > 1 || (values.size() == 1 && shouldWrap(values
245: .get(0).toString())));
246: if (wrap)
247: sb.append("\""); //$NON-NLS-1$
248: for (int i = 0; i < values.size(); i++) {
249: if (i != 0)
250: sb.append(","); //$NON-NLS-1$
251: sb.append(values.get(i));
252: }
253: if (wrap)
254: sb.append("\""); //$NON-NLS-1$
255: }
256: }
257: }
258:
259: private boolean shouldWrap(String value) {
260: return value.indexOf(' ') != -1 || value.indexOf(',') != -1
261: || value.indexOf('.') != -1 || value.indexOf('[') != -1
262: || value.indexOf('(') != -1;
263: }
264:
265: public ManifestHeader getHeader() {
266: return fHeader;
267: }
268:
269: public void setHeader(ManifestHeader header) {
270: fHeader = header;
271: }
272:
273: /**
274: * @param model
275: * @param header
276: */
277: public void reconnect(IBundleModel model, ManifestHeader header) {
278: super .reconnect(model);
279: // Transient Field: Header
280: fHeader = header;
281: }
282:
283: }
|