1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package argos.metadata;
32
33 import java.io.ByteArrayInputStream;
34 import java.io.File;
35 import java.io.IOException;
36 import java.io.Serializable;
37 import java.util.ArrayList;
38 import java.util.List;
39 import java.util.logging.Level;
40 import java.util.logging.Logger;
41
42 import javax.xml.parsers.DocumentBuilder;
43 import javax.xml.parsers.DocumentBuilderFactory;
44 import javax.xml.parsers.ParserConfigurationException;
45
46 import org.w3c.dom.Document;
47 import org.w3c.dom.Element;
48 import org.w3c.dom.NodeList;
49 import org.xml.sax.SAXException;
50
51 import argos.Argos;
52 import argos.deploy.JarClassloader;
53 import argos.deploy.JarResource;
54 import argos.naming.NamingService;
55 import argos.util.Util;
56 import argos.util.graph.Node;
57 import argos.config.Config;
58
59
60
61
62
63
64 public class ServiceMetaInfo extends Running implements Serializable {
65 public static final long serialVersionUID = 23947239478293479L;
66
67 private static final Logger logger = Logger.getLogger(ServiceMetaInfo.class.getName());
68
69 private File orginalFile;
70 private File tempFile;
71 private File tempDir;
72 private String remoteFile;
73 private double version;
74 private String soapEndPoint;
75 private List<File> libraries;
76 private List<String> dependencies;
77 private List<ComponentMetaInfo> componentMetaInfo;
78 private transient JarClassloader loader;
79
80 public ServiceMetaInfo(File file) throws ParserConfigurationException, IOException, SAXException,
81 InformationMissingException {
82 super();
83 this.orginalFile = file;
84
85 componentMetaInfo = new ArrayList<ComponentMetaInfo>();
86 dependencies = new ArrayList<String>();
87 libraries = new ArrayList<File>();
88
89
90 JarResource jar = new JarResource(file);
91 byte[] bytes = jar.getResource(Config.DEPLOY_DESCRIPTOR);
92 if(bytes == null) {
93 throw new InformationMissingException("Deploy descriptor (deploy.xml) is missing in " +
94 file.getName() + ".");
95 }
96 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
97 DocumentBuilder parser = factory.newDocumentBuilder();
98 Document document = parser.parse(new ByteArrayInputStream(bytes));
99 Element service = document.getDocumentElement();
100
101
102
103 name = service.getAttribute("name");
104 if(name == null) {
105 throw new InformationMissingException("The service name is missing");
106 }
107
108
109 soapEndPoint = service.getAttribute("SoapEndPoint");
110
111
112 NodeList elements = service.getElementsByTagName("depend");
113 for(int i = 0; i < elements.getLength(); i++) {
114 Element element = (Element) elements.item(i);
115 Element parent = (Element) element.getParentNode();
116 if(!service.equals(parent)) {
117 continue;
118 }
119 String on = element.getAttribute("on");
120 if(on == null) {
121 throw new InformationMissingException("Dependency tag is missing on attribute");
122 }
123 dependencies.add(on);
124 }
125
126
127
128 String versionTemp = service.getAttribute("version");
129 if(versionTemp == null) {
130 throw new InformationMissingException("The service version is missing");
131 }
132 else {
133 version = Double.parseDouble(versionTemp);
134 }
135
136
137 elements = service.getElementsByTagName("deploy");
138 if(elements.getLength() != 1) {
139 throw new InformationMissingException("There can only be ONE deploy tag");
140 }
141 Element deploy = (Element) elements.item(0);
142 remoteFile = deploy.getAttribute("remote");
143
144 NodeList components = service.getElementsByTagName("component");
145 for(int i = 0; i < components.getLength(); i++) {
146 componentMetaInfo.add(new ComponentMetaInfo(this, (Element) components.item(i)));
147 }
148 }
149
150 public void setupDependencies(List<ServiceMetaInfo> services) throws DependencyMissingException {
151 for(String depends : dependencies) {
152 boolean found = false;
153 for(ServiceMetaInfo service : services) {
154 if(depends.equals(service.getName())) {
155 thisDependsOn.add(service);
156 service.dependsOnThis.add(this);
157 found = true;
158 break;
159 }
160 }
161 if(!found) {
162 ServiceMetaInfo service = NamingService.getInstance().getServiceByName(depends, false);
163 if(service == null) {
164 throw new DependencyMissingException("missing dependency " + depends + ".");
165 }
166 }
167 }
168
169
170 try {
171 for(ComponentMetaInfo meta : componentMetaInfo) {
172 meta.setupDependencies(services);
173 }
174 }
175 catch(DependencyMissingException e) {
176 for(ComponentMetaInfo meta : componentMetaInfo) {
177
178 meta.resetDependencies();
179 }
180 throw e;
181 }
182 }
183
184 public void setClassLoader(JarClassloader loader) {
185 this.loader = loader;
186 }
187
188 public JarClassloader getClassLoader() {
189 return loader;
190 }
191
192 public void addComponentMetaInfo(ComponentMetaInfo component) {
193 componentMetaInfo.add(component);
194 }
195
196 public List<ComponentMetaInfo> getComponentMetaInfo() {
197 List<ComponentMetaInfo> list = new ArrayList<ComponentMetaInfo>();
198 for(ComponentMetaInfo temp : componentMetaInfo) {
199 list.add(temp);
200 }
201 return list;
202 }
203
204 public List<File> getLibraries() {
205 List<File> list = new ArrayList<File>();
206 for(File temp : libraries) {
207 list.add(temp);
208 }
209 return list;
210 }
211
212 public boolean createTempFile() {
213 String dir = Argos.TEMP_DIR + "/" + getName() + System.currentTimeMillis();
214 tempDir = new File(dir);
215 tempDir.mkdir();
216 tempFile = new File(dir + "/" + orginalFile.getName());
217
218 try {
219 Util.copyFile(orginalFile, tempFile);
220 }
221 catch (IOException e) {
222 logger.log(Level.SEVERE, "Unable to copy " + orginalFile.getName() + " to temp dir: " +
223 e.getMessage(), e);
224 Util.cleanDir(tempDir);
225 return false;
226 }
227
228 File libDir = new File(dir + "/lib");
229 libDir.mkdir();
230 try {
231 libraries = Util.extractFromJar(orginalFile, "lib", dir, false);
232 if(libraries.isEmpty()) {
233 libDir.delete();
234 }
235 }
236 catch(IOException e) {
237 logger.log(Level.SEVERE, "Unable to extract files from " + orginalFile.getName() +
238 " to temp dir: " + e.getMessage(), e);
239 Util.cleanDir(tempDir);
240 return false;
241 }
242 return true;
243 }
244
245 public File getTempDir() {
246 return tempDir;
247 }
248
249 public File getTempFile() {
250 return tempFile;
251 }
252
253 public ComponentMetaInfo getComponentMetaInfo(String componentName) {
254 for(ComponentMetaInfo comp : componentMetaInfo) {
255 if(comp.getName().equals(componentName)) {
256 return comp;
257 }
258 }
259 logger.severe("Unable to find component " + componentName);
260 return null;
261 }
262
263 public List<String> getDependencies() {
264 return dependencies;
265 }
266
267 public String getRemoteFile() {
268 return remoteFile;
269 }
270
271 public double getVersion() {
272 return version;
273 }
274
275 public File getFile() {
276 return orginalFile;
277 }
278
279 public String getSoapEndPoint() {
280 return soapEndPoint;
281 }
282
283 public void cleanUp() {
284 Util.cleanDir(tempDir);
285 tempDir.delete();
286 }
287
288 public static void cleanUpTempFolder() {
289 Util.cleanDir(new File(Argos.TEMP_DIR));
290 }
291
292 @Override
293 public boolean equals(Object o) {
294 if(o instanceof ServiceMetaInfo) {
295 ServiceMetaInfo service = (ServiceMetaInfo) o;
296 return service.hashCode() == hashCode();
297 }
298 return false;
299 }
300
301 @Override
302 public int hashCode() {
303 return name.hashCode();
304 }
305
306 @Override
307 public String toString() {
308 return getName();
309 }
310
311 public boolean dependsOn(ServiceMetaInfo service) {
312 for(String s : dependencies) {
313 ServiceMetaInfo temp = NamingService.getInstance().getServiceByName(s);
314 if(temp != null) {
315 if(service == temp) {
316 return true;
317 }
318 else {
319 if(temp.dependsOn(service)) {
320 return true;
321 }
322 }
323 }
324 }
325 return false;
326 }
327
328 @Override
329 public int compareTo(Node node) {
330 if(name.startsWith(Config.BANG_BANG) && !node.getName().startsWith(Config.BANG_BANG)) {
331 return -1;
332 }
333 else if(!name.startsWith(Config.BANG_BANG) && node.getName().startsWith(Config.BANG_BANG)) {
334 return 1;
335 }
336 else {
337 return super.compareTo(node);
338 }
339 }
340 }