1
2 package org.xwt;
3
4 import java.io.*;
5 import java.net.*;
6 import java.util.*;
7 import java.util.zip.*;
8 import java.lang.*;
9 import org.xwt.js.*;
10 import org.xwt.util.*;
11
12
22 public class Resources {
23
24
25 private static Hash bytes = new Hash(2000, 3);
26
27
28 private static Hash usedPackages = new Hash();
29
30
31 private static boolean validResourceName(String name) {
32 if (name == null || name.equals("")) return true;
33 if (name.endsWith("/box.xwt") || name.endsWith("/svg.xwt")) return false;
34 if (name.equals("box.xwt") || name.equals("svg.xwt")) return false;
35 if (!((name.charAt(0) >= 'A' && name.charAt(0) <= 'Z') ||
36 (name.charAt(0) >= 'a' && name.charAt(0) <= 'z'))) return false;
37 for(int i=1; i<name.length(); i++) {
38 char c = name.charAt(i);
39 if (!((c >= 'A' && c <= 'Z') ||
40 (c >= 'a' && c <= 'z') ||
41 c == '_' || c == '.' ||
42 (c >= '0' && c <= '9'))) return false;
43 }
44 return true;
45 }
46
47
48 public static synchronized void loadDirectory(File dir) throws IOException { loadDirectory(dir, ""); }
49 private static synchronized void loadDirectory(File dir, String prefix) throws IOException {
50 String n = prefix.replace(File.separatorChar, '.');
51 if (n.endsWith(".")) n = n.substring(0, n.length() - 1);
52 new Static(n);
53 String[] subfiles = dir.list();
54 for(int i=0; i<subfiles.length; i++) {
55 if (subfiles[i].equals("CVS") || !validResourceName(subfiles[i])) continue;
56 String name = prefix + subfiles[i];
57 File file = new File(dir.getPath() + File.separatorChar + subfiles[i]);
58 if (file.isDirectory()) {
59 loadDirectory(file, name + File.separatorChar);
60 } else {
61 if (name.endsWith(".xwt")) {
62 String name2 = name.substring(0, name.length() - 4);
63 Static.createStatic(name2.replace(File.separatorChar, '.'), false);
64 }
65 bytes.put(name.replace(File.separatorChar, '.'), file);
66 }
67 }
68 }
69
70
71 public static synchronized void loadArchive(InputStream is) throws IOException { loadArchive(is, 0, null); }
72 public static synchronized void loadArchive(InputStream is, final int length, final JS.Callable callback) throws IOException {
73
74
75 Object thisArchive = new Object();
76
77 ZipInputStream zis = new ZipInputStream(new FilterInputStream(is) {
78 int bytesDownloaded = 0;
79 boolean clear = true;
80 public int read() throws IOException {
81 bytesDownloaded++;
82 return super.read();
83 }
84 public int read(byte[] b, int off, int len) throws IOException {
85 int ret = super.read(b, off, len);
86 if (clear && callback != null) {
87 clear = false;
88 ThreadMessage.newthread(new JS.Callable() {
89 public Object call(JS.Array args_) throws JS.Exn {
90 try {
91 JS.Array args = new JS.Array();
92 args.addElement(new Double(bytesDownloaded));
93 args.addElement(new Double(length));
94 callback.call(args);
95 } finally {
96 clear = true;
97 }
98 return null;
99 }
100 });
101 }
102 bytesDownloaded += ret;
103 return ret;
104 }
105 });
106
107 Template.TemplateHelper t = new Template.TemplateHelper();
108
109 for(ZipEntry ze = zis.getNextEntry(); ze != null; ze = zis.getNextEntry()) {
110 String name = ze.getName();
111 if (!validResourceName(name.substring(name.lastIndexOf('/') + 1))) {
112 if (Log.on) Log.log(Resources.class, "WARNING: ignoring xwar entry with invalid name: " + name);
113 continue;
114 }
115
116 if (name.endsWith(".xwt")) {
117
118 bytes.put(name.replace('/', '.'), new byte[] { });
119 name = name.substring(0, name.length() - 4);
120 Static.createStatic(name.replace('/', '.'), false);
121 Template.buildTemplate(zis, name.replace('/', '.'), t);
122
123 } else {
124 bytes.put(name.replace('/', '.'), isToByteArray(zis));
125 }
126 }
127 if (Log.verbose) Log.log(Resources.class, "done loading archive");
128 }
129
130
131 static Vector mapFrom = new Vector();
132
133
134 static Vector mapTo = new Vector();
135 static {
136 mapFrom.addElement("xwt.standard");
137 mapTo.addElement("org.xwt.themes.monopoly");
138 }
139
140
149 public static String resolve(String name, String[] importlist) {
150 final int imax = importlist == null ? 0 : importlist.length;
151 for(int i=-1; i < imax; i++) {
152 String resolved = i == -1 ? name : (importlist[i] + '.' + name);
153 for(int j=mapFrom.size() - 1; j>=0; j--) {
154 String from = mapFrom.elementAt(j).toString();
155 if (resolved.startsWith(from) && (resolved.endsWith(".xwt") || resolved.endsWith(".xwf"))) {
156 String tryme = mapTo.elementAt(j) + resolved.substring(from.length());
157 if (bytes.get(tryme) != null) return tryme;
158 }
159 }
160 if (bytes.get(resolved) != null) return resolved;
161 }
162 return null;
163 }
164
165
170 public static byte[] getResource(String name) {
171 if (name == null) return null;
172 synchronized(bytes) {
173 Object o = bytes.get(name);
174 if (o == null) return null;
175 if (o instanceof byte[]) return ((byte[])o);
176 if (o instanceof File) {
177 try {
178 FileInputStream fi = new FileInputStream((File)o);
179 byte[] b = isToByteArray(fi);
180 bytes.put(name, b);
181 return b;
182 } catch (Exception e) {
183 if (Log.on) Log.log(Resources.class, "Exception while reading from file " + o);
184 if (Log.on) Log.log(Resources.class, e);
185 return null;
186 }
187 }
188 return null;
189 }
190 }
191
192
193 private static byte[] workspace = new byte[16 * 1024];
194
195
196 public static synchronized byte[] isToByteArray(InputStream is) throws IOException {
197 int pos = 0;
198 while (true) {
199 int numread = is.read(workspace, pos, workspace.length - pos);
200 if (numread == -1) break;
201 else if (pos + numread < workspace.length) pos += numread;
202 else {
203 pos += numread;
204 byte[] temp = new byte[workspace.length * 2];
205 System.arraycopy(workspace, 0, temp, 0, workspace.length);
206 workspace = temp;
207 }
208 }
209 byte[] ret = new byte[pos];
210 System.arraycopy(workspace, 0, ret, 0, pos);
211 return ret;
212 }
213 }
214
215
216
217