001: /*******************************************************************************
002: * Copyright (c) 2005 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;
011:
012: import java.util.ArrayList;
013: import java.util.HashMap;
014: import java.util.Map;
015:
016: import org.eclipse.pde.internal.core.ifeature.IFeature;
017: import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
018:
019: /**
020: * Stores IFeatureModels. Models are indexed by id and id with version for fast
021: * retrieval. Given id or version may have more than one corresponding model. A
022: * model has only one id and version that can be null. When models changes, its
023: * Idver stays unchanged until the models reinserted.
024: */
025: class FeatureTable {
026: public class Idver {
027: private final String fId;
028:
029: private final String fVer;
030:
031: public Idver(String id, String version) {
032: fId = id;
033: fVer = version;
034: }
035:
036: public String getId() {
037: return fId;
038: }
039:
040: public String getVer() {
041: return fVer;
042: }
043:
044: public int hashCode() {
045: int code = 0;
046: if (fId != null)
047: code += fId.hashCode();
048: if (fVer != null)
049: code += fVer.hashCode();
050:
051: return code;
052: }
053:
054: public boolean equals(Object obj) {
055: if (this == obj)
056: return true;
057: if (!(obj instanceof Idver))
058: return false;
059: return equals(((Idver) obj).getId(), ((Idver) obj).getVer());
060: }
061:
062: public boolean equals(String id, String version) {
063: boolean sameId = fId == null && id == null || fId != null
064: && fId.equals(id);
065: boolean sameVer = fVer == null && version == null
066: || fVer != null && fVer.equals(version);
067: return sameId && sameVer;
068:
069: }
070:
071: public String toString() {
072: return fId + "_" + fVer; //$NON-NLS-1$
073: }
074: }
075:
076: private static final IFeatureModel[] NO_MODELS = new IFeatureModel[0];
077:
078: /**
079: * Map of IFeatureModel to Idver
080: */
081: private Map fModel2idver;
082:
083: /**
084: * Map of Idver to ArrayList of IFeatureModel
085: */
086: private Map fIdver2models;
087:
088: /**
089: * Map of Id to ArrayList of Idver
090: */
091: private Map fId2idvers;
092:
093: public FeatureTable() {
094:
095: fModel2idver = new HashMap();
096: fIdver2models = new HashMap();
097: fId2idvers = new HashMap();
098: }
099:
100: public synchronized Idver get(IFeatureModel model) {
101: return (Idver) fModel2idver.get(model);
102: }
103:
104: /**
105: * @param id
106: * @param version
107: * @return IFeatureModel[]
108: */
109: public synchronized IFeatureModel[] get(String id, String version) {
110: return getImpl(new Idver(id, version));
111: }
112:
113: /**
114: * @param idver
115: * @return IFeatureModel[]
116: */
117: public synchronized IFeatureModel[] get(Idver idver) {
118: return getImpl(idver);
119: }
120:
121: /**
122: * @param idver
123: * @return
124: */
125: private IFeatureModel[] getImpl(Idver idver) {
126: ArrayList models = (ArrayList) fIdver2models.get(idver);
127: if (models == null) {
128: return NO_MODELS;
129: }
130: return (IFeatureModel[]) models
131: .toArray(new IFeatureModel[models.size()]);
132: }
133:
134: public synchronized IFeatureModel[] get(String id) {
135: ArrayList idvers = (ArrayList) fId2idvers.get(id);
136: if (idvers == null)
137: return NO_MODELS;
138: ArrayList allModels = new ArrayList();
139: for (int i = 0; i < idvers.size(); i++) {
140: Idver idver = (Idver) idvers.get(i);
141: ArrayList models = (ArrayList) fIdver2models.get(idver);
142: if (models == null) {
143: continue;
144: }
145: allModels.addAll(models);
146: }
147: return (IFeatureModel[]) allModels
148: .toArray(new IFeatureModel[allModels.size()]);
149: }
150:
151: public synchronized IFeatureModel[] getAll() {
152: return getAllImpl();
153: }
154:
155: /**
156: * @return
157: */
158: private IFeatureModel[] getAllImpl() {
159: return (IFeatureModel[]) fModel2idver.keySet().toArray(
160: new IFeatureModel[fModel2idver.size()]);
161: }
162:
163: /**
164: * Removes the model.
165: *
166: * @return Idver if model existed and was removed, null otherwise
167: */
168: public synchronized Idver remove(IFeatureModel model) {
169: return removeImpl(model);
170: }
171:
172: /**
173: * @param model
174: * @return
175: */
176: private Idver removeImpl(IFeatureModel model) {
177: Idver idver = (Idver) fModel2idver.remove(model);
178: if (idver == null) {
179: return null;
180: }
181: ArrayList models = (ArrayList) fIdver2models.get(idver);
182: for (int i = 0; i < models.size(); i++) {
183: if (models.get(i) == model) {
184: models.remove(i);
185: break;
186: }
187: }
188: if (models.size() <= 0) {
189: fIdver2models.remove(idver);
190:
191: ArrayList idvers = (ArrayList) fId2idvers
192: .get(idver.getId());
193: for (int i = 0; i < idvers.size(); i++) {
194: if (idvers.get(i).equals(idver)) {
195: idvers.remove(i);
196: break;
197: }
198: }
199: if (idvers.size() <= 0) {
200: fId2idvers.remove(idver.getId());
201: }
202: }
203: return idver;
204: }
205:
206: /**
207: * Adds the model. Updates the position of the model if already exist.
208: *
209: * @return Idver used during insertion
210: */
211: public synchronized Idver add(IFeatureModel model) {
212: removeImpl(model);
213:
214: IFeature feature = model.getFeature();
215: String id = feature.getId();
216: String ver = feature.getVersion();
217: Idver idver = new Idver(id, ver);
218:
219: fModel2idver.put(model, idver);
220:
221: ArrayList models = (ArrayList) fIdver2models.get(idver);
222: if (models == null) {
223: models = new ArrayList(1);
224: fIdver2models.put(idver, models);
225: }
226: models.add(model);
227:
228: ArrayList idvers = (ArrayList) fId2idvers.get(id);
229: if (idvers == null) {
230: idvers = new ArrayList(1);
231: fId2idvers.put(id, idvers);
232: }
233: idvers.add(idver);
234:
235: return idver;
236: }
237:
238: public synchronized String toString() {
239: IFeatureModel[] models = getAllImpl();
240: StringBuffer buf = new StringBuffer(30 * models.length);
241: buf.append("["); //$NON-NLS-1$
242: for (int i = 0; i < models.length; i++) {
243: if (i > 0) {
244: buf.append(", "); //$NON-NLS-1$
245: }
246: buf.append(get(models[i]));
247: buf.append("@"); //$NON-NLS-1$
248: buf.append(models[i].getFeature().getId());
249: buf.append("_"); //$NON-NLS-1$
250: buf.append(models[i].getFeature().getVersion());
251: }
252: buf.append("]"); //$NON-NLS-1$
253: return buf.toString();
254: }
255:
256: }
|