KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quikj > server > framework > AceLicenseManager


1 /*
2  * AceLicenseManager.java
3  *
4  * Created on May 12, 2002, 1:17 AM
5  */

6
7 package com.quikj.server.framework;
8
9 import java.util.*;
10 import java.io.*;
11 import java.security.*;
12
13 // JAXP packages
14
import javax.xml.parsers.*;
15 import org.xml.sax.*;
16 import org.w3c.dom.*;
17
18 /**
19  *
20  * @author amit
21  */

22 public class AceLicenseManager
23 {
24     private String JavaDoc errorMessage = "";
25     private static AceLicenseManager instance = null;
26     private HashMap featureList = new HashMap();
27     private String JavaDoc encryptionSecret = null;
28     private String JavaDoc absPath = null;
29     
30     public static final String JavaDoc ROOT_NODE_NAME = "license";
31     
32     public static final String JavaDoc EL_CODE = "code";
33     public static final String JavaDoc ATT_CODE = "value";
34     
35     public static final String JavaDoc EL_FEATURE = "feature";
36     public static final String JavaDoc ATT_NAME = "name";
37     public static final String JavaDoc ATT_EXPIRES = "expires";
38     public static final String JavaDoc ATT_UNITS = "units";
39     public static final String JavaDoc ATT_CHECKSUM = "checksum";
40     public static final String JavaDoc ATT_INDEX = "index";
41     
42     /** Creates a new instance of AceLicenseManager */
43     public AceLicenseManager(String JavaDoc dir, String JavaDoc file)
44     throws FileNotFoundException, IOException, SAXException,
45     AceException, ParserConfigurationException
46     {
47         this(AceConfigTableFileParser.getAcePath(AceConfigTableFileParser.LOCAL_DATA,
48         dir, file));
49     }
50     
51     public AceLicenseManager(String JavaDoc path)
52     throws FileNotFoundException, IOException, SAXException,
53     AceException, ParserConfigurationException
54     {
55         absPath = path;
56         
57         loadLicenseFile();
58         
59         instance = this;
60     }
61     
62     public static AceLicenseManager getInstance()
63     {
64         return instance;
65     }
66     
67     /** Getter for property errorMessage.
68      * @return Value of property errorMessage.
69      */

70     public java.lang.String JavaDoc getErrorMessage()
71     {
72         return errorMessage;
73     }
74     
75     public AceFeatureLicenseElement findFeature(String JavaDoc feature)
76     {
77         return (AceFeatureLicenseElement)featureList.get(feature);
78     }
79     
80     public HashMap getFeatureList()
81     {
82         return featureList;
83     }
84     
85     public synchronized boolean consumeUnits(String JavaDoc feature, int units)
86     {
87         AceFeatureLicenseElement element = findFeature(feature);
88         if (element == null)
89         {
90             errorMessage = "The feature \"" + feature + "\" was not found";
91             return false;
92         }
93         
94         ArrayList list = element.getElementList();
95         int size = list.size();
96         int count = 0;
97         Date cur_time = new Date();
98         
99         for (int i = 0; i < size; i++)
100         {
101             AceLicenseElement fe = (AceLicenseElement)list.get(i);
102             
103             // first, check if the feature has expired
104
Date expire_date = fe.getFeatureExpires();
105             if (expire_date != null) // an expiry date is specified
106
{
107                 if (cur_time.getTime() >= expire_date.getTime())
108                 {
109                     continue;
110                 }
111             }
112             // else, feature with no expiry date, continue
113
int units_assigned = fe.getUnitsAssigned();
114             if (units_assigned > 0)
115             {
116                 count += units_assigned;
117             }
118             else
119             {
120                 // there is one element in the list with no units specified and
121
// that element has not expired. That means there is no need to
122
// do any unit check.
123
count = -1;
124                 break;
125             }
126         } // for
127

128         if (count == 0)
129         {
130             // if we have reached this point, it means that in the element list
131
// all the elements have expired items
132
errorMessage = "The feature \"" + feature + "\" has expired";
133             return false;
134         }
135         else if (count == -1)
136         {
137             // there is no unit count check required
138
return true;
139         }
140         else
141         {
142             // unit check required
143
int units_consumed = element.getUnitsConsumed();
144             if (units_consumed + units > count)
145             {
146                 errorMessage = "The feature \"" + feature
147                 + "\" has exceeded the licensed quota";
148                 return false;
149             }
150             
151             element.incrementUnitsConsumed(units);
152             return true;
153         }
154         
155     }
156     
157     public synchronized void returnUnits(String JavaDoc feature, int units)
158     {
159         AceFeatureLicenseElement element = findFeature(feature);
160         if (element != null)
161         {
162             element.decrementUnitsConsumed(units);
163         }
164     }
165     
166     public synchronized boolean licenseFeature(String JavaDoc feature)
167     {
168         return consumeUnits(feature, 0);
169     }
170     
171     
172     public void loadLicenseFile()
173     throws FileNotFoundException, IOException, SAXException,
174     AceException, ParserConfigurationException
175     
176     {
177         featureList.clear();
178         
179         File file = new File(absPath);
180         FileInputStream fis = new FileInputStream(file);
181         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
182         
183         // set various configuration options
184
dbf.setValidating(false);
185         dbf.setIgnoringComments(true);
186         dbf.setIgnoringElementContentWhitespace(true);
187         dbf.setCoalescing(true);
188         DocumentBuilder doc_builder = dbf.newDocumentBuilder();
189         
190         Document doc = doc_builder.parse(fis);
191         
192         processDoc(doc);
193         
194         fis.close();
195     }
196     
197     private void processDoc(Node doc)
198     throws AceException
199     {
200         if (doc.getNodeType() != Node.DOCUMENT_NODE)
201         {
202             // the root node must be of the type document
203

204             throw new AceException("Document does not begin with an XML node");
205         }
206         
207         Node root_element;
208         boolean root_found = false;
209         for (root_element = doc.getFirstChild();
210         root_element != null;
211         root_element = root_element.getNextSibling())
212         {
213             if (root_element.getNodeType() == Node.ELEMENT_NODE)
214             {
215                 if (root_element.getNodeName().equals(ROOT_NODE_NAME) == false)
216                 {
217                     throw new AceException("Root node name "
218                     + root_element.getNodeName()
219                     + " must be "
220                     + ROOT_NODE_NAME);
221                 }
222                 root_found = true;
223                 break;
224                 
225             }
226             // else discard
227
}
228         
229         if (root_found == false)
230         {
231             throw new AceException("Root node "
232             + ROOT_NODE_NAME
233             + " not found");
234         }
235         
236         // parse all the child elements
237
HashMap index_map = new HashMap();
238         Node ele_node;
239         for (ele_node = root_element.getFirstChild();
240         ele_node != null;
241         ele_node = ele_node.getNextSibling())
242         {
243             if (ele_node.getNodeType() == Node.ELEMENT_NODE)
244             {
245                 String JavaDoc name = ele_node.getNodeName();
246                 if (name.equals(EL_CODE) == true)
247                 {
248                     processCode(ele_node);
249                 }
250                 else if (name.equals(EL_FEATURE) == true)
251                 {
252                     processFeature(ele_node, index_map);
253                 }
254                 // else, ignore
255
}
256             // else, ignore
257
}
258         
259         String JavaDoc error = validateParams();
260         if (error != null)
261         {
262             throw new AceException(error);
263         }
264     }
265     
266     private void processCode(Node node)
267     throws AceException
268     {
269         String JavaDoc code_s = AceXMLHelper.getXMLAttribute(node,
270         ATT_CODE);
271         if (code_s == null)
272         {
273             throw new AceException("The syntax for "
274             + EL_CODE
275             + " is incorrect");
276         }
277         
278         try
279         {
280             Encryption decryptor = new Encryption();
281             encryptionSecret = decryptor.decrypt(code_s,
282             SysParam.getAuth1(getClass()));
283             if (encryptionSecret == null)
284             {
285                 throw new AceException("Invalid code specified");
286             }
287         }
288         catch (Exception JavaDoc ex)
289         {
290             throw new AceException(ex.getClass().getName() + " occured : "
291             + ex.getMessage());
292         }
293     }
294     
295     private void processFeature(Node node, HashMap map)
296     throws AceException
297     {
298         if (encryptionSecret == null)
299         {
300             throw new AceException("The code element must be specified first");
301         }
302         
303         String JavaDoc[] attributes =
304         { ATT_NAME, ATT_INDEX, ATT_UNITS, ATT_EXPIRES, ATT_CHECKSUM };
305         
306         String JavaDoc[] attrib_values = AceXMLHelper.getXMLAttributes(node, attributes);
307         
308         if ((attrib_values[0] == null) || (attrib_values[1] == null) || (attrib_values[4] == null))
309         {
310             throw new AceException("Either " + ATT_NAME + "," + ATT_INDEX +
311             " and/or "
312             + ATT_CHECKSUM + " not specified");
313         }
314         
315         String JavaDoc name = attrib_values[0];
316         
317         int index = -1;
318         try
319         {
320             index = Integer.parseInt(attrib_values[1]);
321         }
322         catch (NumberFormatException JavaDoc ex)
323         {
324             throw new AceException("Feature " + name + " has invalid value for "
325             + ATT_INDEX);
326         }
327         
328         if (map.get(new Integer JavaDoc(index)) != null)
329         {
330             throw new AceException("Feature " + name + " has a duplicate index");
331         }
332         
333         int units = -1;
334         if (attrib_values[2] != null)
335         {
336             try
337             {
338                 units = Integer.parseInt(attrib_values[2]);
339             }
340             catch (NumberFormatException JavaDoc ex)
341             {
342                 throw new AceException("Feature " + name + " has invalid value for "
343                 + ATT_UNITS);
344             }
345         }
346         
347         Date date = null;
348         if (attrib_values[3] != null)
349         {
350             date = processDate(attrib_values[3]);
351             if (date == null)
352             {
353                 throw new AceException("Feature " + name
354                 + " has invalid value for "
355                 + ATT_EXPIRES);
356             }
357         }
358         
359         // compute the checksum, make sure that it matches with the specified
360
// checksum
361
if (computeChecksum(name, units, date, index).equals(attrib_values[4])
362         == false)
363         {
364             throw new AceException("Feature " + name + " has invalid checksum");
365         }
366         
367         // add the license
368
AceFeatureLicenseElement fle = (AceFeatureLicenseElement)featureList.get(name);
369         if (fle != null) // feature exists
370
{
371             AceLicenseElement ale = new AceLicenseElement(name, units, date);
372             fle.addElement(ale);
373         }
374         else //first time addition
375
{
376             fle = new AceFeatureLicenseElement();
377             AceLicenseElement ale = new AceLicenseElement(name, units, date);
378             fle.addElement(ale);
379             featureList.put(name, fle);
380         }
381         
382         // add it to the index map
383
map.put(new Integer JavaDoc(index), new Integer JavaDoc(index));
384     }
385     
386     private String JavaDoc validateParams()
387     {
388         if (encryptionSecret == null)
389         {
390             return "Code element not specified";
391         }
392         return null;
393     }
394     
395     public static Date processDate(String JavaDoc date)
396     {
397         StringTokenizer tokens = new StringTokenizer(date, "-");
398         try
399         {
400             int num = tokens.countTokens();
401             if (num != 3)
402             {
403                 return null;
404             }
405             
406             int month = Calendar.JANUARY
407             + (Integer.parseInt(tokens.nextToken()) - 1);
408             int day = Integer.parseInt(tokens.nextToken());
409             int year = Integer.parseInt(tokens.nextToken());
410             
411             
412             //System.out.println (month + "-" + day + "-" + year);
413

414             Calendar cal = Calendar.getInstance();
415             cal.setLenient(false);
416             
417             try
418             {
419                 cal.set(year, month, day, 0, 0, 0);
420             }
421             catch (Exception JavaDoc ex)
422             {
423                 return null;
424             }
425             
426             return cal.getTime();
427             
428         }
429         catch (NumberFormatException JavaDoc ex)
430         {
431             return null;
432         }
433     }
434     
435     public static String JavaDoc computeChecksum(String JavaDoc name, int units, Date date,
436     int index,
437     String JavaDoc secret)
438     throws AceException
439     {
440         String JavaDoc date_s = null;
441         if (date != null)
442         {
443             date_s = date.toString();
444         }
445         else
446         {
447             date_s = "null";
448         }
449         
450         String JavaDoc str = secret + name + index + units + date_s + secret;
451         
452         try
453         {
454             MessageDigest md = MessageDigest.getInstance("MD5");
455             byte[] output = md.digest(str.getBytes());
456             
457             return Encryption.byteToString(output);
458         }
459         catch (NoSuchAlgorithmException ex)
460         {
461             throw new AceException("Checksum compute failed : "
462             + ex.getMessage());
463         }
464     }
465     
466     private String JavaDoc computeChecksum(String JavaDoc name, int units, Date date, int index)
467     throws AceException
468     {
469         return computeChecksum(name, units, date, index, encryptionSecret);
470     }
471     
472     public static void main(String JavaDoc[] args)
473     {
474         try
475         {
476             AceLicenseManager a = new AceLicenseManager(args[0]);
477         }
478         catch (Exception JavaDoc ex)
479         {
480             System.err.println(ex.getClass().getName() + " : " + ex.getMessage());
481         }
482         
483         System.exit(0);
484     }
485 }
486
Popular Tags