View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.commons.pkg;
21  
22  import java.io.File;
23  import java.util.Iterator;
24  import java.util.Properties;
25  import java.util.StringTokenizer;
26  import org.xnap.commons.util.StringHelper;
27  import org.xnap.commons.util.VersionParser;
28  
29  /***
30   * This class serves as a plugin information record.
31   */
32  public class PackageInfo implements Comparable
33  {
34  
35      //--- Constant(s) ---
36  
37  	public static final String DELIMETER = ",";
38  
39  	public static final String ACTION_INSTALL = "install";
40  
41  	public static final String PACKAGE_STATUS_INSTALLED = "installed";
42  
43  	public static final String STATUS_INSTALLED = "install ok installed";
44  	public static final String STATUS_NOT_INSTALLED = "purge ok uninstalled";
45  
46      //--- Data field(s) ---
47  
48      private Properties props;
49  
50      //--- Constructor(s) ---
51  
52      /***
53       * Constructs a new plugin information record from <code>p</code>.
54       * All keys with <code>prefix</code> are copied to this info object.
55       *
56       * @param prefix the key prefix 
57       */
58      public PackageInfo(Properties props)
59      {
60  		this.props = (Properties)props.clone();
61      }
62      
63  	PackageInfo(String packageName)
64  	{
65  		this.props = new Properties();
66  		this.props.setProperty("Package", packageName);
67  		this.props.setProperty("Version", "");
68  	}
69  
70  	PackageInfo()
71  	{
72  		this.props = new Properties();
73  	}
74  
75      //--- Method(s) ---
76  
77  	/***
78  	 * Lower versions come first.
79  	 */
80  	public int compareTo(Object o) 
81  	{
82  		PackageInfo info = (PackageInfo)o;
83  		int result = getPackage().compareTo(info.getPackage());
84  		return (result == 0) ? compareToVersion(info) : result;
85  	}
86  
87  	/***
88  	 * Returns a value > 0 if the version of this package is higher
89  	 * than the version of info.
90  	 */
91  	public int compareToVersion(PackageInfo info) 
92  	{
93  		String compareString
94  			= (info.getReleaseNr() != -1 && getReleaseNr() != -1)
95  			? info.getReleaseNr() + ""
96  			: info.getVersion();
97  		return compareToVersion(compareString);
98  	}
99  
100 	public int compareToVersion(String version)
101 	{
102 		if (getReleaseNr() != -1) {
103 			try {
104 				long nr = Long.parseLong(version);
105 				return (new Long(getReleaseNr() - nr)).intValue();
106 			}
107 			catch (NumberFormatException e) {
108 				// fall back to version compare
109 			}
110 		}
111 
112 		return VersionParser.compare(getVersion(), version);
113 	}
114 
115 	public boolean containsProperties(Properties p)
116 	{
117 		for (Iterator i = p.keySet().iterator(); i.hasNext();) {
118 			String key = (String)i.next();
119 			if (!p.getProperty(key, "").equals(props.getProperty(key, ""))) {
120 				return false;
121 			}
122 		}
123 		return true;
124 	}
125 
126 	public boolean equals(Object o)
127 	{
128 		if (o instanceof PackageInfo) {
129 			PackageInfo info = (PackageInfo)o;
130 			return getPackage().equals(info.getPackage())
131 				&& getVersion().equals(info.getVersion());
132 		}
133 		return false;
134 	}
135 
136 	/***
137 	 * See {@link #setAction(String)} for possible return values.
138 	 */
139     public String getAction()
140     {
141 		return getStatus(0);
142 	}
143 
144 	/***
145 	 * Returns "ok".
146 	 */
147     public String getActionStatus()
148     {
149 		return getStatus(1);
150 	}
151 
152     public String getAuthors()
153     {
154 		return props.getProperty("Authors");
155     }
156 
157     /***
158      * Returns an empty array if no dependencies are defined.
159      *
160      * @return never returns null
161      */
162     public String[] getClassPath()
163     {
164 		return getPropertyList("Class-Path");
165     }
166     
167     public String getControlPath()
168     {
169 		return props.getProperty("Control-Path");
170     }
171 
172     public String getDepends()
173     {
174 		return props.getProperty("Depends");
175     }
176 
177     public String getDescription()
178     {
179 		return props.getProperty("Description");
180     }
181 
182 	public String getDownloadFilename()
183 	{
184 		return props.getProperty("Download-Filename");
185 	}
186 
187 	public String[] getDownloadURLs()
188 	{
189 		return getPropertyList("Download-URLs");
190 	}
191 
192 	/***
193 	 * Returns a file that is relative to this packages location.
194 	 */
195 	public File getFile(String filename)
196 	{
197 		return new File(getControlPath(), filename);
198 	}
199 	
200     public String getFilename()
201     {
202 		return props.getProperty
203 			("Filename", 
204 			 getPackage() + "-" + getVersion() + ".zip");
205     }
206 
207     /***
208      * Returns a long description of the package's functionality that may
209      * contain html tags.
210      */
211     public String getLongDescription()
212     {
213 		return getProperty("Long-Description", "");
214     }
215 
216     public String getName()
217     {
218 		String name = props.getProperty("Name");
219 		return (name != null) ? name : getPackage();
220     }
221 
222     public String getPackage()
223     {
224 		return props.getProperty("Package");
225     }
226 
227     public String getPackageStatus()
228     {
229 		return getStatus(2);
230 	}
231 
232 	public Properties getProperties()
233 	{
234 		return props;
235 	}
236 
237     /***
238      * Returns a property.
239      */
240     public String getProperty(String key, String defaultValue)
241     {
242 		return props.getProperty(key, defaultValue);
243     }
244 
245     /***
246      * Returns a property.
247      */
248     public String getProperty(String key)
249     {
250 		return props.getProperty(key);
251     }
252 
253     /***
254      * Returns a property that is a list of strings.
255      */
256     public String[] getPropertyList(String key)
257     {
258 		return StringHelper.toArray(getProperty(key, ""), DELIMETER);
259     }
260 
261     public String getProvides()
262     {
263 		return props.getProperty("Provides");
264     }
265 
266 	public long getReleaseNr()
267 	{
268 		try {
269 			return Long.parseLong(props.getProperty("Release-Nr"));
270 		}
271 		catch (NumberFormatException e) {
272 		}
273 		return -1;
274 	}
275 
276     public String getSection()
277     {
278 		return props.getProperty("Section");
279     }
280 
281 	public long getSize()
282 	{
283 		try {
284 			return Long.parseLong(props.getProperty("Size", "0"));
285 		}
286 		catch (NumberFormatException e) {
287 			return 0;
288 		}
289 	}
290 
291 	public String getStatus()
292 	{
293 		return props.getProperty("Status", STATUS_NOT_INSTALLED);
294 	}
295 
296     public String getStatus(int pos)
297     {
298 		String status = getStatus();
299 		if (status != null) {
300 			StringTokenizer t = new StringTokenizer(status);
301 			// skip tokens
302 			for(int i = 0; i < pos && t.hasMoreTokens(); i++) {
303 				t.nextToken();
304 			}
305 			// return token at pos
306 			if (t.hasMoreTokens()) {
307 				return t.nextToken();
308 			}
309 		}
310 		return null;
311 	}
312 
313 	public String getVersion()
314 	{
315 		return props.getProperty("Version");
316 	}
317 
318 	public boolean isAvailable()
319 	{
320 		return props.getProperty("Available", "").equals("True");
321 	}
322 
323 	public boolean isBase()
324 	{
325 		String section = getSection();
326 		return (section != null) && section.startsWith("base");
327 	}
328 
329 	public boolean isCore()
330 	{
331 		String packageName = getPackage();
332 		return isBase() && (packageName != null) 
333 			&& packageName.indexOf("core") != -1;
334 	}
335 
336 	public boolean isPatch()
337 	{
338 		String packageName = getPackage();
339 		return isBase() && (packageName != null) 
340 			&& packageName.indexOf("patch") != -1;
341 	}
342 
343 	public boolean isInstalled()
344 	{
345 		return STATUS_INSTALLED.equals(getStatus());
346 	}
347 
348 	public boolean isNew()
349 	{
350 		return props.getProperty("New", "").equals("True");
351 	}
352 
353 	public boolean isPlugin()
354 	{
355 		String section = getSection();
356 		return (section != null) ? section.startsWith("plugin") : false;
357 	}
358 
359 	public boolean isUpdateAvailable()
360 	{
361 		return false;
362 	}
363 
364 	public boolean isValid()
365 	{
366 		return getPackage() != null && getVersion() != null;
367 	}
368 
369 	public void putAll(Properties p)
370 	{
371 		props.putAll(p);
372 	}
373 
374 	/***
375 	 * Action can be "deinstall", "hold", "install", "purge"
376 	 */
377 	public void setAction(String action)
378 	{
379 		if (action.equals("deinstall") || action.equals("hold")
380 			|| action.equals("install") || action.equals("purge")) {
381 			
382 			setStatus(action, getActionStatus(), getPackageStatus());
383 		}
384 	}
385 
386 	public void setAvailable(boolean available)
387 	{
388 		props.setProperty("Available", available ? "True" : "False"); 
389 	}
390 
391     public void setClassPath(String[] classPath)
392     {
393 		props.setProperty("Class-Path", 
394 						  StringHelper.toString(classPath, DELIMETER));
395     }
396 
397     public void setControlPath(String controlPath)
398     {
399 		props.setProperty("Control-Path", controlPath);
400     }
401     
402 	public void setDescription(String description)
403 	{
404 		props.setProperty("Description", description);
405 	}
406 
407 	public void setDownloadFilename(String filename)
408 	{
409 		props.setProperty("Download-Filename", filename);
410 	}
411 
412 	public void setInstalled(boolean installed)
413 	{
414 		setStatus(STATUS_INSTALLED);
415 	}
416 
417 	public void setNew(boolean isNew)
418 	{
419 		props.setProperty("New", (isNew) ? "True" : "False"); 
420 	}
421 
422 	public void setPackage(String packageName)
423 	{
424 		props.setProperty("Package", packageName);
425 	}
426 
427 	public void setSection(String section)
428 	{
429 		props.setProperty("Section", section);
430 	}
431 
432 	public void setStatus(String status)
433 	{
434 		props.setProperty("Status", status);
435 	}
436 
437 	public void setStatus(String action, String actionStatus, 
438 						  String packageStatus)
439 	{
440 		setStatus(action + " " + actionStatus + " " + packageStatus);
441 	}
442 
443 	public void setVersion(String version)
444 	{
445 		props.setProperty("Version", version);
446 	}
447 
448     /***
449      * Returns the value of {@link #getName() getName()}.
450      */
451     public String toString()
452     {
453 		return getName();
454     }
455 
456     //--- Inner Class(es) ---
457 
458 }