Lines 66-72
Link Here
|
66 |
import org.openide.filesystems.FileRenameEvent; |
66 |
import org.openide.filesystems.FileRenameEvent; |
67 |
import org.openide.filesystems.FileEvent; |
67 |
import org.openide.filesystems.FileEvent; |
68 |
import org.openide.filesystems.FileAttributeEvent; |
68 |
import org.openide.filesystems.FileAttributeEvent; |
69 |
import java.net.URL; |
|
|
70 |
import java.util.logging.Level; |
69 |
import java.util.logging.Level; |
71 |
import java.util.logging.Logger; |
70 |
import java.util.logging.Logger; |
72 |
import org.openide.filesystems.FileUtil; |
71 |
import org.openide.filesystems.FileUtil; |
Lines 74-143
Link Here
|
74 |
|
73 |
|
75 |
|
74 |
|
76 |
/** |
75 |
/** |
77 |
* Entity resolver which loads entities (typically DTDs) from fixed |
76 |
* Entity resolver which attaches <tt>Environment</tt> according to registrations |
78 |
* locations in the system file system, according to public ID. |
|
|
79 |
* <p> |
80 |
* It expects that PUBLIC has at maximum three "//" parts |
81 |
* (standard // vendor // entity name // language). It is basically |
82 |
* converted to <tt>"/xml/entities/{vendor}/{entity_name}"</tt> resource name. |
83 |
* <p> |
84 |
* It also attaches <tt>Environment</tt> according to registrations |
85 |
* at <tt>/xml/lookups/</tt> area. There can be registered: |
77 |
* at <tt>/xml/lookups/</tt> area. There can be registered: |
86 |
* <tt>Environment.Provider</tt> or deprecated <tt>XMLDataObject.Processor</tt> |
78 |
* <tt>Environment.Provider</tt> or deprecated <tt>XMLDataObject.Processor</tt> |
87 |
* and <tt>XMLDataObject.Info</tt> instances. |
79 |
* and <tt>XMLDataObject.Info</tt> instances. |
88 |
* <p> |
|
|
89 |
* All above are core implementation features. |
90 |
* |
91 |
* @author Jaroslav Tulach |
80 |
* @author Jaroslav Tulach |
92 |
*/ |
81 |
*/ |
93 |
@ServiceProviders({@ServiceProvider(service=Environment.Provider.class), @ServiceProvider(service=EntityCatalog.class)}) |
82 |
@ServiceProvider(service=Environment.Provider.class) |
94 |
public final class FileEntityResolver extends EntityCatalog implements Environment.Provider { |
83 |
public final class FileEntityResolver implements Environment.Provider { |
95 |
private static final String ENTITY_PREFIX = "/xml/entities"; // NOI18N |
84 |
private static final String LOOKUP_PREFIX = "/xml/lookups/"; // NOI18N |
96 |
private static final String LOOKUP_PREFIX = "/xml/lookups"; // NOI18N |
|
|
97 |
|
85 |
|
98 |
static final Logger ERR = Logger.getLogger(FileEntityResolver.class.getName()); |
86 |
static final Logger ERR = Logger.getLogger(FileEntityResolver.class.getName()); |
99 |
|
87 |
|
100 |
/** Constructor |
|
|
101 |
*/ |
102 |
public FileEntityResolver() { |
103 |
} |
104 |
|
105 |
/** Tries to find the entity on system file system. |
106 |
*/ |
107 |
public InputSource resolveEntity(String publicID, String systemID) throws IOException, SAXException { |
108 |
if (publicID == null) { |
109 |
return null; |
110 |
} |
111 |
|
112 |
|
113 |
String id = convertPublicId (publicID); |
114 |
|
115 |
StringBuffer sb = new StringBuffer (200); |
116 |
sb.append (ENTITY_PREFIX); |
117 |
sb.append (id); |
118 |
|
119 |
FileObject fo = FileUtil.getConfigFile (sb.toString ()); |
120 |
if (fo != null) { |
121 |
|
122 |
// fill in InputSource instance |
123 |
|
124 |
InputSource in = new InputSource (fo.getInputStream ()); |
125 |
try { |
126 |
Object myPublicID = fo.getAttribute("hint.originalPublicID"); //NOI18N |
127 |
if (myPublicID instanceof String) { |
128 |
in.setPublicId((String)myPublicID); |
129 |
} |
130 |
URL url = fo.getURL(); |
131 |
in.setSystemId(url.toString()); // we get nasty nbfs: instead nbres: but it is enough |
132 |
} catch (IOException ex) { |
133 |
// do no care just no system id |
134 |
} |
135 |
return in; |
136 |
} else { |
137 |
return null; |
138 |
} |
139 |
} |
140 |
|
141 |
/** A method that tries to find the correct lookup for given XMLDataObject. |
88 |
/** A method that tries to find the correct lookup for given XMLDataObject. |
142 |
* @return the lookup |
89 |
* @return the lookup |
143 |
*/ |
90 |
*/ |
Lines 161-167
Link Here
|
161 |
return null; |
108 |
return null; |
162 |
} |
109 |
} |
163 |
|
110 |
|
164 |
id = convertPublicId (id); |
111 |
id = EntityCatalog.convertPublicId(id); |
165 |
|
112 |
|
166 |
return new Lkp (id, xml); |
113 |
return new Lkp (id, xml); |
167 |
} else if (obj instanceof InstanceDataObject) { |
114 |
} else if (obj instanceof InstanceDataObject) { |
Lines 175-181
Link Here
|
175 |
parser.parse(); |
122 |
parser.parse(); |
176 |
String id = parser.getPublicId(); |
123 |
String id = parser.getPublicId(); |
177 |
if (id == null) return null; |
124 |
if (id == null) return null; |
178 |
id = convertPublicId (id); |
125 |
id = EntityCatalog.convertPublicId(id); |
179 |
return new Lkp (id, ido); |
126 |
return new Lkp (id, ido); |
180 |
} |
127 |
} |
181 |
|
128 |
|
Lines 253-321
Link Here
|
253 |
} |
200 |
} |
254 |
} |
201 |
} |
255 |
|
202 |
|
256 |
/** Converts the publicID into filesystem friendly name. |
|
|
257 |
* <p> |
258 |
* It expects that PUBLIC has at maximum three "//" parts |
259 |
* (standard // vendor // entity name // language). It is basically |
260 |
* converted to "vendor/entity_name" resource name. |
261 |
* |
262 |
* @see EntityCatalog |
263 |
*/ |
264 |
@SuppressWarnings("fallthrough") |
265 |
private static String convertPublicId (String publicID) { |
266 |
char[] arr = publicID.toCharArray (); |
267 |
|
268 |
|
269 |
int numberofslashes = 0; |
270 |
int state = 0; |
271 |
int write = 0; |
272 |
OUT: for (int i = 0; i < arr.length; i++) { |
273 |
char ch = arr[i]; |
274 |
|
275 |
switch (state) { |
276 |
case 0: |
277 |
// initial state |
278 |
if (ch == '+' || ch == '-' || ch == 'I' || ch == 'S' || ch == 'O') { |
279 |
// do not write that char |
280 |
continue; |
281 |
} |
282 |
// switch to regular state |
283 |
state = 1; |
284 |
// fallthru |
285 |
case 1: |
286 |
// regular state expecting any character |
287 |
if (ch == '/') { |
288 |
state = 2; |
289 |
if (++numberofslashes == 3) { |
290 |
// last part of the ID, exit |
291 |
break OUT; |
292 |
} |
293 |
arr[write++] = '/'; |
294 |
continue; |
295 |
} |
296 |
break; |
297 |
case 2: |
298 |
// previous character was / |
299 |
if (ch == '/') { |
300 |
// ignore second / and write nothing |
301 |
continue; |
302 |
} |
303 |
state = 1; |
304 |
break; |
305 |
} |
306 |
|
307 |
// write the char into the array |
308 |
if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9') { |
309 |
arr[write++] = ch; |
310 |
} else { |
311 |
arr[write++] = '_'; |
312 |
} |
313 |
} |
314 |
|
315 |
return new String (arr, 0, write); |
316 |
} |
317 |
|
318 |
|
319 |
/** Finds a fileobject for given ID. |
203 |
/** Finds a fileobject for given ID. |
320 |
* @param id string id |
204 |
* @param id string id |
321 |
* @param last[0] will be filled with last file object we should listen on |
205 |
* @param last[0] will be filled with last file object we should listen on |