1 11 package org.eclipse.osgi.internal.resolver; 12 13 import java.io.*; 14 import java.util.*; 15 import org.eclipse.osgi.service.resolver.*; 16 import org.osgi.framework.Constants; 17 import org.osgi.framework.Version; 18 19 class StateWriter { 20 21 private Map objectTable = new HashMap(); 26 private ArrayList forcedWrite = new ArrayList(); 27 28 private int addToObjectTable(Object object) { 29 Integer cur = (Integer ) objectTable.get(object); 30 if (cur != null) 31 return cur.intValue(); 32 objectTable.put(object, new Integer (objectTable.size())); 33 return (objectTable.size() - 1); 35 } 36 37 private int getFromObjectTable(Object object) { 38 if (objectTable != null) { 39 Object objectResult = objectTable.get(object); 40 if (objectResult != null) { 41 return ((Integer ) objectResult).intValue(); 42 } 43 } 44 return -1; 45 } 46 47 private boolean writePrefix(Object object, DataOutputStream out) throws IOException { 48 if (writeIndex(object, out)) 49 return true; 50 int index = addToObjectTable(object); 52 out.writeByte(StateReader.OBJECT); 53 out.writeInt(index); 54 return false; 55 } 56 57 private void writeStateDeprecated(StateImpl state, DataOutputStream out) throws IOException { 58 out.write(StateReader.STATE_CACHE_VERSION); 59 if (writePrefix(state, out)) 60 return; 61 out.writeLong(state.getTimeStamp()); 62 String [] platformPropKeys = state.getPlatformPropertyKeys(); 64 writePlatformProp(platformPropKeys, out); 65 Dictionary[] propSet = state.getPlatformProperties(); 66 out.writeInt(propSet.length); 67 for (int i = 0; i < propSet.length; i++) { 68 Dictionary props = propSet[i]; 69 out.writeInt(platformPropKeys.length); 70 for (int j = 0; j < platformPropKeys.length; j++) 71 writePlatformProp(props.get(platformPropKeys[j]), out); 72 } 73 BundleDescription[] bundles = state.getBundles(); 74 StateHelperImpl.getInstance().sortBundles(bundles); 75 out.writeInt(bundles.length); 76 if (bundles.length == 0) 77 return; 78 for (int i = 0; i < bundles.length; i++) 79 writeBundleDescription(bundles[i], out, false); 80 out.writeBoolean(state.isResolved()); 81 out.writeInt(out.size()); 83 for (int i = 0; i < bundles.length; i++) 84 writeBundleDescriptionLazyData(bundles[i], out); 85 } 86 87 public void saveState(StateImpl state, File stateFile, File lazyFile) throws IOException { 88 DataOutputStream outLazy = null; 89 DataOutputStream outState = null; 90 FileOutputStream fosLazy = null; 91 FileOutputStream fosState = null; 92 try { 93 BundleDescription[] bundles = state.getBundles(); 94 StateHelperImpl.getInstance().sortBundles(bundles); 95 for (int i = 0; i < bundles.length; i++) 98 addToObjectTable(bundles[i]); 99 fosLazy = new FileOutputStream(lazyFile); 101 outLazy = new DataOutputStream(new BufferedOutputStream(fosLazy)); 102 for (int i = 0; i < bundles.length; i++) 103 writeBundleDescriptionLazyData(bundles[i], outLazy); 104 fosState = new FileOutputStream(stateFile); 106 outState = new DataOutputStream(new BufferedOutputStream(fosState)); 107 outState.write(StateReader.STATE_CACHE_VERSION); 108 if (writePrefix(state, outState)) 109 return; 110 outState.writeLong(state.getTimeStamp()); 111 String [] platformPropKeys = state.getPlatformPropertyKeys(); 113 writePlatformProp(platformPropKeys, outState); 114 Dictionary[] propSet = state.getPlatformProperties(); 116 outState.writeInt(propSet.length); 117 for (int i = 0; i < propSet.length; i++) { 118 Dictionary props = propSet[i]; 119 outState.writeInt(platformPropKeys.length); 120 for (int j = 0; j < platformPropKeys.length; j++) 121 writePlatformProp(props.get(platformPropKeys[j]), outState); 122 } 123 outState.writeInt(bundles.length); 124 if (bundles.length == 0) 125 return; 126 for (int i = 0; i < bundles.length; i++) 127 writeBundleDescription(bundles[i], outState, true); 130 outState.writeBoolean(state.isResolved()); 131 } finally { 132 if (outLazy != null) { 133 try { 134 outLazy.flush(); 135 fosLazy.getFD().sync(); 136 } catch (IOException e) { 137 } 139 try { 140 outLazy.close(); 141 } catch (IOException e) { 142 } 144 } 145 if (outState != null) { 146 try { 147 outState.flush(); 148 fosState.getFD().sync(); 149 } catch (IOException e) { 150 } 152 try { 153 outState.close(); 154 } catch (IOException e) { 155 } 157 } 158 } 159 } 160 161 private void writePlatformProp(Object obj, DataOutputStream out) throws IOException { 162 if (obj == null) 163 out.writeByte(StateReader.NULL); 164 else { 165 out.writeByte(StateReader.OBJECT); 166 if (obj instanceof String ) { 167 out.writeInt(1); 168 writeStringOrNull((String ) obj, out); 169 } else { 170 String [] props = (String []) obj; 171 out.writeInt(props.length); 172 for (int i = 0; i < props.length; i++) 173 writeStringOrNull(props[i], out); 174 } 175 } 176 } 177 178 187 private void writeBundleDescription(BundleDescription bundle, DataOutputStream out, boolean force) throws IOException { 188 if (force && !forcedWrite.contains(bundle)) { 189 int index = addToObjectTable(bundle); 190 out.writeByte(StateReader.OBJECT); 191 out.writeInt(index); 192 forcedWrite.add(bundle); 193 } else if (writePrefix(bundle, out)) 194 return; 195 out.writeLong(bundle.getBundleId()); writeBaseDescription(bundle, out); 198 out.writeInt(((BundleDescriptionImpl) bundle).getLazyDataOffset()); 199 out.writeInt(((BundleDescriptionImpl) bundle).getLazyDataSize()); 200 out.writeBoolean(bundle.isResolved()); 201 out.writeBoolean(bundle.isSingleton()); 202 out.writeBoolean(bundle.hasDynamicImports()); 203 out.writeBoolean(bundle.attachFragments()); 204 out.writeBoolean(bundle.dynamicFragments()); 205 writeHostSpec((HostSpecificationImpl) bundle.getHost(), out, force); 206 207 List dependencies = ((BundleDescriptionImpl) bundle).getBundleDependencies(); 208 out.writeInt(dependencies.size()); 209 for (Iterator iter = dependencies.iterator(); iter.hasNext();) 210 writeBundleDescription((BundleDescription) iter.next(), out, force); 211 } 213 214 private void writeBundleDescriptionLazyData(BundleDescription bundle, DataOutputStream out) throws IOException { 215 int dataStart = out.size(); int index = getFromObjectTable(bundle); 217 ((BundleDescriptionImpl) bundle).setLazyDataOffset(out.size()); 218 out.writeInt(index); 219 220 writeStringOrNull(bundle.getLocation(), out); 221 writeStringOrNull(bundle.getPlatformFilter(), out); 222 223 ExportPackageDescription[] exports = bundle.getExportPackages(); 224 out.writeInt(exports.length); 225 for (int i = 0; i < exports.length; i++) 226 writeExportPackageDesc((ExportPackageDescriptionImpl) exports[i], out); 227 228 ImportPackageSpecification[] imports = bundle.getImportPackages(); 229 out.writeInt(imports.length); 230 for (int i = 0; i < imports.length; i++) 231 writeImportPackageSpec(imports[i], out); 232 233 BundleSpecification[] requiredBundles = bundle.getRequiredBundles(); 234 out.writeInt(requiredBundles.length); 235 for (int i = 0; i < requiredBundles.length; i++) 236 writeBundleSpec((BundleSpecificationImpl) requiredBundles[i], out); 237 238 ExportPackageDescription[] selectedExports = bundle.getSelectedExports(); 239 if (selectedExports == null) { 240 out.writeInt(0); 241 } else { 242 out.writeInt(selectedExports.length); 243 for (int i = 0; i < selectedExports.length; i++) 244 writeExportPackageDesc((ExportPackageDescriptionImpl) selectedExports[i], out); 245 } 246 247 ExportPackageDescription[] resolvedImports = bundle.getResolvedImports(); 248 if (resolvedImports == null) { 249 out.writeInt(0); 250 } else { 251 out.writeInt(resolvedImports.length); 252 for (int i = 0; i < resolvedImports.length; i++) 253 writeExportPackageDesc((ExportPackageDescriptionImpl) resolvedImports[i], out); 254 } 255 256 BundleDescription[] resolvedRequires = bundle.getResolvedRequires(); 257 if (resolvedRequires == null) { 258 out.writeInt(0); 259 } else { 260 out.writeInt(resolvedRequires.length); 261 for (int i = 0; i < resolvedRequires.length; i++) 262 writeBundleDescription(resolvedRequires[i], out, false); 263 } 264 265 String [] ees = bundle.getExecutionEnvironments(); 266 out.writeInt(ees.length); 267 for (int i = 0; i < ees.length; i++) 268 writeStringOrNull(ees[i], out); 269 270 HashMap dynamicStamps = ((BundleDescriptionImpl) bundle).getDynamicStamps(); 271 if (dynamicStamps == null) 272 out.writeInt(0); 273 else { 274 out.writeInt(dynamicStamps.size()); 275 for (Iterator pkgs = dynamicStamps.keySet().iterator(); pkgs.hasNext();) { 276 String pkg = (String ) pkgs.next(); 277 writeStringOrNull(pkg, out); 278 out.writeLong(((Long ) dynamicStamps.get(pkg)).longValue()); 279 } 280 } 281 282 GenericDescription[] genericCapabilities = bundle.getGenericCapabilities(); 283 if (genericCapabilities == null) 284 out.writeInt(0); 285 else { 286 out.writeInt(genericCapabilities.length); 287 for (int i = 0; i < genericCapabilities.length; i++) 288 writeGenericDescription(genericCapabilities[i], out); 289 } 290 291 GenericSpecification[] genericRequires = bundle.getGenericRequires(); 292 if (genericRequires == null) 293 out.writeInt(0); 294 else { 295 out.writeInt(genericRequires.length); 296 for (int i = 0; i < genericRequires.length; i++) 297 writeGenericSpecification(genericRequires[i], out); 298 } 299 300 ((BundleDescriptionImpl) bundle).setLazyDataSize(out.size() - dataStart); 302 } 303 304 private void writeBundleSpec(BundleSpecificationImpl bundle, DataOutputStream out) throws IOException { 305 writeVersionConstraint(bundle, out); 306 writeBundleDescription((BundleDescription) bundle.getSupplier(), out, false); 307 out.writeBoolean(bundle.isExported()); 308 out.writeBoolean(bundle.isOptional()); 309 } 310 311 private void writeExportPackageDesc(ExportPackageDescriptionImpl exportPackageDesc, DataOutputStream out) throws IOException { 312 if (writePrefix(exportPackageDesc, out)) 313 return; 314 writeBaseDescription(exportPackageDesc, out); 315 out.writeBoolean(exportPackageDesc.isRoot()); 316 writeMap(out, exportPackageDesc.getAttributes()); 317 writeMap(out, exportPackageDesc.getDirectives()); 318 } 319 320 private void writeGenericDescription(GenericDescription description, DataOutputStream out) throws IOException { 321 if (writePrefix(description, out)) 322 return; 323 writeBaseDescription(description, out); 324 writeStringOrNull(description.getType() == GenericDescription.DEFAULT_TYPE ? null : description.getType(), out); 325 Dictionary attrs = description.getAttributes(); 326 Map mapAttrs = new HashMap(attrs.size()); 327 for (Enumeration keys = attrs.keys(); keys.hasMoreElements();) { 328 Object key = keys.nextElement(); 329 if (!Constants.VERSION_ATTRIBUTE.equals(key)) 330 mapAttrs.put(key, attrs.get(key)); 331 } 332 writeMap(out, mapAttrs); 333 } 334 335 private void writeGenericSpecification(GenericSpecification specification, DataOutputStream out) throws IOException { 336 writeVersionConstraint(specification, out); 337 writeStringOrNull(specification.getType() == GenericDescription.DEFAULT_TYPE ? null : specification.getType(), out); 338 GenericDescription[] suppliers = specification.getSuppliers(); 339 out.writeInt(suppliers == null ? 0 : suppliers.length); 340 if (suppliers != null) 341 for (int i = 0; i < suppliers.length; i++) 342 writeGenericDescription(suppliers[i], out); 343 out.writeInt(specification.getResolution()); 344 writeStringOrNull(specification.getMatchingFilter(), out); 345 } 346 347 private void writeMap(DataOutputStream out, Map source) throws IOException { 348 if (source == null) { 349 out.writeInt(0); 350 } else { 351 out.writeInt(source.size()); 352 Iterator iter = source.keySet().iterator(); 353 while (iter.hasNext()) { 354 String key = (String ) iter.next(); 355 Object value = source.get(key); 356 writeStringOrNull(key, out); 357 if (value instanceof String ) { 358 out.writeByte(0); 359 writeStringOrNull((String ) value, out); 360 } else if (value instanceof String []) { 361 out.writeByte(1); 362 writeList(out, (String []) value); 363 } else if (value instanceof Boolean ) { 364 out.writeByte(2); 365 out.writeBoolean(((Boolean ) value).booleanValue()); 366 } else if (value instanceof Integer ) { 367 out.writeByte(3); 368 out.writeInt(((Integer ) value).intValue()); 369 } else if (value instanceof Long ) { 370 out.writeByte(4); 371 out.writeLong(((Long ) value).longValue()); 372 } else if (value instanceof Double ) { 373 out.writeByte(5); 374 out.writeDouble(((Double ) value).doubleValue()); 375 } else if (value instanceof Version) { 376 out.writeByte(6); 377 writeVersion((Version) value, out); 378 } else if ("java.net.URI".equals(value.getClass().getName())) { out.writeByte(7); 380 writeStringOrNull(value.toString(), out); 381 } 382 } 383 } 384 } 385 386 private void writeList(DataOutputStream out, String [] list) throws IOException { 387 if (list == null) { 388 out.writeInt(0); 389 } else { 390 out.writeInt(list.length); 391 for (int i = 0; i < list.length; i++) 392 writeStringOrNull(list[i], out); 393 } 394 } 395 396 private void writeBaseDescription(BaseDescription rootDesc, DataOutputStream out) throws IOException { 397 writeStringOrNull(rootDesc.getName(), out); 398 writeVersion(rootDesc.getVersion(), out); 399 } 400 401 private void writeImportPackageSpec(ImportPackageSpecification importPackageSpec, DataOutputStream out) throws IOException { 402 writeVersionConstraint(importPackageSpec, out); 403 if (importPackageSpec.getBundle().isResolved()) 406 writeExportPackageDesc((ExportPackageDescriptionImpl) importPackageSpec.getSupplier(), out); 407 else 408 out.writeByte(StateReader.NULL); 409 410 writeStringOrNull(importPackageSpec.getBundleSymbolicName(), out); 411 writeVersionRange(importPackageSpec.getBundleVersionRange(), out); 412 writeMap(out, importPackageSpec.getAttributes()); 413 writeMap(out, importPackageSpec.getDirectives()); 414 } 415 416 private void writeHostSpec(HostSpecificationImpl host, DataOutputStream out, boolean force) throws IOException { 417 if (host == null) { 418 out.writeByte(StateReader.NULL); 419 return; 420 } 421 out.writeByte(StateReader.OBJECT); 422 writeVersionConstraint(host, out); 423 BundleDescription[] hosts = host.getHosts(); 424 if (hosts == null) { 425 out.writeInt(0); 426 return; 427 } 428 out.writeInt(hosts.length); 429 for (int i = 0; i < hosts.length; i++) 430 writeBundleDescription(hosts[i], out, force); 431 } 432 433 private void writeVersionConstraint(VersionConstraint constraint, DataOutputStream out) throws IOException { 435 writeStringOrNull(constraint.getName(), out); 436 writeVersionRange(constraint.getVersionRange(), out); 437 } 438 439 private void writeVersion(Version version, DataOutputStream out) throws IOException { 440 if (version == null || version.equals(Version.emptyVersion)) { 441 out.writeByte(StateReader.NULL); 442 return; 443 } 444 out.writeByte(StateReader.OBJECT); 445 out.writeInt(version.getMajor()); 446 out.writeInt(version.getMinor()); 447 out.writeInt(version.getMicro()); 448 writeQualifier(version.getQualifier(), out); 449 } 450 451 private void writeVersionRange(VersionRange versionRange, DataOutputStream out) throws IOException { 452 if (versionRange == null || versionRange.equals(VersionRange.emptyRange)) { 453 out.writeByte(StateReader.NULL); 454 return; 455 } 456 out.writeByte(StateReader.OBJECT); 457 writeVersion(versionRange.getMinimum(), out); 458 out.writeBoolean(versionRange.getIncludeMinimum()); 459 writeVersion(versionRange.getMaximum(), out); 460 out.writeBoolean(versionRange.getIncludeMaximum()); 461 } 462 463 private boolean writeIndex(Object object, DataOutputStream out) throws IOException { 464 if (object == null) { 465 out.writeByte(StateReader.NULL); 466 return true; 467 } 468 int index = getFromObjectTable(object); 469 if (index == -1) 470 return false; 471 out.writeByte(StateReader.INDEX); 472 out.writeInt(index); 473 return true; 474 } 475 476 public void saveStateDeprecated(StateImpl state, DataOutputStream output) throws IOException { 477 try { 478 writeStateDeprecated(state, output); 479 } finally { 480 output.close(); 481 } 482 } 483 484 private void writeStringOrNull(String string, DataOutputStream out) throws IOException { 485 if (string == null) 486 out.writeByte(StateReader.NULL); 487 else { 488 out.writeByte(StateReader.OBJECT); 489 out.writeUTF(string); 490 } 491 } 492 493 private void writeQualifier(String string, DataOutputStream out) throws IOException { 494 if (string != null && string.length() == 0) 495 string = null; 496 writeStringOrNull(string, out); 497 } 498 } 499 | Popular Tags |