1 | /******************************************************************************* |
2 | * Copyright (c) 2007, 2009 IBM Corporation and others. |
3 | * All rights reserved. This program and the accompanying materials |
4 | * are made available under the terms of the Eclipse Public License v1.0 |
5 | * which accompanies this distribution, and is available at |
6 | * http://www.eclipse.org/legal/epl-v10.html |
7 | * |
8 | * Contributors: |
9 | * IBM Corporation - initial API and implementation |
10 | *******************************************************************************/ |
11 | package org.eclipse.pde.api.tools.internal.model; |
12 | |
13 | import java.util.ArrayList; |
14 | import java.util.Arrays; |
15 | import java.util.Iterator; |
16 | import java.util.List; |
17 | |
18 | import org.eclipse.core.runtime.CoreException; |
19 | import org.eclipse.core.runtime.IStatus; |
20 | import org.eclipse.core.runtime.MultiStatus; |
21 | import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin; |
22 | import org.eclipse.pde.api.tools.internal.provisional.model.ApiTypeContainerVisitor; |
23 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent; |
24 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement; |
25 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer; |
26 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeRoot; |
27 | |
28 | /** |
29 | * Common implementation of an {@link IApiTypeContainer} |
30 | * |
31 | * @since 1.0.0 |
32 | */ |
33 | public abstract class AbstractApiTypeContainer extends ApiElement implements IApiTypeContainer { |
34 | |
35 | /** |
36 | * Collection of {@link IApiTypeContainer}s |
37 | */ |
38 | private List fApiTypeContainers = null; |
39 | |
40 | /** |
41 | * Constructor |
42 | * @param parent the parent {@link IApiElement} or <code>null</code> if none. |
43 | * @param type the type of the container |
44 | * @param name the name |
45 | */ |
46 | protected AbstractApiTypeContainer(IApiElement parent, int type, String name) { |
47 | super(parent, type, name); |
48 | } |
49 | |
50 | /* (non-Javadoc) |
51 | * @see org.eclipse.pde.api.tools.internal.provisional.IApiTypeContainer#accept(org.eclipse.pde.api.tools.internal.provisional.ApiTypeContainerVisitor) |
52 | */ |
53 | public void accept(ApiTypeContainerVisitor visitor) throws CoreException { |
54 | IApiTypeContainer[] containers = getApiTypeContainers(); |
55 | for (int i = 0; i < containers.length; i++) { |
56 | containers[i].accept(visitor); |
57 | } |
58 | } |
59 | |
60 | /* (non-Javadoc) |
61 | * @see org.eclipse.pde.api.tools.internal.provisional.IApiTypeContainer#close() |
62 | */ |
63 | public synchronized void close() throws CoreException { |
64 | if (fApiTypeContainers == null) { |
65 | return; |
66 | } |
67 | //clean component cache elements |
68 | ApiModelCache.getCache().removeElementInfo(this); |
69 | |
70 | MultiStatus multi = null; |
71 | IStatus single = null; |
72 | IApiTypeContainer[] containers = getApiTypeContainers(); |
73 | for (int i = 0; i < containers.length; i++) { |
74 | try { |
75 | containers[i].close(); |
76 | } catch (CoreException e) { |
77 | if (single == null) { |
78 | single = e.getStatus(); |
79 | } else { |
80 | if (multi == null) { |
81 | multi = new MultiStatus(ApiPlugin.PLUGIN_ID, single.getCode(), single.getMessage(), single.getException()); |
82 | } |
83 | multi.add(e.getStatus()); |
84 | } |
85 | } |
86 | } |
87 | if (multi != null) { |
88 | throw new CoreException(multi); |
89 | } |
90 | if (single != null) { |
91 | throw new CoreException(single); |
92 | } |
93 | } |
94 | |
95 | /** |
96 | * @see org.eclipse.pde.api.tools.internal.provisional.IApiTypeContainer#findTypeRoot(java.lang.String) |
97 | */ |
98 | public IApiTypeRoot findTypeRoot(String qualifiedName) throws CoreException { |
99 | IApiTypeContainer[] containers = getApiTypeContainers(); |
100 | for (int i = 0; i < containers.length; i++) { |
101 | IApiTypeRoot file = containers[i].findTypeRoot(qualifiedName); |
102 | if (file != null) { |
103 | return file; |
104 | } |
105 | } |
106 | return null; |
107 | } |
108 | |
109 | /** |
110 | * @see org.eclipse.pde.api.tools.internal.provisional.IApiTypeContainer#findTypeRoot(java.lang.String, java.lang.String) |
111 | */ |
112 | public IApiTypeRoot findTypeRoot(String qualifiedName, String id) throws CoreException { |
113 | IApiTypeContainer[] containers = getApiTypeContainers(); |
114 | String origin = null; |
115 | IApiComponent comp = null; |
116 | for (int i = 0; i < containers.length; i++) { |
117 | comp = (IApiComponent) containers[i].getAncestor(IApiElement.COMPONENT); |
118 | if(comp != null) { |
119 | origin = comp.getId(); |
120 | } |
121 | if (origin == null) { |
122 | IApiTypeRoot file = containers[i].findTypeRoot(qualifiedName); |
123 | if (file != null) { |
124 | return file; |
125 | } |
126 | } else if (origin.equals(id)) { |
127 | IApiTypeRoot file = containers[i].findTypeRoot(qualifiedName, id); |
128 | if (file != null) { |
129 | return file; |
130 | } |
131 | } |
132 | } |
133 | return null; |
134 | } |
135 | |
136 | /* (non-Javadoc) |
137 | * @see org.eclipse.pde.api.tools.internal.provisional.IApiTypeContainer#getPackageNames() |
138 | */ |
139 | public String[] getPackageNames() throws CoreException { |
140 | List names = new ArrayList(); |
141 | IApiTypeContainer[] containers = getApiTypeContainers(); |
142 | for (int i = 0, max = containers.length; i < max; i++) { |
143 | String[] packageNames = containers[i].getPackageNames(); |
144 | for (int j = 0, max2 = packageNames.length; j < max2; j++) { |
145 | names.add(packageNames[j]); |
146 | } |
147 | } |
148 | String[] result = new String[names.size()]; |
149 | names.toArray(result); |
150 | Arrays.sort(result); |
151 | return result; |
152 | } |
153 | |
154 | /** |
155 | * Returns the {@link IApiTypeContainer}s in this container. Creates the containers if |
156 | * they are not yet created. |
157 | * |
158 | * @return the {@link IApiTypeContainer}s |
159 | */ |
160 | protected synchronized IApiTypeContainer[] getApiTypeContainers() throws CoreException { |
161 | if (fApiTypeContainers == null) { |
162 | fApiTypeContainers = createApiTypeContainers(); |
163 | } |
164 | return (IApiTypeContainer[]) fApiTypeContainers.toArray(new IApiTypeContainer[fApiTypeContainers.size()]); |
165 | } |
166 | |
167 | /** |
168 | * Returns the {@link IApiTypeContainer}s in this container. Creates the containers if |
169 | * they are not yet created. |
170 | * |
171 | * @param id the given id |
172 | * @return the {@link IApiTypeContainer}s |
173 | */ |
174 | protected synchronized IApiTypeContainer[] getApiTypeContainers(String id) throws CoreException { |
175 | if (fApiTypeContainers == null) { |
176 | fApiTypeContainers = createApiTypeContainers(); |
177 | } |
178 | List containers = new ArrayList(); |
179 | String origin = null; |
180 | IApiTypeContainer container = null; |
181 | for (Iterator iterator = this.fApiTypeContainers.iterator(); iterator.hasNext(); ) { |
182 | container = (IApiTypeContainer) iterator.next(); |
183 | origin = ((IApiComponent)container.getAncestor(IApiElement.COMPONENT)).getId(); |
184 | if (origin != null && origin.equals(id)) { |
185 | containers.add(container); |
186 | } |
187 | } |
188 | return (IApiTypeContainer[]) containers.toArray(new IApiTypeContainer[containers.size()]); |
189 | } |
190 | |
191 | /** |
192 | * Creates and returns the {@link IApiTypeContainer}s for this component. |
193 | * Subclasses must override. |
194 | * |
195 | * @return list of {@link IApiTypeContainer}s for this component |
196 | */ |
197 | protected abstract List createApiTypeContainers() throws CoreException; |
198 | |
199 | /** |
200 | * Sets the {@link IApiTypeContainer}s in this container. |
201 | * |
202 | * @param containers the {@link IApiTypeContainer}s to set |
203 | */ |
204 | protected synchronized void setApiTypeContainers(IApiTypeContainer[] containers) { |
205 | if (fApiTypeContainers != null) { |
206 | try { |
207 | close(); |
208 | } catch (CoreException e) { |
209 | // TODO log error |
210 | } |
211 | fApiTypeContainers.clear(); |
212 | } else { |
213 | fApiTypeContainers = new ArrayList(containers.length); |
214 | } |
215 | for (int i = 0; i < containers.length; i++) { |
216 | fApiTypeContainers.add(containers[i]); |
217 | } |
218 | } |
219 | |
220 | /* (non-Javadoc) |
221 | * @see org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer#getContainerType() |
222 | */ |
223 | public int getContainerType() { |
224 | return 0; |
225 | } |
226 | |
227 | } |