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.io.PrintWriter;
013: import java.util.ArrayList;
014: import java.util.Iterator;
015: import java.util.StringTokenizer;
016: import java.util.TreeMap;
017:
018: import org.eclipse.jdt.core.IPackageFragment;
019: import org.eclipse.osgi.util.ManifestElement;
020: import org.eclipse.pde.core.IModelChangedEvent;
021: import org.eclipse.pde.internal.core.ibundle.IBundleModel;
022: import org.osgi.framework.Constants;
023:
024: public class ExportPackageObject extends PackageObject {
025:
026: private static final String INTERNAL = "x-internal"; //$NON-NLS-1$
027: private static final String FRIENDS = "x-friends"; //$NON-NLS-1$
028:
029: private static final long serialVersionUID = 1L;
030:
031: private TreeMap fFriends = new TreeMap();
032:
033: public ExportPackageObject(ManifestHeader header,
034: ManifestElement element, String versionAttribute) {
035: super (header, element, versionAttribute);
036: processFriends();
037: }
038:
039: public ExportPackageObject(ManifestHeader header,
040: IPackageFragment fragment, String versionAttribute) {
041: super (header, fragment.getElementName(), null, versionAttribute);
042: }
043:
044: public ExportPackageObject(ManifestHeader header, String id,
045: String version, String versionAttribute) {
046: super (header, id, version, versionAttribute);
047: }
048:
049: protected void processFriends() {
050: String[] friends = getDirectives(FRIENDS);
051: if (friends != null) {
052: for (int i = 0; i < friends.length; i++) {
053: fFriends.put(friends[i], new PackageFriend(this ,
054: friends[i]));
055: }
056: }
057: }
058:
059: public boolean isInternal() {
060: return "true".equals(getDirective(INTERNAL)) || getDirective(FRIENDS) != null; //$NON-NLS-1$
061: }
062:
063: public void removeInternalDirective() {
064: setDirective(INTERNAL, null);
065: ((CompositeManifestHeader) fHeader).update(true);
066: }
067:
068: public void setInternal(boolean internal) {
069: boolean old = isInternal();
070: if (!internal) {
071: setDirective(INTERNAL, null);
072: setDirective(FRIENDS, null);
073: } else {
074: if (fFriends.size() == 0)
075: setDirective(INTERNAL, "true"); //$NON-NLS-1$
076: else {
077: Iterator iter = fFriends.keySet().iterator();
078: while (iter.hasNext())
079: addDirective(FRIENDS, iter.next().toString());
080: }
081: }
082: fHeader.update();
083: firePropertyChanged(this , INTERNAL, Boolean.toString(old),
084: Boolean.toString(internal));
085: }
086:
087: public PackageFriend[] getFriends() {
088: return (PackageFriend[]) fFriends.values().toArray(
089: new PackageFriend[fFriends.size()]);
090: }
091:
092: public void addFriend(PackageFriend friend) {
093: fFriends.put(friend.getName(), friend);
094: addDirective(FRIENDS, friend.getName());
095: setDirective(INTERNAL, null);
096: fHeader.update();
097: fireStructureChanged(friend, IModelChangedEvent.INSERT);
098: }
099:
100: public void removeFriend(PackageFriend friend) {
101: fFriends.remove(friend.getName());
102: setDirective(FRIENDS, null);
103: if (fFriends.size() == 0)
104: setDirective(INTERNAL, "true"); //$NON-NLS-1$
105: else {
106: Iterator iter = fFriends.keySet().iterator();
107: while (iter.hasNext())
108: addDirective(FRIENDS, iter.next().toString());
109: }
110: fHeader.update();
111: fireStructureChanged(friend, IModelChangedEvent.REMOVE);
112: }
113:
114: public boolean hasFriend(String name) {
115: return fFriends.containsKey(name);
116: }
117:
118: public boolean hasSameVisibility(ExportPackageObject object) {
119: if (object.isInternal() != isInternal())
120: return false;
121:
122: if (fFriends.size() != object.fFriends.size())
123: return false;
124:
125: Iterator iter = fFriends.keySet().iterator();
126: while (iter.hasNext()) {
127: if (!object.fFriends.containsKey(iter.next()))
128: return false;
129: }
130: return true;
131: }
132:
133: public void setUsesDirective(String value) {
134: String oldValue = getUsesDirective();
135: setDirective(Constants.USES_DIRECTIVE, value);
136: fHeader.update();
137: firePropertyChanged(this , Constants.USES_DIRECTIVE, oldValue,
138: value);
139: }
140:
141: public String getUsesDirective() {
142: return getDirective(Constants.USES_DIRECTIVE);
143: }
144:
145: protected void appendValuesToBuffer(StringBuffer sb, TreeMap table) {
146: if (table == null)
147: return;
148: Object usesValue = null;
149: // remove the Uses directive, we will make sure to put it at the end
150: if (table.containsKey(Constants.USES_DIRECTIVE))
151: usesValue = table.remove(Constants.USES_DIRECTIVE);
152: super .appendValuesToBuffer(sb, table);
153: if (usesValue != null) {
154: table.put(Constants.USES_DIRECTIVE, usesValue);
155: formatUsesDirective(sb, usesValue);
156: }
157: }
158:
159: private void formatUsesDirective(StringBuffer sb, Object usesValue) {
160: StringTokenizer tokenizer = null;
161: if (usesValue instanceof String)
162: tokenizer = new StringTokenizer((String) usesValue, ","); //$NON-NLS-1$
163: boolean newLine = (tokenizer != null) ? tokenizer.countTokens() > 3
164: : ((ArrayList) usesValue).size() > 3;
165: String eol = getHeader().getLineLimiter();
166: sb.append(';');
167: if (newLine)
168: sb.append(eol).append(" "); //$NON-NLS-1$
169: sb.append(Constants.USES_DIRECTIVE);
170: sb.append(":=\""); //$NON-NLS-1$
171: if (tokenizer != null)
172: while (tokenizer.hasMoreTokens()) {
173: sb.append(tokenizer.nextToken());
174: if (tokenizer.hasMoreTokens()) {
175: sb.append(',');
176: if (newLine)
177: sb.append(eol).append(" "); //$NON-NLS-1$
178: }
179: }
180: else {
181: ArrayList list = ((ArrayList) usesValue);
182: for (int i = 0; i < list.size(); i++) {
183: if (i != 0) {
184: sb.append(',');
185: if (newLine)
186: sb.append(eol).append(" "); //$NON-NLS-1$
187: }
188: sb.append(list.get(i));
189: }
190: }
191: sb.append("\""); //$NON-NLS-1$
192: }
193:
194: /* (non-Javadoc)
195: * @see org.eclipse.pde.internal.core.bundle.BundleObject#write(java.lang.String, java.io.PrintWriter)
196: */
197: public void write(String indent, PrintWriter writer) {
198: // Used for text transfers for copy, cut, paste operations
199: writer.write(write());
200: }
201:
202: /**
203: * @param model
204: * @param header
205: * @param versionAttribute
206: */
207: public void reconnect(IBundleModel model,
208: ExportPackageHeader header, String versionAttribute) {
209: super .reconnect(model, header, versionAttribute);
210: // Non-Transient Field: Friends
211: reconnectFriends();
212: }
213:
214: /**
215: *
216: */
217: private void reconnectFriends() {
218: // Get all the friends
219: Iterator keys = fFriends.keySet().iterator();
220: // Fill in appropriate transient field values for all friends
221: while (keys.hasNext()) {
222: String key = (String) keys.next();
223: PackageFriend friend = (PackageFriend) fFriends.get(key);
224: friend.reconnect(this);
225: }
226: }
227:
228: }
|