Lines 45-51
Link Here
|
45 |
import java.beans.PropertyChangeListener; |
45 |
import java.beans.PropertyChangeListener; |
46 |
import java.io.BufferedInputStream; |
46 |
import java.io.BufferedInputStream; |
47 |
import java.io.ByteArrayInputStream; |
47 |
import java.io.ByteArrayInputStream; |
48 |
import java.io.ByteArrayOutputStream; |
|
|
49 |
import java.io.CharArrayWriter; |
48 |
import java.io.CharArrayWriter; |
50 |
import java.io.DataOutputStream; |
49 |
import java.io.DataOutputStream; |
51 |
import java.io.File; |
50 |
import java.io.File; |
Lines 53-66
Link Here
|
53 |
import java.io.IOException; |
52 |
import java.io.IOException; |
54 |
import java.io.InputStream; |
53 |
import java.io.InputStream; |
55 |
import java.io.ObjectInputStream; |
54 |
import java.io.ObjectInputStream; |
56 |
import java.io.ObjectOutput; |
|
|
57 |
import java.io.ObjectOutputStream; |
55 |
import java.io.ObjectOutputStream; |
58 |
import java.io.OutputStream; |
56 |
import java.io.OutputStream; |
59 |
import java.io.OutputStreamWriter; |
57 |
import java.io.OutputStreamWriter; |
60 |
import java.io.PushbackInputStream; |
58 |
import java.io.PushbackInputStream; |
61 |
import java.io.Writer; |
59 |
import java.io.Writer; |
62 |
import java.util.ArrayList; |
60 |
import java.util.ArrayList; |
63 |
import java.util.Arrays; |
|
|
64 |
import java.util.Collections; |
61 |
import java.util.Collections; |
65 |
import java.util.HashMap; |
62 |
import java.util.HashMap; |
66 |
import java.util.HashSet; |
63 |
import java.util.HashSet; |
Lines 69-74
Link Here
|
69 |
import java.util.Map; |
66 |
import java.util.Map; |
70 |
import java.util.Set; |
67 |
import java.util.Set; |
71 |
import java.util.TreeMap; |
68 |
import java.util.TreeMap; |
|
|
69 |
import java.util.jar.JarFile; |
72 |
import java.util.logging.Level; |
70 |
import java.util.logging.Level; |
73 |
import java.util.logging.Logger; |
71 |
import java.util.logging.Logger; |
74 |
import org.netbeans.DuplicateException; |
72 |
import org.netbeans.DuplicateException; |
Lines 89-102
Link Here
|
89 |
import org.openide.filesystems.FileUtil; |
87 |
import org.openide.filesystems.FileUtil; |
90 |
import org.openide.modules.Dependency; |
88 |
import org.openide.modules.Dependency; |
91 |
import org.openide.modules.InstalledFileLocator; |
89 |
import org.openide.modules.InstalledFileLocator; |
92 |
import org.openide.modules.ModuleInstall; |
|
|
93 |
import org.openide.modules.SpecificationVersion; |
90 |
import org.openide.modules.SpecificationVersion; |
94 |
import org.openide.util.Parameters; |
91 |
import org.openide.util.Parameters; |
95 |
import org.openide.util.RequestProcessor; |
92 |
import org.openide.util.RequestProcessor; |
96 |
import org.openide.util.Utilities; |
93 |
import org.openide.util.Utilities; |
97 |
import org.openide.util.WeakSet; |
94 |
import org.openide.util.WeakSet; |
98 |
import org.openide.util.io.NbObjectInputStream; |
|
|
99 |
import org.openide.util.io.NbObjectOutputStream; |
100 |
import org.openide.xml.EntityCatalog; |
95 |
import org.openide.xml.EntityCatalog; |
101 |
import org.openide.xml.XMLUtil; |
96 |
import org.openide.xml.XMLUtil; |
102 |
import org.xml.sax.Attributes; |
97 |
import org.xml.sax.Attributes; |
Lines 139-146
Link Here
|
139 |
private boolean triggered = false; |
134 |
private boolean triggered = false; |
140 |
/** listener for changes in modules, etc.; see comment on class Listener */ |
135 |
/** listener for changes in modules, etc.; see comment on class Listener */ |
141 |
private final Listener listener = new Listener(); |
136 |
private final Listener listener = new Listener(); |
142 |
/** any module install sers from externalizedModules.ser, from class name to data */ |
|
|
143 |
private final Map<String,byte[]> compatibilitySers = new HashMap<String,byte[]>(100); |
144 |
/** atomic actions I have used to change Modules/*.xml */ |
137 |
/** atomic actions I have used to change Modules/*.xml */ |
145 |
private final Set<FileSystem.AtomicAction> myAtomicActions = Collections.<FileSystem.AtomicAction>synchronizedSet(new WeakSet<FileSystem.AtomicAction>(100)); |
138 |
private final Set<FileSystem.AtomicAction> myAtomicActions = Collections.<FileSystem.AtomicAction>synchronizedSet(new WeakSet<FileSystem.AtomicAction>(100)); |
146 |
|
139 |
|
Lines 189-199
Link Here
|
189 |
if (!f.isFile()) throw new FileNotFoundException(f.getAbsolutePath()); |
182 |
if (!f.isFile()) throw new FileNotFoundException(f.getAbsolutePath()); |
190 |
return f; |
183 |
return f; |
191 |
} else { |
184 |
} else { |
192 |
f = InstalledFileLocator.getDefault().locate(jar, name, false); |
185 |
Set<File> jars = InstalledFileLocator.getDefault().locateAll(jar, name, false); |
193 |
if (f != null) { |
186 |
if (jars.isEmpty()) { |
194 |
return f; |
187 |
throw new FileNotFoundException(jar); |
|
|
188 |
} else if (jars.size() == 1) { |
189 |
return jars.iterator().next(); |
195 |
} else { |
190 |
} else { |
196 |
throw new FileNotFoundException(jar); |
191 |
// Pick the newest one available. |
|
|
192 |
int major = -1; |
193 |
SpecificationVersion spec = null; |
194 |
File newest = null; |
195 |
for (File candidate : jars) { |
196 |
int candidateMajor = -1; |
197 |
SpecificationVersion candidateSpec = null; |
198 |
JarFile jf = new JarFile(candidate); |
199 |
try { |
200 |
java.util.jar.Attributes attr = jf.getManifest().getMainAttributes(); |
201 |
String codename = attr.getValue("OpenIDE-Module"); |
202 |
if (codename != null) { |
203 |
int slash = codename.lastIndexOf('/'); |
204 |
if (slash != -1) { |
205 |
candidateMajor = Integer.parseInt(codename.substring(slash + 1)); |
206 |
} |
207 |
} |
208 |
String sv = attr.getValue("OpenIDE-Module-Specification-Version"); |
209 |
if (sv != null) { |
210 |
candidateSpec = new SpecificationVersion(sv); |
211 |
} |
212 |
} finally { |
213 |
jf.close(); |
214 |
} |
215 |
if (newest == null || candidateMajor > major || (spec != null && candidateSpec != null && candidateSpec.compareTo(spec) > 0)) { |
216 |
newest = candidate; |
217 |
major = candidateMajor; |
218 |
spec = candidateSpec; |
219 |
} |
220 |
} |
221 |
return newest; |
197 |
} |
222 |
} |
198 |
} |
223 |
} |
199 |
} |
224 |
} |
Lines 301-497
Link Here
|
301 |
ev.log(Events.PERF_END, "ModuleList.installNew"); // NOI18N |
326 |
ev.log(Events.PERF_END, "ModuleList.installNew"); // NOI18N |
302 |
} |
327 |
} |
303 |
|
328 |
|
304 |
/** Record initial condition of a module installer. |
|
|
305 |
* First, if any stored state of the installer was found on disk, |
306 |
* that is if it is kept in the ModuleHistory, then deserialize |
307 |
* it (to the found installer). If there are deserialization errors, |
308 |
* this step is simply skipped. Or, if there was no prerecorded state, |
309 |
* and the ModuleInstall class overrides writeExternal or a similar |
310 |
* serialization-related method, thus indicating that it wishes to |
311 |
* serialize state, then this initial object is serialized to the |
312 |
* history's state for comparison with the later value. If there are |
313 |
* problems with this serialization, the history receives a dummy state |
314 |
* (empty bytestream) to indicate that something should be saved later. |
315 |
* If there is no prerecorded state and no writeExternal method, it is |
316 |
* assumed that serialization is irrelevant to this installer and so the |
317 |
* state is left null and nothing will be done here or in the postpare method. |
318 |
* If this installer was mentioned in externalizedModules.ser, also try to |
319 |
* handle the situation (determine if the state was useful or not etc.). |
320 |
* Access from NbInstaller. |
321 |
*/ |
322 |
void installPrepare(Module m, ModuleInstall inst) { |
323 |
if (! (m.getHistory() instanceof ModuleHistory)) { |
324 |
LOG.fine(m + " had strange history " + m.getHistory() + ", ignoring..."); |
325 |
return; |
326 |
} |
327 |
ModuleHistory hist = (ModuleHistory)m.getHistory(); |
328 |
// We might have loaded something from externalizedModules.ser before. |
329 |
byte[] compatSer = compatibilitySers.get(inst.getClass().getName()); |
330 |
if (compatSer != null) { |
331 |
LOG.fine("Had some old-style state for " + m); |
332 |
if (isReallyExternalizable(inst.getClass())) { |
333 |
// OK, maybe it was not useless, let's see... |
334 |
// Compare virgin state to what we had; if different, load |
335 |
// the old state and record that we want to track state. |
336 |
try { |
337 |
ByteArrayOutputStream baos = new ByteArrayOutputStream(1000); |
338 |
new NbObjectOutputStream(baos).writeObject(inst); |
339 |
baos.close(); |
340 |
if (Utilities.compareObjects(compatSer, baos.toByteArray())) { |
341 |
LOG.fine("Old-style state for " + m + " was gratuitous"); |
342 |
// leave hist.installerState null |
343 |
} else { |
344 |
LOG.fine("Old-style state for " + m + " was useful, loading it..."); |
345 |
// Make sure it is recorded as "changed" in history by writing something |
346 |
// fake now. In installPostpare, we will load the new installer state |
347 |
// and call setInstallerState again, so the result will be written to disk. |
348 |
hist.setInstallerState(new byte[0]); |
349 |
// And also load it into the actual installer. |
350 |
InputStream is = new ByteArrayInputStream(compatSer); |
351 |
Object o = new NbObjectInputStream(is).readObject(); |
352 |
if (o != inst) throw new ClassCastException("Stored " + o + " but expecting " + inst); // NOI18N |
353 |
} |
354 |
} catch (Exception e) { |
355 |
LOG.log(Level.WARNING, null, e); |
356 |
// Try later to continue. |
357 |
hist.setInstallerState(new byte[0]); |
358 |
} catch (LinkageError le) { |
359 |
LOG.log(Level.WARNING, null, le); |
360 |
// Try later to continue. |
361 |
hist.setInstallerState(new byte[0]); |
362 |
} |
363 |
} else { |
364 |
LOG.fine(m + " did not want to store install state"); |
365 |
// leave hist.installerState null |
366 |
} |
367 |
} else if (hist.getInstallerState() != null) { |
368 |
// We already have some state, load it now. |
369 |
LOG.fine("Loading install state for " + m); |
370 |
try { |
371 |
InputStream is = new ByteArrayInputStream(hist.getInstallerState()); |
372 |
// Note: NBOOS requires the system class loader to be in order. |
373 |
// Technically we have not yet fired any changes in it. However, |
374 |
// assuming that we are not in the first block of modules to be |
375 |
// loaded (that is, core = bootstraps) this will work because the |
376 |
// available systemClassLoader is just appended to. Better would |
377 |
// probably be to use a special ObjectInputStream resolving |
378 |
// specifically to the module's classloader, as this is far more |
379 |
// direct and possibly more reliable. |
380 |
Object o = new NbObjectInputStream(is).readObject(); |
381 |
// The joys of SharedClassObject. The deserialization itself actually |
382 |
// is assumed to overwrite the state of the install singleton. We |
383 |
// can only confirm that we actually deserialized the same thing we |
384 |
// were expecting too (it is too late to revert anything of course). |
385 |
if (o != inst) throw new ClassCastException("Stored " + o + " but expecting " + inst); // NOI18N |
386 |
} catch (Exception e) { |
387 |
// IOException, ClassNotFoundException, and maybe unchecked stuff |
388 |
LOG.log(Level.WARNING, null, e); |
389 |
// Nothing else to do, hope that the install object was not corrupted |
390 |
// by the failed deserialization! If it was, it cannot be saved now. |
391 |
} catch (LinkageError le) { |
392 |
LOG.log(Level.WARNING, null, le); |
393 |
} |
394 |
} else { |
395 |
// Virgin installer. First we check if it really cares about serialization |
396 |
// at all, because it not we do not want to waste time forcing it. |
397 |
if (isReallyExternalizable(inst.getClass())) { |
398 |
LOG.fine("Checking pre-install state of " + m); |
399 |
LOG.warning("Warning: use of writeExternal (or writeReplace) in " + inst.getClass().getName() + " is deprecated; use normal settings instead"); |
400 |
try { |
401 |
ByteArrayOutputStream baos = new ByteArrayOutputStream(1000); |
402 |
new NbObjectOutputStream(baos).writeObject(inst); |
403 |
baos.close(); |
404 |
// Keep track of the installer's state before we installed it. |
405 |
// This will be compared to its state afterwards so we can |
406 |
// avoid writing anything if nothing changed, thus avoid |
407 |
// polluting the disk. |
408 |
hist.setInstallerState(baos.toByteArray()); |
409 |
} catch (Exception e) { |
410 |
LOG.log(Level.WARNING, null, e); |
411 |
// Remember that it is *supposed* to be serializable to something. |
412 |
hist.setInstallerState(new byte[0]); |
413 |
} catch (LinkageError le) { |
414 |
LOG.log(Level.WARNING, null, le); |
415 |
hist.setInstallerState(new byte[0]); |
416 |
} |
417 |
} else { |
418 |
// It does not want to store anything. Leave the installer state null |
419 |
// and continue. |
420 |
LOG.fine(m + " did not want to store install state"); |
421 |
} |
422 |
} |
423 |
} |
424 |
/** Check if a class (extends ModuleInstall) is truly externalizable, |
425 |
* e.g. overrides writeExternal. |
426 |
*/ |
427 |
private static boolean isReallyExternalizable(Class clazz) { |
428 |
Class<?> c; |
429 |
for (c = clazz; c != ModuleInstall.class && c != Object.class; c = c.getSuperclass()) { |
430 |
try { |
431 |
c.getDeclaredMethod("writeExternal", ObjectOutput.class); // NOI18N |
432 |
// [PENDING] check that m is public, nonstatic, returns Void.TYPE and includes at most |
433 |
// IOException and unchecked exceptions in its clauses, else die |
434 |
// OK, it does something nontrivial. |
435 |
return true; |
436 |
} catch (NoSuchMethodException nsme) { |
437 |
// Didn't find it at this level, continue. |
438 |
} |
439 |
try { |
440 |
c.getDeclaredMethod("writeReplace"); // NOI18N |
441 |
// [PENDING] check that m is nonstatic, returns Object, throws ObjectStreamException |
442 |
// Designates a serializable replacer, this is special. |
443 |
return true; |
444 |
} catch (NoSuchMethodException nsme) { |
445 |
// Again keep on looking. |
446 |
} |
447 |
} |
448 |
// Hit a superclass. |
449 |
if (c == Object.class) throw new IllegalArgumentException("Class " + clazz + " was not a ModuleInstall"); // NOI18N |
450 |
// Hit ModuleInstall. Did not find anything. Assumed to not do anything during externalization. |
451 |
return false; |
452 |
} |
453 |
|
454 |
/** Acknowledge later conditions of a module installer. |
455 |
* If the module history indicates a nonnull installer state, then we |
456 |
* try to serialize the current state to a temporary buffer and compare |
457 |
* to the previous state. If the serialization succeeds, and they differ, |
458 |
* then the new state is recorded in the history and will later be written to disk. |
459 |
* Access from NbInstaller. |
460 |
*/ |
461 |
void installPostpare(Module m, ModuleInstall inst) { |
462 |
if (! (m.getHistory() instanceof ModuleHistory)) { |
463 |
LOG.fine(m + " had strange history " + m.getHistory() + ", ignoring..."); |
464 |
return; |
465 |
} |
466 |
ModuleHistory hist = (ModuleHistory)m.getHistory(); |
467 |
if (hist.getInstallerState() != null) { |
468 |
try { |
469 |
ByteArrayOutputStream baos = new ByteArrayOutputStream(1000); |
470 |
new NbObjectOutputStream(baos).writeObject(inst); |
471 |
baos.close(); |
472 |
byte[] old = hist.getInstallerState(); |
473 |
byte[] nue = baos.toByteArray(); |
474 |
if (Utilities.compareObjects(old, nue)) { |
475 |
// State has not changed. |
476 |
LOG.fine(m + " did not change installer state (" + old.length + " bytes), not writing anything"); |
477 |
} else { |
478 |
// It did change. Store new version. |
479 |
LOG.fine(m + " changed installer state after loading"); |
480 |
hist.setInstallerState(nue); |
481 |
} |
482 |
} catch (Exception e) { |
483 |
LOG.log(Level.WARNING, null, e); |
484 |
// We could not compare, so don't bother writing out any old state. |
485 |
//hist.setInstallerState(null); |
486 |
} catch (LinkageError le) { |
487 |
LOG.log(Level.WARNING, null, le); |
488 |
} |
489 |
} else { |
490 |
// Nothing stored (does not writeExternal), do nothing. |
491 |
LOG.fine(m + " has no saved state"); |
492 |
} |
493 |
} |
494 |
|
495 |
/** Read an XML file using an XMLReader and parse into a map of properties. |
329 |
/** Read an XML file using an XMLReader and parse into a map of properties. |
496 |
* One distinguished property 'name' is the code name base |
330 |
* One distinguished property 'name' is the code name base |
497 |
* and is taken from the root element. Others are taken |
331 |
* and is taken from the root element. Others are taken |
Lines 579-594
Link Here
|
579 |
* @return some parsed value suitable for the status map |
413 |
* @return some parsed value suitable for the status map |
580 |
*/ |
414 |
*/ |
581 |
private Object processStatusParam(String k, String v) throws NumberFormatException { |
415 |
private Object processStatusParam(String k, String v) throws NumberFormatException { |
582 |
if (k == "release") { // NOI18N |
416 |
if (k == "enabled" // NOI18N |
583 |
return Integer.parseInt(v); |
|
|
584 |
} else if (k == "enabled" // NOI18N |
585 |
|| k == "autoload" // NOI18N |
417 |
|| k == "autoload" // NOI18N |
586 |
|| k == "eager" // NOI18N |
418 |
|| k == "eager" // NOI18N |
587 |
|| k == "reloadable" // NOI18N |
419 |
|| k == "reloadable" // NOI18N |
588 |
) { |
420 |
) { |
589 |
return Boolean.valueOf(v); |
421 |
return Boolean.valueOf(v); |
590 |
} else if (k == "specversion") { // NOI18N |
|
|
591 |
return new SpecificationVersion(v); |
592 |
} else { |
422 |
} else { |
593 |
// Other properties are of type String. |
423 |
// Other properties are of type String. |
594 |
// Intern the smaller ones which are likely to be repeated somewhere. |
424 |
// Intern the smaller ones which are likely to be repeated somewhere. |
Lines 610-634
Link Here
|
610 |
&& ((Boolean)m.get("eager")).booleanValue() // NOI18N |
440 |
&& ((Boolean)m.get("eager")).booleanValue() // NOI18N |
611 |
&& m.get("enabled") != null) // NOI18N |
441 |
&& m.get("enabled") != null) // NOI18N |
612 |
throw new IOException("Eager modules cannot specify enablement"); // NOI18N |
442 |
throw new IOException("Eager modules cannot specify enablement"); // NOI18N |
613 |
// Compatibility: |
|
|
614 |
String origin = (String)m.remove("origin"); // NOI18N |
615 |
if (origin != null) { |
616 |
String jar = (String)m.get("jar"); // NOI18N |
617 |
String newjar; |
618 |
if (origin.equals("user") || origin.equals("installation")) { // NOI18N |
619 |
newjar = "modules/" + jar; // NOI18N |
620 |
} else if (origin.equals("user/autoload") || origin.equals("installation/autoload")) { // NOI18N |
621 |
newjar = "modules/autoload/" + jar; // NOI18N |
622 |
} else if (origin.equals("user/eager") || origin.equals("installation/eager")) { // NOI18N |
623 |
newjar = "modules/eager/" + jar; // NOI18N |
624 |
} else if (origin.equals("adhoc")) { // NOI18N |
625 |
newjar = jar; |
626 |
} else { |
627 |
throw new IOException("Unrecognized origin " + origin + " for " + jar); // NOI18N |
628 |
} |
629 |
LOG.warning("Upgrading 'jar' param from " + jar + " to " + newjar + " and removing 'origin' " + origin); |
630 |
m.put("jar", newjar); // NOI18N |
631 |
} |
632 |
} |
443 |
} |
633 |
|
444 |
|
634 |
// Encoding irrelevant for these getBytes() calls: all are ASCII... |
445 |
// Encoding irrelevant for these getBytes() calls: all are ASCII... |
Lines 874-880
Link Here
|
874 |
for (Map.Entry<String, Object> entry: new TreeMap<String, Object>(m).entrySet()) { |
685 |
for (Map.Entry<String, Object> entry: new TreeMap<String, Object>(m).entrySet()) { |
875 |
String name = entry.getKey(); |
686 |
String name = entry.getKey(); |
876 |
if ( |
687 |
if ( |
877 |
name.equals("installerState") || name.equals("name") || // NOI18N |
688 |
name.equals("name") || // NOI18N |
878 |
name.equals("deps") // NOI18N |
689 |
name.equals("deps") // NOI18N |
879 |
) { |
690 |
) { |
880 |
// Skip this one, it is a pseudo-param. |
691 |
// Skip this one, it is a pseudo-param. |
Lines 936-971
Link Here
|
936 |
lock.releaseLock(); |
747 |
lock.releaseLock(); |
937 |
} |
748 |
} |
938 |
//nue.lastApprovedChange = nue.file.lastModified().getTime(); |
749 |
//nue.lastApprovedChange = nue.file.lastModified().getTime(); |
939 |
// Now check up on the installer ser. |
|
|
940 |
byte[] data = (byte[])nue.diskProps.get("installerState"); // NOI18N |
941 |
if (data != null) { |
942 |
String installerName = (String)nue.diskProps.get("installer"); // NOI18N |
943 |
FileObject ser = folder.getFileObject(installerName); |
944 |
if (ser == null) { |
945 |
// Need to make it. |
946 |
int idx = installerName.lastIndexOf('.'); // NOI18N |
947 |
ser = folder.createData(installerName.substring(0, idx), installerName.substring(idx + 1)); |
948 |
} |
949 |
// Now write it. |
950 |
lock = ser.lock(); |
951 |
try { |
952 |
OutputStream os = ser.getOutputStream(lock); |
953 |
try { |
954 |
os.write(data); |
955 |
} finally { |
956 |
os.close(); |
957 |
} |
958 |
} finally { |
959 |
lock.releaseLock(); |
960 |
} |
961 |
} else { |
962 |
/* Probably not right: |
963 |
// Delete any existing one. |
964 |
if (ser != null) { |
965 |
ser.delete(); |
966 |
} |
967 |
*/ |
968 |
} |
969 |
} |
750 |
} |
970 |
}; |
751 |
}; |
971 |
myAtomicActions.add(aa); |
752 |
myAtomicActions.add(aa); |
Lines 1153-1175
Link Here
|
1153 |
|
934 |
|
1154 |
/** Compute what properties we would want to store in XML |
935 |
/** Compute what properties we would want to store in XML |
1155 |
* for this module. I.e. 'name', 'reloadable', etc. |
936 |
* for this module. I.e. 'name', 'reloadable', etc. |
1156 |
* The special property 'installerState' may be set (only |
|
|
1157 |
* if the normal property 'installer' is also set) and |
1158 |
* will be a byte[] rather than a string, which means that |
1159 |
* the indicated installer state should be written out. |
1160 |
*/ |
937 |
*/ |
1161 |
private Map<String,Object> computeProperties(Module m) { |
938 |
private Map<String,Object> computeProperties(Module m) { |
1162 |
if (m.isFixed() || ! m.isValid()) throw new IllegalArgumentException("fixed or invalid: " + m); // NOI18N |
939 |
if (m.isFixed() || ! m.isValid()) throw new IllegalArgumentException("fixed or invalid: " + m); // NOI18N |
1163 |
Map<String,Object> p = new HashMap<String,Object>(); |
940 |
Map<String,Object> p = new HashMap<String,Object>(); |
1164 |
p.put("name", m.getCodeNameBase()); // NOI18N |
941 |
p.put("name", m.getCodeNameBase()); // NOI18N |
1165 |
int rel = m.getCodeNameRelease(); |
|
|
1166 |
if (rel >= 0) { |
1167 |
p.put("release", rel); // NOI18N |
1168 |
} |
1169 |
SpecificationVersion spec = m.getSpecificationVersion(); |
1170 |
if (spec != null) { |
1171 |
p.put("specversion", spec); // NOI18N |
1172 |
} |
1173 |
if (!m.isAutoload() && !m.isEager()) { |
942 |
if (!m.isAutoload() && !m.isEager()) { |
1174 |
p.put("enabled", m.isEnabled()); // NOI18N |
943 |
p.put("enabled", m.isEnabled()); // NOI18N |
1175 |
} |
944 |
} |
Lines 1179-1188
Link Here
|
1179 |
if (m.getHistory() instanceof ModuleHistory) { |
948 |
if (m.getHistory() instanceof ModuleHistory) { |
1180 |
ModuleHistory hist = (ModuleHistory) m.getHistory(); |
949 |
ModuleHistory hist = (ModuleHistory) m.getHistory(); |
1181 |
p.put("jar", hist.getJar()); // NOI18N |
950 |
p.put("jar", hist.getJar()); // NOI18N |
1182 |
if (hist.getInstallerStateChanged()) { |
|
|
1183 |
p.put("installer", m.getCodeNameBase().replace('.', '-') + ".ser"); // NOI18N |
1184 |
p.put("installerState", hist.getInstallerState()); // NOI18N |
1185 |
} |
1186 |
} |
951 |
} |
1187 |
return p; |
952 |
return p; |
1188 |
} |
953 |
} |
Lines 1636-1642
Link Here
|
1636 |
} |
1401 |
} |
1637 |
private void stepCheckMisc(Map<String,Map<String,Object>> dirtyprops) { |
1402 |
private void stepCheckMisc(Map<String,Map<String,Object>> dirtyprops) { |
1638 |
LOG.fine("ModuleList: stepCheckMisc"); |
1403 |
LOG.fine("ModuleList: stepCheckMisc"); |
1639 |
String[] toCheck = {"jar", "autoload", "eager", "release", "specversion"}; // NOI18N |
1404 |
String[] toCheck = {"jar", "autoload", "eager"}; // NOI18N |
1640 |
for (Map.Entry<String,Map<String,Object>> entry : dirtyprops.entrySet()) { |
1405 |
for (Map.Entry<String,Map<String,Object>> entry : dirtyprops.entrySet()) { |
1641 |
String cnb = entry.getKey(); |
1406 |
String cnb = entry.getKey(); |
1642 |
Map<String,Object> props = entry.getValue(); |
1407 |
Map<String,Object> props = entry.getValue(); |
Lines 1804-1813
Link Here
|
1804 |
continue; |
1569 |
continue; |
1805 |
} |
1570 |
} |
1806 |
ModuleHistory history = new ModuleHistory(jar); // NOI18N |
1571 |
ModuleHistory history = new ModuleHistory(jar); // NOI18N |
1807 |
Integer prevReleaseI = (Integer) props.get("release"); // NOI18N |
|
|
1808 |
int prevRelease = prevReleaseI == null ? -1 : prevReleaseI.intValue(); |
1809 |
SpecificationVersion prevSpec = (SpecificationVersion) props.get("specversion"); // NOI18N |
1810 |
history.upgrade(prevRelease, prevSpec); |
1811 |
Boolean reloadableB = (Boolean) props.get("reloadable"); // NOI18N |
1572 |
Boolean reloadableB = (Boolean) props.get("reloadable"); // NOI18N |
1812 |
boolean reloadable = reloadableB != null ? reloadableB.booleanValue() : false; |
1573 |
boolean reloadable = reloadableB != null ? reloadableB.booleanValue() : false; |
1813 |
boolean enabled = enabledB != null ? enabledB.booleanValue() : false; |
1574 |
boolean enabled = enabledB != null ? enabledB.booleanValue() : false; |
Lines 1815-1843
Link Here
|
1815 |
boolean autoload = autoloadB != null ? autoloadB.booleanValue() : false; |
1576 |
boolean autoload = autoloadB != null ? autoloadB.booleanValue() : false; |
1816 |
Boolean eagerB = (Boolean) props.get("eager"); // NOI18N |
1577 |
Boolean eagerB = (Boolean) props.get("eager"); // NOI18N |
1817 |
boolean eager = eagerB != null ? eagerB.booleanValue() : false; |
1578 |
boolean eager = eagerB != null ? eagerB.booleanValue() : false; |
1818 |
String installer = (String) props.get("installer"); // NOI18N |
|
|
1819 |
if (installer != null) { |
1820 |
String nameDashes = name.replace('.', '-'); |
1821 |
if (!installer.equals(nameDashes + ".ser")) { |
1822 |
throw new IOException("Incorrect installer ser name: " + installer); // NOI18N |
1823 |
} |
1824 |
// Load from disk in mentioned file. |
1825 |
FileObject installerSer = folder.getFileObject(nameDashes, "ser"); // NOI18N |
1826 |
if (installerSer == null) { |
1827 |
throw new IOException("No such install ser: " + installer + "; I see only: " + Arrays.asList(folder.getChildren())); // NOI18N |
1828 |
} |
1829 |
// Hope the stored state is not >Integer.MAX_INT! :-) |
1830 |
byte[] buf = new byte[(int) installerSer.getSize()]; |
1831 |
InputStream is2 = installerSer.getInputStream(); |
1832 |
try { |
1833 |
is2.read(buf); |
1834 |
} finally { |
1835 |
is2.close(); |
1836 |
} |
1837 |
history.setInstallerState(buf); |
1838 |
// Quasi-prop which is stored separately. |
1839 |
props.put("installerState", buf); // NOI18N |
1840 |
} |
1841 |
NbInstaller.register(name, props.get("deps")); // NOI18N |
1579 |
NbInstaller.register(name, props.get("deps")); // NOI18N |
1842 |
Module m = mgr.create(jarFile, history, reloadable, autoload, eager); |
1580 |
Module m = mgr.create(jarFile, history, reloadable, autoload, eager); |
1843 |
NbInstaller.register(null, null); |
1581 |
NbInstaller.register(null, null); |