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