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.plugin.opennap.util;
21  
22  import java.util.StringTokenizer;
23  
24  /***
25   * This class provides means to parse the version string that is submitted
26   * by most servers on login. This class is used by {@link MessageSender}
27   * to send messages that are only supported by specific server 
28   * software version.
29   */
30  public class OpenNapServerVersion {
31  
32      //--- Constant(s) ---
33  
34      public static final OpenNapServerVersion OPENNAP044 
35  	= new OpenNapServerVersion("opennap 0.44.0", null);
36  
37      public static final OpenNapServerVersion SLAVANAP1
38  	= new OpenNapServerVersion("slavanap 1.0.0", null);
39  
40      public static final OpenNapServerVersion SLAVANAP2 
41  	= new OpenNapServerVersion("slavanap 2.0.0", SLAVANAP1);
42  
43      public static final OpenNapServerVersion UNKNOWN 
44  	= new OpenNapServerVersion("", null);
45  
46      public static final OpenNapServerVersion[] TOP_VERSIONS = {
47  	OPENNAP044, SLAVANAP2
48      };
49  
50      //--- Data field(s) ---
51  
52      public String software;
53      public int[] versions;
54      public OpenNapServerVersion nextVersion;
55  
56      //--- Constructor(s) ---
57  
58      public OpenNapServerVersion(String version, OpenNapServerVersion nextVersion)
59      {
60  	parse(version);
61  
62  	this.nextVersion = nextVersion;
63      }
64  
65      public OpenNapServerVersion(String version)
66      {
67  	parse(version);
68  
69  	this.nextVersion = getClosestVersion();
70  	if (this.nextVersion == null) {
71  	    // fall back to opennap 0.44
72  	    this.nextVersion = OPENNAP044;
73  	}
74      }
75  
76      //--- Method(s) ---
77  
78      /***
79       * Find a known version that is smaller than ours. That should be 
80       * compatible for sure. 
81      */
82      public OpenNapServerVersion getClosestVersion()
83      {
84  	for (int i = 0; i < TOP_VERSIONS.length; i++) {
85  	    OpenNapServerVersion next = TOP_VERSIONS[i];
86  	    if (software.equalsIgnoreCase(next.software)) {
87  		while (next != null) {
88  		    if (this.isCompatibleTo(next)) {
89  			return next;
90  		    }
91  		    next = next.getNextVersion();
92  		}
93  	    }
94  	}
95  
96  	return null;
97      }
98  
99      public OpenNapServerVersion getNextVersion()
100     {
101 	return nextVersion;
102     }
103 
104     public boolean isOpenNap()
105     {
106 	return software.equalsIgnoreCase("opennap");
107     }
108 
109     public boolean isSlavaNap()
110     {
111 	return software.equalsIgnoreCase("slavanap");
112     }
113 
114     public String toString() 
115     {
116 	StringBuffer sb = new StringBuffer();
117 	sb.append(software);
118 	if (versions.length > 0) {
119 	    sb.append(" ");
120 	}
121 	for (int i = 0; i < versions.length; i++) {
122 	    sb.append(versions[i]);
123 	    if (i < versions.length - 1) {
124 		sb.append(".");
125 	    }
126 	}
127 	return sb.toString();
128     }
129 
130     /***
131      * Returns true, if this version is greater or equal than 
132      * <code>v</code>.
133      */
134     public boolean isCompatibleTo(OpenNapServerVersion v)
135     {
136 	for (int i = 0; i < versions.length && i < v.versions.length; i++) {
137 	    if (this.versions[i] > v.versions[i]) {
138 		return true;
139 	    }
140 	    else if (this.versions[i] < v.versions[i]) {
141 		return false;
142 	    }
143 	}
144 
145 	return this.versions.length >= v.versions.length;
146     }
147 
148     protected void parse(String version)
149     {
150 	// separate by " " first
151 	StringTokenizer t = new StringTokenizer(version, " .");
152 	if (t.hasMoreTokens()) {
153 	    software = t.nextToken();
154 	}
155 	else {
156 	    software = "";
157 	}
158 	
159 	// now parse version
160 	versions = new int[t.countTokens()];
161 	if (t.hasMoreTokens()) {
162 	    for (int i = 0; i < versions.length; i++) {
163 		try {
164 		    versions[i] = Integer.parseInt(t.nextToken());
165 		}
166 		catch (NumberFormatException e) {
167 		    versions[i] = 0;
168 		}
169 	    }
170 	} 
171     }
172 	
173 }