001: /*******************************************************************************
002: * Copyright (c) 2005, 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.Map;
014: import java.util.TreeMap;
015: import java.util.Vector;
016:
017: import org.eclipse.osgi.util.ManifestElement;
018: import org.eclipse.pde.core.IModelChangedEvent;
019: import org.eclipse.pde.internal.core.bundle.BundleObject;
020: import org.eclipse.pde.internal.core.ibundle.IBundle;
021: import org.osgi.framework.BundleException;
022:
023: public class CompositeManifestHeader extends ManifestHeader {
024:
025: private static final PDEManifestElement[] NO_ELEMENTS = new PDEManifestElement[0];
026:
027: private static final long serialVersionUID = 1L;
028:
029: private boolean fSort;
030:
031: protected ArrayList fManifestElements;
032:
033: protected Map fElementMap;
034:
035: public CompositeManifestHeader(String name, String value,
036: IBundle bundle, String lineDelimiter) {
037: this (name, value, bundle, lineDelimiter, false);
038: }
039:
040: public CompositeManifestHeader(String name, String value,
041: IBundle bundle, String lineDelimiter, boolean sort) {
042: fName = name;
043: fBundle = bundle;
044: fLineDelimiter = lineDelimiter;
045: setModel(fBundle.getModel());
046: fSort = sort;
047: fValue = value;
048: processValue(value);
049: }
050:
051: protected void processValue(String value) {
052: try {
053: ManifestElement[] elements = ManifestElement.parseHeader(
054: fName, value);
055: for (int i = 0; i < elements.length; i++)
056: addManifestElement(createElement(elements[i]), false);
057: } catch (BundleException e) {
058: }
059: }
060:
061: protected PDEManifestElement createElement(ManifestElement element) {
062: return new PDEManifestElement(this , element);
063: }
064:
065: public void update() {
066: // let subclasses fire changes
067: update(false);
068: }
069:
070: public void update(boolean notify) {
071: StringBuffer sb = new StringBuffer();
072: PDEManifestElement[] elements = getElements();
073: for (int i = 0; i < elements.length; i++) {
074: if (sb.length() > 0) {
075: sb.append(","); //$NON-NLS-1$
076: sb.append(fLineDelimiter);
077: sb.append(" "); //$NON-NLS-1$
078: }
079: sb.append(elements[i].write());
080: }
081: String old = fValue;
082: fValue = sb.toString();
083: if (notify)
084: firePropertyChanged(this , fName, old, fValue);
085: }
086:
087: protected void addManifestElement(String value) {
088: addManifestElement(new PDEManifestElement(this , value));
089: }
090:
091: /**
092: * @param value
093: * @param index
094: */
095: protected void addManifestElement(String value, int index) {
096: PDEManifestElement element = new PDEManifestElement(this , value);
097: addManifestElement(element, index, true);
098: }
099:
100: protected void addManifestElement(PDEManifestElement element) {
101: addManifestElement(element, true);
102: }
103:
104: protected void addManifestElements(PDEManifestElement[] elements) {
105: for (int i = 0; i < elements.length; i++)
106: addManifestElement(elements[i], false);
107: update(false);
108: fireStructureChanged(elements, IModelChangedEvent.INSERT);
109: }
110:
111: protected void addManifestElement(PDEManifestElement element,
112: boolean update) {
113: element.setModel(getModel());
114: element.setHeader(this );
115: if (fSort) {
116: if (fElementMap == null)
117: fElementMap = new TreeMap();
118: fElementMap.put(element.getValue(), element);
119: } else {
120: if (fManifestElements == null)
121: fManifestElements = new ArrayList(1);
122: fManifestElements.add(element);
123: }
124: if (update) {
125: update(false);
126: fireStructureChanged(element, IModelChangedEvent.INSERT);
127: }
128: }
129:
130: protected Object removeManifestElement(PDEManifestElement element) {
131: return removeManifestElement(element.getValue());
132: }
133:
134: protected Object removeManifestElement(String name) {
135: Object object = null;
136: if (fSort) {
137: if (fElementMap != null) {
138: object = fElementMap.remove(name);
139: }
140: } else if (fManifestElements != null) {
141: for (int i = 0; i < fManifestElements.size(); i++) {
142: PDEManifestElement element = (PDEManifestElement) fManifestElements
143: .get(i);
144: if (name.equals(element.getValue()))
145: object = fManifestElements.remove(i);
146: }
147: }
148: update(false);
149: if (object instanceof BundleObject)
150: fireStructureChanged((BundleObject) object,
151: IModelChangedEvent.REMOVE);
152: return object;
153: }
154:
155: public PDEManifestElement[] getElements() {
156: if (fSort && fElementMap != null)
157: return (PDEManifestElement[]) fElementMap.values().toArray(
158: new PDEManifestElement[fElementMap.size()]);
159:
160: if (fManifestElements != null)
161: return (PDEManifestElement[]) fManifestElements
162: .toArray(new PDEManifestElement[fManifestElements
163: .size()]);
164:
165: return NO_ELEMENTS;
166: }
167:
168: public boolean isEmpty() {
169: if (fSort)
170: return fElementMap == null || fElementMap.size() == 0;
171: return fManifestElements == null
172: || fManifestElements.size() == 0;
173: }
174:
175: public boolean hasElement(String name) {
176: if (fSort && fElementMap != null)
177: return fElementMap.containsKey(name);
178:
179: if (fManifestElements != null) {
180: for (int i = 0; i < fManifestElements.size(); i++) {
181: PDEManifestElement element = (PDEManifestElement) fManifestElements
182: .get(i);
183: if (name.equals(element.getValue()))
184: return true;
185: }
186: }
187: return false;
188: }
189:
190: public Vector getElementNames() {
191: PDEManifestElement[] elements = getElements();
192: Vector vector = new Vector(elements.length);
193: for (int i = 0; i < elements.length; i++) {
194: vector.add(elements[i].getValue());
195: }
196: return vector;
197: }
198:
199: public void swap(int index1, int index2) {
200: if (fSort || fManifestElements == null)
201: return;
202: int size = fManifestElements.size();
203: if (index1 >= 0 && index2 >= 0
204: && size > Math.max(index1, index2)) {
205: Object object1 = fManifestElements.get(index1);
206: Object object2 = fManifestElements.get(index2);
207: fManifestElements.set(index1, object2);
208: fManifestElements.set(index2, object1);
209: update(true);
210: }
211: }
212:
213: protected PDEManifestElement getElementAt(int index) {
214: if (fManifestElements != null
215: && fManifestElements.size() > index)
216: return (PDEManifestElement) fManifestElements.get(index);
217: return null;
218: }
219:
220: /**
221: * Method not applicable for headers that are sorted
222: * @param targetElement
223: * @return
224: */
225: public PDEManifestElement getPreviousElement(
226: PDEManifestElement targetElement) {
227: // Ensure we have elements
228: if (fSort == true) {
229: return null;
230: } else if (fManifestElements == null) {
231: return null;
232: } else if (fManifestElements.size() <= 1) {
233: return null;
234: }
235: // Get the index of the target element
236: int targetIndex = fManifestElements.indexOf(targetElement);
237: // Validate index
238: if (targetIndex < 0) {
239: // Target element does not exist
240: return null;
241: } else if (targetIndex == 0) {
242: // Target element has no previous element
243: return null;
244: }
245: // 1 <= index < size()
246: // Get the previous element
247: PDEManifestElement previousElement = (PDEManifestElement) fManifestElements
248: .get(targetIndex - 1);
249:
250: return previousElement;
251: }
252:
253: /**
254: * Method not applicable for headers that are sorted
255: * @param targetElement
256: * @return
257: */
258: public PDEManifestElement getNextElement(
259: PDEManifestElement targetElement) {
260: // Ensure we have elements
261: if (fSort == true) {
262: return null;
263: } else if (fManifestElements == null) {
264: return null;
265: } else if (fManifestElements.size() <= 1) {
266: return null;
267: }
268: // Get the index of the target element
269: int targetIndex = fManifestElements.indexOf(targetElement);
270: // Get the index of the last element
271: int lastIndex = fManifestElements.size() - 1;
272: // Validate index
273: if (targetIndex < 0) {
274: // Target element does not exist
275: return null;
276: } else if (targetIndex >= lastIndex) {
277: // Target element has no next element
278: return null;
279: }
280: // 0 <= index < last element < size()
281: // Get the next element
282: PDEManifestElement nextElement = (PDEManifestElement) fManifestElements
283: .get(targetIndex + 1);
284:
285: return nextElement;
286: }
287:
288: /**
289: * Method not applicable for headers that are sorted
290: * @param element
291: * @param index
292: * @param update
293: */
294: protected void addManifestElement(PDEManifestElement element,
295: int index, boolean update) {
296: // Validate index
297: int elementCount = 0;
298: if (fManifestElements != null) {
299: elementCount = fManifestElements.size();
300: }
301: // 0 <= index <= size()
302: if (fSort == true) {
303: return;
304: } else if (index < 0) {
305: return;
306: } else if (index > elementCount) {
307: return;
308: }
309: // Set element properties
310: element.setModel(getModel());
311: element.setHeader(this );
312: // Add the element to the list
313: if (fManifestElements == null) {
314: // Initialize the element list if not defined
315: fManifestElements = new ArrayList(1);
316: // Add the element to the end of the list
317: fManifestElements.add(element);
318: } else {
319: // Add the element to the list at the specified index
320: fManifestElements.add(index, element);
321: }
322: // Fire event
323: if (update) {
324: update(false);
325: fireStructureChanged(element, IModelChangedEvent.INSERT);
326: }
327: }
328:
329: /**
330: * Method not applicable for headers that are sorted
331: * @param targetElement
332: * @return
333: */
334: public int indexOf(PDEManifestElement targetElement) {
335: if (fSort) {
336: // Elements are sorted. Position is irrelevant
337: return -1;
338: } else if (fManifestElements == null) {
339: // No elements
340: return -1;
341: }
342: return fManifestElements.indexOf(targetElement);
343: }
344:
345: /**
346: * Method not applicable for headers that are sorted
347: * @param element
348: * @param update
349: * @return
350: */
351: protected PDEManifestElement removeManifestElement(
352: PDEManifestElement element, boolean update) {
353: if (fSort) {
354: return null;
355: } else if (fManifestElements == null) {
356: return null;
357: } else if (fManifestElements.size() == 0) {
358: return null;
359: }
360: // Remove the element
361: boolean removed = fManifestElements.remove(element);
362: PDEManifestElement removedElement = null;
363: if (removed) {
364: removedElement = element;
365: }
366: // Fire event
367: if (update) {
368: update(false);
369: fireStructureChanged(removedElement,
370: IModelChangedEvent.REMOVE);
371: }
372: return removedElement;
373: }
374:
375: }
|