PageRenderTime 27ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollection.java

https://github.com/dekellum/jetty
Java | 477 lines | 325 code | 51 blank | 101 comment | 64 complexity | df8bb8e4c8cb75e5239bf2a1c921e19d MD5 | raw file
  1. // ========================================================================
  2. // Copyright (c) 2007-2009 Mort Bay Consulting Pty. Ltd.
  3. // ------------------------------------------------------------------------
  4. // All rights reserved. This program and the accompanying materials
  5. // are made available under the terms of the Eclipse Public License v1.0
  6. // and Apache License v2.0 which accompanies this distribution.
  7. // The Eclipse Public License is available at
  8. // http://www.eclipse.org/legal/epl-v10.html
  9. // The Apache License v2.0 is available at
  10. // http://www.opensource.org/licenses/apache2.0.php
  11. // You may elect to redistribute this code under either of these licenses.
  12. // ========================================================================
  13. package org.eclipse.jetty.util.resource;
  14. import java.io.File;
  15. import java.io.IOException;
  16. import java.io.InputStream;
  17. import java.io.OutputStream;
  18. import java.net.MalformedURLException;
  19. import java.net.URL;
  20. import java.util.ArrayList;
  21. import java.util.Arrays;
  22. import java.util.HashSet;
  23. import java.util.List;
  24. import java.util.StringTokenizer;
  25. import org.eclipse.jetty.util.URIUtil;
  26. /**
  27. * A collection of resources (dirs).
  28. * Allows webapps to have multiple (static) sources.
  29. * The first resource in the collection is the main resource.
  30. * If a resource is not found in the main resource, it looks it up in
  31. * the order the resources were constructed.
  32. *
  33. *
  34. *
  35. */
  36. public class ResourceCollection extends Resource
  37. {
  38. private Resource[] _resources;
  39. /* ------------------------------------------------------------ */
  40. /**
  41. * Instantiates an empty resource collection.
  42. *
  43. * This constructor is used when configuring jetty-maven-plugin.
  44. */
  45. public ResourceCollection()
  46. {
  47. _resources = new Resource[0];
  48. }
  49. /* ------------------------------------------------------------ */
  50. /**
  51. * Instantiates a new resource collection.
  52. *
  53. * @param resources the resources to be added to collection
  54. */
  55. public ResourceCollection(Resource... resources)
  56. {
  57. List<Resource> list = new ArrayList<Resource>();
  58. for (Resource r : resources)
  59. {
  60. if (r==null)
  61. continue;
  62. if (r instanceof ResourceCollection)
  63. {
  64. for (Resource r2 : ((ResourceCollection)r).getResources())
  65. list.add(r2);
  66. }
  67. else
  68. list.add(r);
  69. }
  70. _resources = list.toArray(new Resource[list.size()]);
  71. for(Resource r : _resources)
  72. {
  73. if(!r.exists() || !r.isDirectory())
  74. throw new IllegalArgumentException(r + " is not an existing directory.");
  75. }
  76. }
  77. /* ------------------------------------------------------------ */
  78. /**
  79. * Instantiates a new resource collection.
  80. *
  81. * @param resources the resource strings to be added to collection
  82. */
  83. public ResourceCollection(String[] resources)
  84. {
  85. _resources = new Resource[resources.length];
  86. try
  87. {
  88. for(int i=0; i<resources.length; i++)
  89. {
  90. _resources[i] = Resource.newResource(resources[i]);
  91. if(!_resources[i].exists() || !_resources[i].isDirectory())
  92. throw new IllegalArgumentException(_resources[i] + " is not an existing directory.");
  93. }
  94. }
  95. catch(IllegalArgumentException e)
  96. {
  97. throw e;
  98. }
  99. catch(Exception e)
  100. {
  101. throw new RuntimeException(e);
  102. }
  103. }
  104. /* ------------------------------------------------------------ */
  105. /**
  106. * Instantiates a new resource collection.
  107. *
  108. * @param csvResources the string containing comma-separated resource strings
  109. */
  110. public ResourceCollection(String csvResources)
  111. {
  112. setResourcesAsCSV(csvResources);
  113. }
  114. /* ------------------------------------------------------------ */
  115. /**
  116. * Retrieves the resource collection's resources.
  117. *
  118. * @return the resource array
  119. */
  120. public Resource[] getResources()
  121. {
  122. return _resources;
  123. }
  124. /* ------------------------------------------------------------ */
  125. /**
  126. * Sets the resource collection's resources.
  127. *
  128. * @param resources the new resource array
  129. */
  130. public void setResources(Resource[] resources)
  131. {
  132. _resources = resources != null ? resources : new Resource[0];
  133. }
  134. /* ------------------------------------------------------------ */
  135. /**
  136. * Sets the resources as string of comma-separated values.
  137. * This method should be used when configuring jetty-maven-plugin.
  138. *
  139. * @param csvResources the comma-separated string containing
  140. * one or more resource strings.
  141. */
  142. public void setResourcesAsCSV(String csvResources)
  143. {
  144. StringTokenizer tokenizer = new StringTokenizer(csvResources, ",;");
  145. int len = tokenizer.countTokens();
  146. if(len==0)
  147. {
  148. throw new IllegalArgumentException("ResourceCollection@setResourcesAsCSV(String) " +
  149. " argument must be a string containing one or more comma-separated resource strings.");
  150. }
  151. _resources = new Resource[len];
  152. try
  153. {
  154. for(int i=0; tokenizer.hasMoreTokens(); i++)
  155. {
  156. _resources[i] = Resource.newResource(tokenizer.nextToken().trim());
  157. if(!_resources[i].exists() || !_resources[i].isDirectory())
  158. throw new IllegalArgumentException(_resources[i] + " is not an existing directory.");
  159. }
  160. }
  161. catch(Exception e)
  162. {
  163. throw new RuntimeException(e);
  164. }
  165. }
  166. /* ------------------------------------------------------------ */
  167. /**
  168. * @param path The path segment to add
  169. * @return The contained resource (found first) in the collection of resources
  170. */
  171. @Override
  172. public Resource addPath(String path) throws IOException, MalformedURLException
  173. {
  174. if(_resources==null)
  175. throw new IllegalStateException("*resources* not set.");
  176. if(path==null)
  177. throw new MalformedURLException();
  178. if(path.length()==0 || URIUtil.SLASH.equals(path))
  179. return this;
  180. Resource resource=null;
  181. ArrayList<Resource> resources = null;
  182. int i=0;
  183. for(; i<_resources.length; i++)
  184. {
  185. resource = _resources[i].addPath(path);
  186. if (resource.exists())
  187. {
  188. if (resource.isDirectory())
  189. break;
  190. return resource;
  191. }
  192. }
  193. for(i++; i<_resources.length; i++)
  194. {
  195. Resource r = _resources[i].addPath(path);
  196. if (r.exists() && r.isDirectory())
  197. {
  198. if (resource!=null)
  199. {
  200. resources = new ArrayList<Resource>();
  201. resources.add(resource);
  202. resource=null;
  203. }
  204. resources.add(r);
  205. }
  206. }
  207. if (resource!=null)
  208. return resource;
  209. if (resources!=null)
  210. return new ResourceCollection(resources.toArray(new Resource[resources.size()]));
  211. return null;
  212. }
  213. /* ------------------------------------------------------------ */
  214. /**
  215. * @param path
  216. * @return the resource(file) if found, returns a list of resource dirs if its a dir, else null.
  217. * @throws IOException
  218. * @throws MalformedURLException
  219. */
  220. protected Object findResource(String path) throws IOException, MalformedURLException
  221. {
  222. Resource resource=null;
  223. ArrayList<Resource> resources = null;
  224. int i=0;
  225. for(; i<_resources.length; i++)
  226. {
  227. resource = _resources[i].addPath(path);
  228. if (resource.exists())
  229. {
  230. if (resource.isDirectory())
  231. break;
  232. return resource;
  233. }
  234. }
  235. for(i++; i<_resources.length; i++)
  236. {
  237. Resource r = _resources[i].addPath(path);
  238. if (r.exists() && r.isDirectory())
  239. {
  240. if (resource!=null)
  241. {
  242. resources = new ArrayList<Resource>();
  243. resources.add(resource);
  244. }
  245. resources.add(r);
  246. }
  247. }
  248. if (resource!=null)
  249. return resource;
  250. if (resources!=null)
  251. return resources;
  252. return null;
  253. }
  254. /* ------------------------------------------------------------ */
  255. @Override
  256. public boolean delete() throws SecurityException
  257. {
  258. throw new UnsupportedOperationException();
  259. }
  260. /* ------------------------------------------------------------ */
  261. @Override
  262. public boolean exists()
  263. {
  264. if(_resources==null)
  265. throw new IllegalStateException("*resources* not set.");
  266. return true;
  267. }
  268. /* ------------------------------------------------------------ */
  269. @Override
  270. public File getFile() throws IOException
  271. {
  272. if(_resources==null)
  273. throw new IllegalStateException("*resources* not set.");
  274. for(Resource r : _resources)
  275. {
  276. File f = r.getFile();
  277. if(f!=null)
  278. return f;
  279. }
  280. return null;
  281. }
  282. /* ------------------------------------------------------------ */
  283. @Override
  284. public InputStream getInputStream() throws IOException
  285. {
  286. if(_resources==null)
  287. throw new IllegalStateException("*resources* not set.");
  288. for(Resource r : _resources)
  289. {
  290. InputStream is = r.getInputStream();
  291. if(is!=null)
  292. return is;
  293. }
  294. return null;
  295. }
  296. /* ------------------------------------------------------------ */
  297. @Override
  298. public String getName()
  299. {
  300. if(_resources==null)
  301. throw new IllegalStateException("*resources* not set.");
  302. for(Resource r : _resources)
  303. {
  304. String name = r.getName();
  305. if(name!=null)
  306. return name;
  307. }
  308. return null;
  309. }
  310. /* ------------------------------------------------------------ */
  311. @Override
  312. public OutputStream getOutputStream() throws IOException, SecurityException
  313. {
  314. if(_resources==null)
  315. throw new IllegalStateException("*resources* not set.");
  316. for(Resource r : _resources)
  317. {
  318. OutputStream os = r.getOutputStream();
  319. if(os!=null)
  320. return os;
  321. }
  322. return null;
  323. }
  324. /* ------------------------------------------------------------ */
  325. @Override
  326. public URL getURL()
  327. {
  328. if(_resources==null)
  329. throw new IllegalStateException("*resources* not set.");
  330. for(Resource r : _resources)
  331. {
  332. URL url = r.getURL();
  333. if(url!=null)
  334. return url;
  335. }
  336. return null;
  337. }
  338. /* ------------------------------------------------------------ */
  339. @Override
  340. public boolean isDirectory()
  341. {
  342. if(_resources==null)
  343. throw new IllegalStateException("*resources* not set.");
  344. return true;
  345. }
  346. /* ------------------------------------------------------------ */
  347. @Override
  348. public long lastModified()
  349. {
  350. if(_resources==null)
  351. throw new IllegalStateException("*resources* not set.");
  352. for(Resource r : _resources)
  353. {
  354. long lm = r.lastModified();
  355. if (lm!=-1)
  356. return lm;
  357. }
  358. return -1;
  359. }
  360. /* ------------------------------------------------------------ */
  361. @Override
  362. public long length()
  363. {
  364. return -1;
  365. }
  366. /* ------------------------------------------------------------ */
  367. /**
  368. * @return The list of resource names(merged) contained in the collection of resources.
  369. */
  370. @Override
  371. public String[] list()
  372. {
  373. if(_resources==null)
  374. throw new IllegalStateException("*resources* not set.");
  375. HashSet<String> set = new HashSet<String>();
  376. for(Resource r : _resources)
  377. {
  378. for(String s : r.list())
  379. set.add(s);
  380. }
  381. String[] result=set.toArray(new String[set.size()]);
  382. Arrays.sort(result);
  383. return result;
  384. }
  385. /* ------------------------------------------------------------ */
  386. @Override
  387. public void release()
  388. {
  389. if(_resources==null)
  390. throw new IllegalStateException("*resources* not set.");
  391. for(Resource r : _resources)
  392. r.release();
  393. }
  394. /* ------------------------------------------------------------ */
  395. @Override
  396. public boolean renameTo(Resource dest) throws SecurityException
  397. {
  398. throw new UnsupportedOperationException();
  399. }
  400. /* ------------------------------------------------------------ */
  401. @Override
  402. public void copyTo(File destination)
  403. throws IOException
  404. {
  405. for (int r=_resources.length;r-->0;)
  406. _resources[r].copyTo(destination);
  407. }
  408. /* ------------------------------------------------------------ */
  409. /**
  410. * @return the list of resources separated by a path separator
  411. */
  412. @Override
  413. public String toString()
  414. {
  415. if(_resources==null)
  416. return "[]";
  417. return String.valueOf(Arrays.asList(_resources));
  418. }
  419. /* ------------------------------------------------------------ */
  420. @Override
  421. public boolean isContainedIn(Resource r) throws MalformedURLException
  422. {
  423. // TODO could look at implementing the semantic of is this collection a subset of the Resource r?
  424. return false;
  425. }
  426. }