00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 package org.knopflerfish.framework;
00036
00037 import java.io.*;
00038 import java.util.List;
00039 import java.util.ArrayList;
00040 import java.util.HashMap;
00041 import java.util.Vector;
00042 import java.util.Iterator;
00043 import java.util.Dictionary;
00044 import java.util.Enumeration;
00045
00046 public class Util {
00053 public static FileTree getFileStorage(String name) {
00054
00055 String fwdir = System.getProperty("org.osgi.framework.dir");
00056 if (fwdir == null) {
00057 return null;
00058 }
00059 FileTree dir = new FileTree((new File(fwdir)).getAbsoluteFile(), name);
00060 if (dir != null) {
00061 if (dir.exists()) {
00062 if (!dir.isDirectory()) {
00063 throw new RuntimeException("Not a directory: " + dir);
00064 }
00065 } else {
00066 if (!dir.mkdirs()) {
00067 throw new RuntimeException("Cannot create directory: " + dir);
00068 }
00069 }
00070 }
00071 return dir;
00072 }
00073
00074
00084 public static int compareStringVersion(String ver1, String ver2)
00085 throws NumberFormatException {
00086 int i1, i2;
00087 while (ver1 != null || ver2 != null) {
00088 if (ver1 != null) {
00089 int d1 = ver1.indexOf(".");
00090 if (d1 == -1) {
00091 i1 = Integer.parseInt(ver1.trim());
00092 ver1 = null;
00093 } else {
00094 i1 = Integer.parseInt(ver1.substring(0, d1).trim());
00095 ver1 = ver1.substring(d1 + 1);
00096 }
00097 } else {
00098 i1 = 0;
00099 }
00100 if (ver2 != null) {
00101 int d2 = ver2.indexOf(".");
00102 if (d2 == -1) {
00103 i2 = Integer.parseInt(ver2.trim());
00104 ver2 = null;
00105 } else {
00106 i2 = Integer.parseInt(ver2.substring(0, d2).trim());
00107 ver2 = ver2.substring(d2 + 1);
00108 }
00109 } else {
00110 i2 = 0;
00111 }
00112 if (i1 < i2) {
00113 return -1;
00114 }
00115 if (i1 > i2) {
00116 return 1;
00117 }
00118 }
00119 return 0;
00120 }
00121
00132 public static ArrayList parseEnumeration(String d, String s) {
00133 ArrayList result = new ArrayList();
00134 if (s != null) {
00135 AttributeTokenizer at = new AttributeTokenizer(s);
00136 do {
00137 String key = at.getKey();
00138 if (key == null) {
00139 throw new IllegalArgumentException("Directive " + d + ", unexpected character at: "
00140 + at.getRest());
00141 }
00142 if (!at.getEntryEnd()) {
00143 throw new IllegalArgumentException("Directive " + d + ", expected end of entry at: "
00144 + at.getRest());
00145 }
00146 int i = Math.abs(binarySearch(result, strComp, key) + 1);
00147 result.add(i, key);
00148 } while (!at.getEnd());
00149 return result;
00150 } else {
00151 return null;
00152 }
00153 }
00154
00171 public static Iterator parseEntries(String a, String s, boolean single, boolean unique, boolean single_entry) {
00172 ArrayList result = new ArrayList();
00173 if (s != null) {
00174 AttributeTokenizer at = new AttributeTokenizer(s);
00175 do {
00176 ArrayList keys = new ArrayList();
00177 HashMap params = new HashMap();
00178 String key = at.getKey();
00179 if (key == null) {
00180 throw new IllegalArgumentException("Definition, " + a + ", expected key at: " + at.getRest());
00181 }
00182 if (!single) {
00183 keys.add(key);
00184 while ((key = at.getKey()) != null) {
00185 keys.add(key);
00186 }
00187 }
00188 String param;
00189 while ((param = at.getParam()) != null) {
00190 List old = (List)params.get(param);
00191 boolean is_directive = at.isDirective();
00192 if (old != null && unique) {
00193 throw new IllegalArgumentException("Definition, " + a + ", duplicate " +
00194 (is_directive ? "directive" : "attribute") +
00195 ": " + param);
00196 }
00197 String value = at.getValue();
00198 if (value == null) {
00199 throw new IllegalArgumentException("Definition, " + a + ", expected value at: " + at.getRest());
00200 }
00201 if (is_directive) {
00202
00203
00204 }
00205 if (unique) {
00206 params.put(param, value);
00207 } else {
00208 if (old == null) {
00209 old = new ArrayList();
00210 params.put(param, old);
00211 }
00212 old.add(value);
00213 }
00214 }
00215 if (at.getEntryEnd()) {
00216 if (single) {
00217 params.put("key", key);
00218 } else {
00219 params.put("keys", keys);
00220 }
00221 result.add(params);
00222 } else {
00223 throw new IllegalArgumentException("Definition, " + a + ", expected end of entry at: " + at.getRest());
00224 }
00225 if (single_entry && !at.getEnd()) {
00226 throw new IllegalArgumentException("Definition, " + a + ", expected end of single entry at: " + at.getRest());
00227 }
00228 } while (!at.getEnd());
00229 }
00230 return result.iterator();
00231 }
00232
00239 static byte[] readResource(String name) throws IOException {
00240 byte[] buf = new byte[1024];
00241
00242 InputStream in = Main.class.getResourceAsStream(name);
00243 ByteArrayOutputStream bout = new ByteArrayOutputStream();
00244 int n;
00245 while ((n = in.read(buf)) > 0) {
00246 bout.write(buf, 0, n);
00247 }
00248 try { in.close(); } catch (Exception ignored) { }
00249
00250 return bout.toByteArray();
00251 }
00252
00257 protected static String WHITESPACE = " \t\n\r";
00258
00263 protected static char CITCHAR = '"';
00264
00265
00273 public static String [] splitwords(String s) {
00274 return splitwords(s, WHITESPACE);
00275 }
00276
00284 public static String [] splitwords(String s, String whiteSpace) {
00285 return splitwords(s, whiteSpace, CITCHAR);
00286 }
00287
00288
00305 public static String [] splitwords(String s,
00306 String whiteSpace,
00307 char citChar) {
00308 boolean bCit = false;
00309 Vector v = new Vector();
00310 StringBuffer buf = new StringBuffer();
00311 int i = 0;
00312
00313 while(i < s.length()) {
00314 char c = s.charAt(i);
00315
00316 if(bCit || whiteSpace.indexOf(c) == -1) {
00317
00318 if(c == citChar) {
00319 bCit = !bCit;
00320 } else {
00321 if(buf == null) {
00322 buf = new StringBuffer();
00323 }
00324 buf.append(c);
00325 }
00326 i++;
00327 } else {
00328
00329 if(buf != null) {
00330 v.addElement(buf.toString());
00331 buf = null;
00332 }
00333
00334
00335 while((i < s.length()) && (-1 != whiteSpace.indexOf(s.charAt(i)))) {
00336 i++;
00337 }
00338 }
00339 }
00340
00341
00342 if(buf != null) {
00343 v.addElement(buf.toString());
00344 }
00345
00346
00347 String [] r = new String[v.size()];
00348 v.copyInto(r);
00349
00350 return r;
00351 }
00352
00380 public static String replace(final String s,
00381 final String v1,
00382 final String v2) {
00383
00384
00385 if(s == null
00386 || v1 == null
00387 || v2 == null
00388 || v1.length() == 0
00389 || v1.equals(v2)) {
00390 return s;
00391 }
00392
00393 int ix = 0;
00394 int v1Len = v1.length();
00395 int n = 0;
00396
00397
00398
00399 while(-1 != (ix = s.indexOf(v1, ix))) {
00400 n++;
00401 ix += v1Len;
00402 }
00403
00404
00405 if(n == 0) {
00406 return s;
00407 }
00408
00409
00410 int start = 0;
00411 int v2Len = v2.length();
00412 char[] r = new char[s.length() + n * (v2Len - v1Len)];
00413 int rPos = 0;
00414
00415
00416 while(-1 != (ix = s.indexOf(v1, start))) {
00417 while(start < ix) r[rPos++] = s.charAt(start++);
00418 for(int j = 0; j < v2Len; j++) {
00419 r[rPos++] = v2.charAt(j);
00420 }
00421 start += v1Len;
00422 }
00423
00424
00425 ix = s.length();
00426 while(start < ix) r[rPos++] = s.charAt(start++);
00427
00428
00429 return new String(r);
00430 }
00431
00432
00433 public static String getContent(File f) {
00434 DataInputStream in = null;
00435 try {
00436 in = new DataInputStream(new FileInputStream(f));
00437 return in.readUTF();
00438 } catch (IOException ignore) {
00439 } finally {
00440 if (in != null) {
00441 try {
00442 in.close();
00443 } catch (IOException ignore) { }
00444 }
00445 }
00446 return null;
00447 }
00448
00449 public static void putContent(File f, String content) throws IOException {
00450 putContent(f, content, true);
00451 }
00452
00453 public static void putContent(File f, String content, boolean useUTF8) throws IOException {
00454 DataOutputStream out = null;
00455 try {
00456 out = new DataOutputStream(new FileOutputStream(f));
00457 if (useUTF8) {
00458 out.writeUTF(content);
00459 } else {
00460 out.writeChars(content);
00461 }
00462 } finally {
00463 if (out != null) {
00464 out.close();
00465 }
00466 }
00467 }
00468
00469 public interface Comparator {
00470 public int compare(Object a, Object b);
00471 }
00472
00479 static public void sort(List a, Comparator cf, boolean bReverse) {
00480 sort(a, 0, a.size() - 1, cf, bReverse ? -1 : 1);
00481 }
00482
00486 static void sort(List a, int lo0, int hi0, Comparator cf, int k) {
00487 int lo = lo0;
00488 int hi = hi0;
00489 Object mid;
00490
00491 if ( hi0 > lo0) {
00492
00493 mid = a.get( ( lo0 + hi0 ) / 2 );
00494
00495 while( lo <= hi ) {
00496 while( ( lo < hi0 ) && ( k * cf.compare(a.get(lo), mid) < 0 )) {
00497 ++lo;
00498 }
00499
00500 while( ( hi > lo0 ) && ( k * cf.compare(a.get(hi), mid ) > 0 )) {
00501 --hi;
00502 }
00503
00504 if( lo <= hi ) {
00505 swap(a, lo, hi);
00506 ++lo;
00507 --hi;
00508 }
00509 }
00510
00511 if( lo0 < hi ) {
00512 sort( a, lo0, hi, cf, k );
00513 }
00514
00515 if( lo < hi0 ) {
00516 sort( a, lo, hi0, cf, k );
00517 }
00518 }
00519 }
00520
00521 private static void swap(List a, int i, int j) {
00522 Object tmp = a.get(i);
00523 a.set(i, a.get(j));
00524 a.set(j, tmp);
00525 }
00526
00527
00539 public static int binarySearch(List pl, Comparator c, Object p) {
00540 int l = 0;
00541 int u = pl.size()-1;
00542
00543 while (l <= u) {
00544 int m = (l + u)/2;
00545 int v = c.compare(pl.get(m), p);
00546 if (v > 0) {
00547 l = m + 1;
00548 } else if (v < 0) {
00549 u = m - 1;
00550 } else {
00551 return m;
00552 }
00553 }
00554 return -(l + 1);
00555 }
00556
00557 static final Comparator strComp = new Comparator() {
00567 public int compare(Object oa, Object ob) throws ClassCastException {
00568 String a = (String)oa;
00569 String b = (String)ob;
00570 return a.compareTo(b);
00571 }
00572 };
00573
00574 private static final byte encTab[] = {
00575 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,
00576 0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x61,0x62,0x63,0x64,0x65,0x66,
00577 0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
00578 0x77,0x78,0x79,0x7a,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2b,0x2f
00579 };
00580
00581 private static final byte decTab[]={
00582 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00583 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00584 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
00585 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
00586 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
00587 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
00588 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
00589 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
00590 };
00591
00592
00593 public static String base64Encode(String s) throws IOException {
00594 return encode(s.getBytes(), 0);
00595 }
00596
00602
00603
00604
00605
00612 public static String encode(byte[] in, int len) throws IOException {
00613 ByteArrayOutputStream baos = null;
00614 ByteArrayInputStream bais = null;
00615 try {
00616 baos = new ByteArrayOutputStream();
00617 bais = new ByteArrayInputStream(in);
00618 encode(bais, baos, len);
00619
00620 return(new String(baos.toByteArray()));
00621 } finally {
00622 if (baos != null) baos.close();
00623 if (bais != null) bais.close();
00624 }
00625 }
00626
00627 public static void encode(InputStream in, OutputStream out, int len)
00628 throws IOException {
00629
00630
00631 if(len%4!=0)
00632 throw new IllegalArgumentException("Length must be a multiple of 4");
00633
00634
00635 int bits=0;
00636 int nbits=0;
00637 int nbytes=0;
00638 int b;
00639
00640 while( (b=in.read()) != -1) {
00641 bits=(bits<<8)|b;
00642 nbits+=8;
00643 while(nbits>=6) {
00644 nbits-=6;
00645 out.write(encTab[0x3f&(bits>>nbits)]);
00646 nbytes ++;
00647
00648 if (len !=0 && nbytes>=len) {
00649 out.write(0x0d);
00650 out.write(0x0a);
00651 nbytes -= len;
00652 }
00653 }
00654 }
00655
00656 switch(nbits) {
00657 case 2:
00658 out.write(encTab[0x3f&(bits<<4)]);
00659 out.write(0x3d);
00660 out.write(0x3d);
00661 break;
00662 case 4:
00663 out.write(encTab[0x3f&(bits<<2)]);
00664 out.write(0x3d);
00665 break;
00666 }
00667
00668 if (len != 0) {
00669 if (nbytes != 0) {
00670 out.write(0x0d);
00671 out.write(0x0a);
00672 }
00673 out.write(0x0d);
00674 out.write(0x0a);
00675 }
00676 }
00677
00678
00684 static void mergeDictionaries(Dictionary target, Dictionary extra) {
00685 for (Enumeration e = extra.keys();
00686 e.hasMoreElements(); ) {
00687 Object key = e.nextElement();
00688 if (target.get(key) == null) {
00689 target.put(key, extra.get(key));
00690 }
00691 }
00692 }
00693
00694
00698 public static boolean filterMatch(String filter, String s) {
00699 return patSubstr(s.toCharArray(), 0, filter.toCharArray(), 0);
00700 }
00701
00702
00705 private static boolean patSubstr(char[] s, int si, char[] pat, int pi) {
00706 if (pat.length-pi == 0)
00707 return s.length-si == 0;
00708 if (pat[pi] == '*') {
00709 pi++;
00710 for (;;) {
00711 if (patSubstr( s, si, pat, pi))
00712 return true;
00713 if (s.length-si == 0)
00714 return false;
00715 si++;
00716 }
00717 } else {
00718 if (s.length-si==0){
00719 return false;
00720 }
00721 if(s[si]!=pat[pi]){
00722 return false;
00723 }
00724 return patSubstr( s, ++si, pat, ++pi);
00725 }
00726 }
00727
00728
00729
00730 }
00731
00732
00736 class AttributeTokenizer {
00737
00738 String s;
00739 int length;
00740 int pos = 0;
00741
00742 AttributeTokenizer(String input) {
00743 s = input;
00744 length = s.length();
00745 }
00746
00747 String getWord() {
00748 skipWhite();
00749 boolean backslash = false;
00750 boolean quote = false;
00751 StringBuffer val = new StringBuffer();
00752 int end = 0;
00753 loop:
00754 for (; pos < length; pos++) {
00755 if (backslash) {
00756 backslash = false;
00757 val.append(s.charAt(pos));
00758 } else {
00759 char c = s.charAt(pos);
00760 switch (c) {
00761 case '"':
00762 quote = !quote;
00763 end = val.length();
00764 break;
00765 case '\\':
00766 backslash = true;
00767 break;
00768 case ',': case ':': case ';': case '=':
00769 if (!quote) {
00770 break loop;
00771 }
00772
00773 default:
00774 val.append(c);
00775 if (!Character.isWhitespace(c)) {
00776 end = val.length();
00777 }
00778 break;
00779 }
00780 }
00781 }
00782 if (quote || backslash || end == 0) {
00783 return null;
00784 }
00785 char [] res = new char [end];
00786 val.getChars(0, end, res, 0);
00787 return new String(res);
00788 }
00789
00790 String getKey() {
00791 if (pos >= length) {
00792 return null;
00793 }
00794 int save = pos;
00795 if (s.charAt(pos) == ';') {
00796 pos++;
00797 }
00798 String res = getWord();
00799 if (res != null) {
00800 if (pos == length) {
00801 return res;
00802 }
00803 char c = s.charAt(pos);
00804 if (c == ';' || c == ',') {
00805 return res;
00806 }
00807 }
00808 pos = save;
00809 return null;
00810 }
00811
00812 String getParam() {
00813 if (pos == length || s.charAt(pos) != ';') {
00814 return null;
00815 }
00816 int save = pos++;
00817 String res = getWord();
00818 if (res != null) {
00819 if (pos < length && s.charAt(pos) == '=') {
00820 return res;
00821 } if (pos + 1 < length && s.charAt(pos) == ':' && s.charAt(pos+1) == '=') {
00822 return res;
00823 }
00824 }
00825 pos = save;
00826 return null;
00827 }
00828
00829 boolean isDirective() {
00830 if (pos + 1 < length && s.charAt(pos) == ':') {
00831 pos++;
00832 return true;
00833 } else {
00834 return false;
00835 }
00836 }
00837
00838 String getValue() {
00839 if (s.charAt(pos) != '=') {
00840 return null;
00841 }
00842 int save = pos++;
00843 skipWhite();
00844 String val = getWord();
00845 if (val == null) {
00846 pos = save;
00847 return null;
00848 }
00849 return val;
00850 }
00851
00852 boolean getEntryEnd() {
00853 int save = pos;
00854 skipWhite();
00855 if (pos == length) {
00856 return true;
00857 } else if (s.charAt(pos) == ',') {
00858 pos++;
00859 return true;
00860 } else {
00861 pos = save;
00862 return false;
00863 }
00864 }
00865
00866 boolean getEnd() {
00867 int save = pos;
00868 skipWhite();
00869 if (pos == length) {
00870 return true;
00871 } else {
00872 pos = save;
00873 return false;
00874 }
00875 }
00876
00877 String getRest() {
00878 String res = s.substring(pos).trim();
00879 return res.length() == 0 ? "<END OF LINE>" : res;
00880 }
00881
00882 private void skipWhite() {
00883 for (; pos < length; pos++) {
00884 if (!Character.isWhitespace(s.charAt(pos))) {
00885 break;
00886 }
00887 }
00888 }
00889
00890
00891
00892 }