PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/eclipse_SDK-3.7.1/plugins/org.eclipse.osgi.source_3.7.1.R37x_v20110808-1106/org/eclipse/osgi/internal/resolver/StateWriter.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 695 lines | 588 code | 56 blank | 51 comment | 181 complexity | 43780c2ea8d0217f65aacc819426efaa MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2003, 2011 IBM Corporation and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * IBM Corporation - initial API and implementation
  10. * Rob Harrop - SpringSource Inc. (bug 247522)
  11. *******************************************************************************/
  12. package org.eclipse.osgi.internal.resolver;
  13. import java.io.*;
  14. import java.util.*;
  15. import org.eclipse.osgi.service.resolver.*;
  16. import org.osgi.framework.*;
  17. /**
  18. * This class is <strong>not</strong> thread safe. Instances must not be
  19. * shared across multiple threads.
  20. */
  21. class StateWriter {
  22. // objectTable will be a hashmap of objects. The objects will be things
  23. // like BundleDescription, ExportPackageDescription, Version etc.. The integer
  24. // index value will be used in the cache to allow cross-references in the
  25. // cached state.
  26. private final Map<Object, Integer> objectTable = new HashMap<Object, Integer>();
  27. private final List<Object> forcedWrite = new ArrayList<Object>();
  28. private int addToObjectTable(Object object) {
  29. Integer cur = objectTable.get(object);
  30. if (cur != null)
  31. return cur.intValue();
  32. objectTable.put(object, new Integer(objectTable.size()));
  33. // return the index of the object just added (i.e. size - 1)
  34. return (objectTable.size() - 1);
  35. }
  36. private int getFromObjectTable(Object object) {
  37. if (objectTable != null) {
  38. Object objectResult = objectTable.get(object);
  39. if (objectResult != null) {
  40. return ((Integer) objectResult).intValue();
  41. }
  42. }
  43. return -1;
  44. }
  45. private boolean writePrefix(Object object, DataOutputStream out) throws IOException {
  46. if (writeIndex(object, out))
  47. return true;
  48. // add this object to the object table first
  49. int index = addToObjectTable(object);
  50. out.writeByte(StateReader.OBJECT);
  51. out.writeInt(index);
  52. return false;
  53. }
  54. private void writeStateDeprecated(StateImpl state, DataOutputStream out) throws IOException {
  55. out.write(StateReader.STATE_CACHE_VERSION);
  56. if (writePrefix(state, out))
  57. return;
  58. out.writeLong(state.getTimeStamp());
  59. // write the platform property keys
  60. String[] platformPropKeys = state.getPlatformPropertyKeys();
  61. writePlatformProp(platformPropKeys, out);
  62. Dictionary<Object, Object>[] propSet = state.getPlatformProperties();
  63. out.writeInt(propSet.length);
  64. for (int i = 0; i < propSet.length; i++) {
  65. Dictionary<Object, Object> props = propSet[i];
  66. out.writeInt(platformPropKeys.length);
  67. for (int j = 0; j < platformPropKeys.length; j++)
  68. writePlatformProp(props.get(platformPropKeys[j]), out);
  69. }
  70. BundleDescription[] bundles = state.getBundles();
  71. StateHelperImpl.getInstance().sortBundles(bundles);
  72. out.writeInt(bundles.length);
  73. if (bundles.length == 0)
  74. return;
  75. for (int i = 0; i < bundles.length; i++)
  76. writeBundleDescription(bundles[i], out, false);
  77. out.writeBoolean(state.isResolved());
  78. // save the lazy data offset
  79. out.writeInt(out.size());
  80. for (int i = 0; i < bundles.length; i++)
  81. writeBundleDescriptionLazyData(bundles[i], out);
  82. }
  83. public void saveState(StateImpl state, File stateFile, File lazyFile) throws IOException {
  84. DataOutputStream outLazy = null;
  85. DataOutputStream outState = null;
  86. FileOutputStream fosLazy = null;
  87. FileOutputStream fosState = null;
  88. synchronized (state.monitor) {
  89. try {
  90. BundleDescription[] bundles = state.getBundles();
  91. StateHelperImpl.getInstance().sortBundles(bundles);
  92. // need to prime the object table with all bundles
  93. // this allows us to write only indexes to bundles in the lazy data
  94. for (int i = 0; i < bundles.length; i++) {
  95. addToObjectTable(bundles[i]);
  96. if (bundles[i].getHost() != null)
  97. addToObjectTable(bundles[i].getHost());
  98. }
  99. // first write the lazy data to get the offsets and sizes to the lazy data
  100. 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. // now write the state data
  105. 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. // write the platform property keys
  112. String[] platformPropKeys = state.getPlatformPropertyKeys();
  113. writePlatformProp(platformPropKeys, outState);
  114. // write the platform property values
  115. Dictionary<Object, Object>[] propSet = state.getPlatformProperties();
  116. outState.writeInt(propSet.length);
  117. for (int i = 0; i < propSet.length; i++) {
  118. Dictionary<Object, Object> 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. for (int i = 0; i < bundles.length; i++)
  125. // write out each bundle with the force flag set to make sure
  126. // the data is written at least once in the non-lazy state data
  127. writeBundleDescription(bundles[i], outState, true);
  128. // write the DisabledInfos
  129. DisabledInfo[] infos = state.getDisabledInfos();
  130. outState.writeInt(infos.length);
  131. for (int i = 0; i < infos.length; i++)
  132. writeDisabledInfo(infos[i], outState);
  133. outState.writeBoolean(state.isResolved());
  134. } finally {
  135. if (outLazy != null) {
  136. try {
  137. outLazy.flush();
  138. fosLazy.getFD().sync();
  139. } catch (IOException e) {
  140. // do nothing, we tried
  141. }
  142. try {
  143. outLazy.close();
  144. } catch (IOException e) {
  145. // do nothing
  146. }
  147. }
  148. if (outState != null) {
  149. try {
  150. outState.flush();
  151. fosState.getFD().sync();
  152. } catch (IOException e) {
  153. // do nothing, we tried
  154. }
  155. try {
  156. outState.close();
  157. } catch (IOException e) {
  158. // do nothing
  159. }
  160. }
  161. }
  162. }
  163. }
  164. private void writePlatformProp(Object obj, DataOutputStream out) throws IOException {
  165. if (!(obj instanceof String) && !(obj instanceof String[]))
  166. out.writeByte(StateReader.NULL);
  167. else {
  168. out.writeByte(StateReader.OBJECT);
  169. if (obj instanceof String) {
  170. out.writeInt(1);
  171. writeStringOrNull((String) obj, out);
  172. } else {
  173. String[] props = (String[]) obj;
  174. out.writeInt(props.length);
  175. for (int i = 0; i < props.length; i++)
  176. writeStringOrNull(props[i], out);
  177. }
  178. }
  179. }
  180. /*
  181. * The force flag is used when writing the non-lazy state data. This forces the data to be
  182. * written once even if the object exists in the object table.
  183. * This is needed because we want to write the lazy data first but we only want
  184. * to include indexes to the actual bundles in the lazy data. To do this we
  185. * prime the object table with all the bundles first. Then we write the
  186. * lazy data. Finally we write the non-lazy data and force a write of the
  187. * bundles data once even if the bundle is in the object table.
  188. */
  189. private void writeBundleDescription(BundleDescription bundle, DataOutputStream out, boolean force) throws IOException {
  190. if (force && !forcedWrite.contains(bundle)) {
  191. int index = addToObjectTable(bundle);
  192. out.writeByte(StateReader.OBJECT);
  193. out.writeInt(index);
  194. forcedWrite.add(bundle);
  195. } else if (writePrefix(bundle, out))
  196. return;
  197. // first write out non-lazy loaded data
  198. out.writeLong(bundle.getBundleId()); // ID must be the first thing
  199. writeBaseDescription(bundle, out);
  200. out.writeInt(((BundleDescriptionImpl) bundle).getLazyDataOffset());
  201. out.writeInt(((BundleDescriptionImpl) bundle).getLazyDataSize());
  202. out.writeBoolean(bundle.isResolved());
  203. out.writeBoolean(bundle.isSingleton());
  204. out.writeBoolean(bundle.hasDynamicImports());
  205. out.writeBoolean(bundle.attachFragments());
  206. out.writeBoolean(bundle.dynamicFragments());
  207. writeList(out, (String[]) ((BundleDescriptionImpl) bundle).getDirective(Constants.MANDATORY_DIRECTIVE));
  208. writeMap(out, bundle.getAttributes());
  209. writeHostSpec((HostSpecificationImpl) bundle.getHost(), out, force);
  210. List<BundleDescription> dependencies = ((BundleDescriptionImpl) bundle).getBundleDependencies();
  211. out.writeInt(dependencies.size());
  212. for (Iterator<BundleDescription> iter = dependencies.iterator(); iter.hasNext();)
  213. writeBundleDescription(iter.next(), out, force);
  214. // the rest is lazy loaded data
  215. }
  216. private void writeBundleDescriptionLazyData(BundleDescription bundle, DataOutputStream out) throws IOException {
  217. int dataStart = out.size(); // save the offset of lazy data start
  218. int index = getFromObjectTable(bundle);
  219. ((BundleDescriptionImpl) bundle).setLazyDataOffset(out.size());
  220. out.writeInt(index);
  221. writeStringOrNull(bundle.getLocation(), out);
  222. writeStringOrNull(bundle.getPlatformFilter(), out);
  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. ImportPackageSpecification[] imports = bundle.getImportPackages();
  228. out.writeInt(imports.length);
  229. for (int i = 0; i < imports.length; i++)
  230. writeImportPackageSpec(imports[i], out);
  231. BundleSpecification[] requiredBundles = bundle.getRequiredBundles();
  232. out.writeInt(requiredBundles.length);
  233. for (int i = 0; i < requiredBundles.length; i++)
  234. writeBundleSpec((BundleSpecificationImpl) requiredBundles[i], out);
  235. ExportPackageDescription[] selectedExports = bundle.getSelectedExports();
  236. if (selectedExports == null) {
  237. out.writeInt(0);
  238. } else {
  239. out.writeInt(selectedExports.length);
  240. for (int i = 0; i < selectedExports.length; i++)
  241. writeExportPackageDesc((ExportPackageDescriptionImpl) selectedExports[i], out);
  242. }
  243. ExportPackageDescription[] substitutedExports = bundle.getSubstitutedExports();
  244. if (substitutedExports == null) {
  245. out.writeInt(0);
  246. } else {
  247. out.writeInt(substitutedExports.length);
  248. for (int i = 0; i < substitutedExports.length; i++)
  249. writeExportPackageDesc((ExportPackageDescriptionImpl) substitutedExports[i], out);
  250. }
  251. ExportPackageDescription[] resolvedImports = bundle.getResolvedImports();
  252. if (resolvedImports == null) {
  253. out.writeInt(0);
  254. } else {
  255. out.writeInt(resolvedImports.length);
  256. for (int i = 0; i < resolvedImports.length; i++)
  257. writeExportPackageDesc((ExportPackageDescriptionImpl) resolvedImports[i], out);
  258. }
  259. BundleDescription[] resolvedRequires = bundle.getResolvedRequires();
  260. if (resolvedRequires == null) {
  261. out.writeInt(0);
  262. } else {
  263. out.writeInt(resolvedRequires.length);
  264. for (int i = 0; i < resolvedRequires.length; i++)
  265. writeBundleDescription(resolvedRequires[i], out, false);
  266. }
  267. String[] ees = bundle.getExecutionEnvironments();
  268. out.writeInt(ees.length);
  269. for (int i = 0; i < ees.length; i++)
  270. writeStringOrNull(ees[i], out);
  271. Map<String, Long> dynamicStamps = ((BundleDescriptionImpl) bundle).getDynamicStamps();
  272. if (dynamicStamps == null)
  273. out.writeInt(0);
  274. else {
  275. out.writeInt(dynamicStamps.size());
  276. for (Iterator<String> pkgs = dynamicStamps.keySet().iterator(); pkgs.hasNext();) {
  277. String pkg = pkgs.next();
  278. writeStringOrNull(pkg, out);
  279. out.writeLong(dynamicStamps.get(pkg).longValue());
  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. GenericSpecification[] genericRequires = bundle.getGenericRequires();
  291. if (genericRequires == null)
  292. out.writeInt(0);
  293. else {
  294. out.writeInt(genericRequires.length);
  295. for (int i = 0; i < genericRequires.length; i++)
  296. writeGenericSpecification(genericRequires[i], out);
  297. }
  298. GenericDescription[] selectedCapabilities = bundle.getSelectedGenericCapabilities();
  299. if (selectedCapabilities == null)
  300. out.writeInt(0);
  301. else {
  302. out.writeInt(selectedCapabilities.length);
  303. for (int i = 0; i < selectedCapabilities.length; i++)
  304. writeGenericDescription(selectedCapabilities[i], out);
  305. }
  306. GenericDescription[] resolvedCapabilities = bundle.getResolvedGenericRequires();
  307. if (resolvedCapabilities == null)
  308. out.writeInt(0);
  309. else {
  310. out.writeInt(resolvedCapabilities.length);
  311. for (int i = 0; i < resolvedCapabilities.length; i++)
  312. writeGenericDescription(resolvedCapabilities[i], out);
  313. }
  314. writeNativeCode(bundle.getNativeCodeSpecification(), out);
  315. writeMap(out, ((BundleDescriptionImpl) bundle).getWiresInternal());
  316. // save the size of the lazy data
  317. ((BundleDescriptionImpl) bundle).setLazyDataSize(out.size() - dataStart);
  318. }
  319. private void writeDisabledInfo(DisabledInfo disabledInfo, DataOutputStream out) throws IOException {
  320. writeStringOrNull(disabledInfo.getPolicyName(), out);
  321. writeStringOrNull(disabledInfo.getMessage(), out);
  322. writeBundleDescription(disabledInfo.getBundle(), out, false);
  323. }
  324. private void writeBundleSpec(BundleSpecificationImpl bundle, DataOutputStream out) throws IOException {
  325. if (writePrefix(bundle, out))
  326. return;
  327. writeVersionConstraint(bundle, out);
  328. writeBundleDescription((BundleDescription) bundle.getSupplier(), out, false);
  329. out.writeBoolean(bundle.isExported());
  330. out.writeBoolean(bundle.isOptional());
  331. writeMap(out, bundle.getAttributes());
  332. }
  333. private void writeExportPackageDesc(ExportPackageDescriptionImpl exportPackageDesc, DataOutputStream out) throws IOException {
  334. if (writePrefix(exportPackageDesc, out))
  335. return;
  336. writeBaseDescription(exportPackageDesc, out);
  337. writeBundleDescription(exportPackageDesc.getExporter(), out, false);
  338. writeMap(out, exportPackageDesc.getAttributes());
  339. writeMap(out, exportPackageDesc.getDirectives());
  340. writeExportPackageDesc((ExportPackageDescriptionImpl) exportPackageDesc.getFragmentDeclaration(), out);
  341. }
  342. private void writeGenericDescription(GenericDescription description, DataOutputStream out) throws IOException {
  343. if (writePrefix(description, out))
  344. return;
  345. writeBaseDescription(description, out);
  346. writeBundleDescription(description.getSupplier(), out, false);
  347. writeStringOrNull(description.getType() == GenericDescription.DEFAULT_TYPE ? null : description.getType(), out);
  348. Dictionary<String, Object> attrs = description.getAttributes();
  349. Map<String, Object> mapAttrs = new HashMap<String, Object>(attrs.size());
  350. for (Enumeration<String> keys = attrs.keys(); keys.hasMoreElements();) {
  351. String key = keys.nextElement();
  352. mapAttrs.put(key, attrs.get(key));
  353. }
  354. writeMap(out, mapAttrs);
  355. Map<String, String> directives = description.getDeclaredDirectives();
  356. writeMap(out, directives);
  357. writeGenericDescription((GenericDescription) ((BaseDescriptionImpl) description).getFragmentDeclaration(), out);
  358. }
  359. private void writeGenericSpecification(GenericSpecification specification, DataOutputStream out) throws IOException {
  360. if (writePrefix(specification, out))
  361. return;
  362. writeVersionConstraint(specification, out);
  363. writeStringOrNull(specification.getType() == GenericDescription.DEFAULT_TYPE ? null : specification.getType(), out);
  364. GenericDescription[] suppliers = specification.getSuppliers();
  365. out.writeInt(suppliers == null ? 0 : suppliers.length);
  366. if (suppliers != null)
  367. for (int i = 0; i < suppliers.length; i++)
  368. writeGenericDescription(suppliers[i], out);
  369. out.writeInt(specification.getResolution());
  370. writeStringOrNull(specification.getMatchingFilter(), out);
  371. }
  372. private void writeNativeCode(NativeCodeSpecification nativeCodeSpecification, DataOutputStream out) throws IOException {
  373. if (nativeCodeSpecification == null) {
  374. out.writeBoolean(false);
  375. return;
  376. }
  377. out.writeBoolean(true);
  378. out.writeBoolean(nativeCodeSpecification.isOptional());
  379. NativeCodeDescription[] nativeDescs = nativeCodeSpecification.getPossibleSuppliers();
  380. int numDescs = nativeDescs == null ? 0 : nativeDescs.length;
  381. out.writeInt(numDescs);
  382. int supplierIndex = -1;
  383. for (int i = 0; i < numDescs; i++) {
  384. if (nativeDescs[i] == nativeCodeSpecification.getSupplier())
  385. supplierIndex = i;
  386. writeNativeCodeDescription(nativeDescs[i], out);
  387. }
  388. out.writeInt(supplierIndex);
  389. }
  390. private void writeNativeCodeDescription(NativeCodeDescription nativeCodeDescription, DataOutputStream out) throws IOException {
  391. writeBaseDescription(nativeCodeDescription, out);
  392. writeBundleDescription(nativeCodeDescription.getSupplier(), out, false);
  393. Filter filter = nativeCodeDescription.getFilter();
  394. writeStringOrNull(filter == null ? null : filter.toString(), out);
  395. writeStringArray(nativeCodeDescription.getLanguages(), out);
  396. writeStringArray(nativeCodeDescription.getNativePaths(), out);
  397. writeStringArray(nativeCodeDescription.getOSNames(), out);
  398. writeVersionRanges(nativeCodeDescription.getOSVersions(), out);
  399. writeStringArray(nativeCodeDescription.getProcessors(), out);
  400. out.writeBoolean(nativeCodeDescription.hasInvalidNativePaths());
  401. }
  402. private void writeVersionRanges(VersionRange[] ranges, DataOutputStream out) throws IOException {
  403. out.writeInt(ranges == null ? 0 : ranges.length);
  404. if (ranges == null)
  405. return;
  406. for (int i = 0; i < ranges.length; i++)
  407. writeVersionRange(ranges[i], out);
  408. }
  409. private void writeStringArray(String[] strings, DataOutputStream out) throws IOException {
  410. out.writeInt(strings == null ? 0 : strings.length);
  411. if (strings == null)
  412. return;
  413. for (int i = 0; i < strings.length; i++)
  414. writeStringOrNull(strings[i], out);
  415. }
  416. private void writeMap(DataOutputStream out, Map<String, ?> source) throws IOException {
  417. if (source == null) {
  418. out.writeInt(0);
  419. } else {
  420. out.writeInt(source.size());
  421. Iterator<String> iter = source.keySet().iterator();
  422. while (iter.hasNext()) {
  423. String key = iter.next();
  424. Object value = source.get(key);
  425. writeStringOrNull(key, out);
  426. if (value instanceof String) {
  427. out.writeByte(0);
  428. writeStringOrNull((String) value, out);
  429. } else if (value instanceof String[]) {
  430. out.writeByte(1);
  431. writeList(out, (String[]) value);
  432. } else if (value instanceof Boolean) {
  433. out.writeByte(2);
  434. out.writeBoolean(((Boolean) value).booleanValue());
  435. } else if (value instanceof Integer) {
  436. out.writeByte(3);
  437. out.writeInt(((Integer) value).intValue());
  438. } else if (value instanceof Long) {
  439. out.writeByte(4);
  440. out.writeLong(((Long) value).longValue());
  441. } else if (value instanceof Double) {
  442. out.writeByte(5);
  443. out.writeDouble(((Double) value).doubleValue());
  444. } else if (value instanceof Version) {
  445. out.writeByte(6);
  446. writeVersion((Version) value, out);
  447. } else if ("java.net.URI".equals(value.getClass().getName())) { //$NON-NLS-1$
  448. out.writeByte(7);
  449. writeStringOrNull(value.toString(), out);
  450. } else if (value instanceof List) {
  451. writeList(out, (List<?>) value);
  452. }
  453. }
  454. }
  455. }
  456. private void writeList(DataOutputStream out, List<?> list) throws IOException {
  457. byte type = getListType(list);
  458. if (type == -2)
  459. return; // don't understand the list type
  460. out.writeByte(8);
  461. out.writeByte(type);
  462. out.writeInt(list.size());
  463. for (Object value : list) {
  464. switch (type) {
  465. case 0 :
  466. writeStringOrNull((String) value, out);
  467. break;
  468. case 3 :
  469. out.writeInt(((Integer) value).intValue());
  470. break;
  471. case 4 :
  472. out.writeLong(((Long) value).longValue());
  473. break;
  474. case 5 :
  475. out.writeDouble(((Double) value).doubleValue());
  476. break;
  477. case 6 :
  478. writeVersion((Version) value, out);
  479. break;
  480. case 7 :
  481. writeStateWire((StateWire) value, out);
  482. default :
  483. break;
  484. }
  485. }
  486. }
  487. private void writeStateWire(StateWire wire, DataOutputStream out) throws IOException {
  488. VersionConstraint requirement = wire.getDeclaredRequirement();
  489. if (requirement instanceof ImportPackageSpecificationImpl) {
  490. out.writeByte(0);
  491. writeImportPackageSpec((ImportPackageSpecificationImpl) requirement, out);
  492. } else if (requirement instanceof BundleSpecificationImpl) {
  493. out.writeByte(1);
  494. writeBundleSpec((BundleSpecificationImpl) requirement, out);
  495. } else if (requirement instanceof HostSpecificationImpl) {
  496. out.writeByte(2);
  497. writeHostSpec((HostSpecificationImpl) requirement, out, false);
  498. } else if (requirement instanceof GenericSpecificationImpl) {
  499. out.writeByte(3);
  500. writeGenericSpecification((GenericSpecificationImpl) requirement, out);
  501. } else
  502. throw new IllegalArgumentException("Unknown requiement type: " + requirement.getClass());
  503. BaseDescription capability = wire.getDeclaredCapability();
  504. if (capability instanceof BundleDescription)
  505. writeBundleDescription((BundleDescription) capability, out, false);
  506. else if (capability instanceof ExportPackageDescriptionImpl)
  507. writeExportPackageDesc((ExportPackageDescriptionImpl) capability, out);
  508. else if (capability instanceof GenericDescription)
  509. writeGenericDescription((GenericDescription) capability, out);
  510. else
  511. throw new IllegalArgumentException("Unknown capability type: " + requirement.getClass());
  512. writeBundleDescription(wire.getRequirementHost(), out, false);
  513. writeBundleDescription(wire.getCapabilityHost(), out, false);
  514. }
  515. private byte getListType(List<?> list) {
  516. if (list.size() == 0)
  517. return -1;
  518. Object type = list.get(0);
  519. if (type instanceof String)
  520. return 0;
  521. if (type instanceof Integer)
  522. return 3;
  523. if (type instanceof Long)
  524. return 4;
  525. if (type instanceof Double)
  526. return 5;
  527. if (type instanceof Version)
  528. return 6;
  529. if (type instanceof StateWire)
  530. return 7;
  531. return -2;
  532. }
  533. private void writeList(DataOutputStream out, String[] list) throws IOException {
  534. if (list == null) {
  535. out.writeInt(0);
  536. } else {
  537. out.writeInt(list.length);
  538. for (int i = 0; i < list.length; i++)
  539. writeStringOrNull(list[i], out);
  540. }
  541. }
  542. private void writeBaseDescription(BaseDescription rootDesc, DataOutputStream out) throws IOException {
  543. writeStringOrNull(rootDesc.getName(), out);
  544. writeVersion(rootDesc.getVersion(), out);
  545. }
  546. private void writeImportPackageSpec(ImportPackageSpecification importPackageSpec, DataOutputStream out) throws IOException {
  547. if (writePrefix(importPackageSpec, out))
  548. return;
  549. writeVersionConstraint(importPackageSpec, out);
  550. // TODO this is a hack until the state dynamic loading is cleaned up
  551. // we should only write the supplier if we are resolved
  552. if (importPackageSpec.getBundle().isResolved())
  553. writeExportPackageDesc((ExportPackageDescriptionImpl) importPackageSpec.getSupplier(), out);
  554. else
  555. out.writeByte(StateReader.NULL);
  556. writeStringOrNull(importPackageSpec.getBundleSymbolicName(), out);
  557. writeVersionRange(importPackageSpec.getBundleVersionRange(), out);
  558. writeMap(out, importPackageSpec.getAttributes());
  559. writeMap(out, importPackageSpec.getDirectives());
  560. }
  561. private void writeHostSpec(HostSpecificationImpl host, DataOutputStream out, boolean force) throws IOException {
  562. if (host != null && force && !forcedWrite.contains(host)) {
  563. int index = addToObjectTable(host);
  564. out.writeByte(StateReader.OBJECT);
  565. out.writeInt(index);
  566. forcedWrite.add(host);
  567. } else if (writePrefix(host, out))
  568. return;
  569. writeVersionConstraint(host, out);
  570. BundleDescription[] hosts = host.getHosts();
  571. if (hosts == null) {
  572. out.writeInt(0);
  573. return;
  574. }
  575. out.writeInt(hosts.length);
  576. for (int i = 0; i < hosts.length; i++)
  577. writeBundleDescription(hosts[i], out, force);
  578. writeMap(out, host.getAttributes());
  579. }
  580. // called by writers for VersionConstraintImpl subclasses
  581. private void writeVersionConstraint(VersionConstraint constraint, DataOutputStream out) throws IOException {
  582. writeStringOrNull(constraint.getName(), out);
  583. writeVersionRange(constraint.getVersionRange(), out);
  584. }
  585. private void writeVersion(Version version, DataOutputStream out) throws IOException {
  586. if (version == null || version.equals(Version.emptyVersion)) {
  587. out.writeByte(StateReader.NULL);
  588. return;
  589. }
  590. out.writeByte(StateReader.OBJECT);
  591. out.writeInt(version.getMajor());
  592. out.writeInt(version.getMinor());
  593. out.writeInt(version.getMicro());
  594. writeQualifier(version.getQualifier(), out);
  595. }
  596. private void writeVersionRange(VersionRange versionRange, DataOutputStream out) throws IOException {
  597. if (versionRange == null || versionRange.equals(VersionRange.emptyRange)) {
  598. out.writeByte(StateReader.NULL);
  599. return;
  600. }
  601. out.writeByte(StateReader.OBJECT);
  602. writeVersion(versionRange.getMinimum(), out);
  603. out.writeBoolean(versionRange.getIncludeMinimum());
  604. writeVersion(versionRange.getMaximum(), out);
  605. out.writeBoolean(versionRange.getIncludeMaximum());
  606. }
  607. private boolean writeIndex(Object object, DataOutputStream out) throws IOException {
  608. if (object == null) {
  609. out.writeByte(StateReader.NULL);
  610. return true;
  611. }
  612. int index = getFromObjectTable(object);
  613. if (index == -1)
  614. return false;
  615. out.writeByte(StateReader.INDEX);
  616. out.writeInt(index);
  617. return true;
  618. }
  619. public void saveStateDeprecated(StateImpl state, DataOutputStream output) throws IOException {
  620. try {
  621. writeStateDeprecated(state, output);
  622. } finally {
  623. output.close();
  624. }
  625. }
  626. private void writeStringOrNull(String string, DataOutputStream out) throws IOException {
  627. if (string == null)
  628. out.writeByte(StateReader.NULL);
  629. else {
  630. out.writeByte(StateReader.OBJECT);
  631. out.writeUTF(string);
  632. }
  633. }
  634. private void writeQualifier(String string, DataOutputStream out) throws IOException {
  635. if (string != null && string.length() == 0)
  636. string = null;
  637. writeStringOrNull(string, out);
  638. }
  639. }