/**
   * This method does what the report designer does on save.
   *
   * @param report
   * @param file
   * @throws Exception
   */
  private void saveReport(final MasterReport report, final File file) throws Exception {
    BundleWriter.writeReportToZipFile(report, file);
    final ResourceManager resourceManager = report.getResourceManager();
    final Resource bundleResource = resourceManager.createDirectly(file, DocumentBundle.class);
    final DocumentBundle bundle = (DocumentBundle) bundleResource.getResource();
    final ResourceKey bundleKey = bundle.getBundleKey();

    final MemoryDocumentBundle mem = new MemoryDocumentBundle();
    BundleUtilities.copyStickyInto(mem, bundle);
    BundleUtilities.copyMetaData(mem, bundle);
    report.setBundle(mem);
    report.setContentBase(mem.getBundleMainKey());
    report.setDefinitionSource(bundleKey);
  }
  public static void copyStaticResources(
      final WriteableDocumentBundle bundle,
      final BundleWriterState state,
      final Expression expression,
      final BeanUtility beanUtility,
      final ExpressionPropertyMetaData[] datas)
      throws BundleWriterException, BeanException {
    if (bundle == null) {
      throw new NullPointerException();
    }
    if (state == null) {
      throw new NullPointerException();
    }
    if (expression == null) {
      throw new NullPointerException();
    }
    if (beanUtility == null) {
      throw new NullPointerException();
    }
    if (datas == null) {
      throw new NullPointerException();
    }

    final AbstractReportDefinition report = state.getReport();
    final ResourceKey contentBase = report.getContentBase();
    if (contentBase == null) {
      // treat all resources as linked resources ..
      return;
    }
    final ResourceKey defSource = report.getDefinitionSource();
    if (defSource == null) {
      // treat all resources as linked resources ..
      return;
    }

    if (ObjectUtilities.equal(contentBase.getParent(), defSource.getParent()) == false) {
      // treat all resources as linked resources ..
      return;
    }

    final Object contentBasePathRaw = contentBase.getIdentifier();
    if (contentBasePathRaw instanceof String == false) {
      return;
    }

    final String contentBasePath = String.valueOf(contentBasePathRaw);
    final ResourceManager resourceManager = state.getMasterReport().getResourceManager();

    for (int i = 0; i < datas.length; i++) {
      final ExpressionPropertyMetaData attributeMetaData = datas[i];
      final Object attValue = beanUtility.getProperty(attributeMetaData.getName());
      if (attValue == null) {
        continue;
      }
      final ResourceReference[] referencedResources =
          attributeMetaData.getReferencedResources(expression, attValue, report, resourceManager);
      for (int j = 0; j < referencedResources.length; j++) {
        final ResourceReference reference = referencedResources[j];
        if (reference.isLinked()) {
          continue;
        }

        final ResourceKey path = reference.getPath();
        final Object identifier = path.getIdentifier();
        if (identifier instanceof String == false) {
          continue;
        }

        final String identifierString = String.valueOf(identifier);
        final String relativePath =
            IOUtils.getInstance().createRelativePath(identifierString, contentBasePath);
        try {
          BundleUtilities.copyInto(bundle, relativePath, path, resourceManager);
        } catch (Exception e) {
          throw new BundleWriterException("Failed to copy content from key " + path, e);
        }
      }
    }
  }