content: /**
   *  Licensed to the Apache Software Foundation (ASF) under one or more
   *  contributor license agreements.  See the NOTICE file distributed with
   *  this work for additional information regarding copyright ownership.
   *  The ASF licenses this file to You under the Apache License, Version 2.0
   *  (the "License"); you may not use this file except in compliance with
   *  the License.  You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   */
  package org.apache.aries.blueprint.spring.extender;
  
  import java.io.BufferedWriter;
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.InputStream;
  import java.io.OutputStreamWriter;
  import java.net.URI;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.LinkedHashSet;
  import java.util.List;
  import java.util.Set;
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  
  import org.apache.aries.blueprint.services.BlueprintExtenderService;
  import org.apache.felix.utils.extender.Extension;
  import org.osgi.framework.Bundle;
  import org.osgi.service.blueprint.container.BlueprintContainer;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.w3c.dom.Attr;
  import org.w3c.dom.Document;
  import org.xml.sax.InputSource;
  
  public class SpringOsgiExtension implements Extension {
  
      private static final Logger LOGGER = LoggerFactory.getLogger(SpringOsgiExtension.class);
  
      private final BlueprintExtenderService blueprintExtenderService;
      private final Bundle bundle;
      private final List<URL> paths;
  
      BlueprintContainer container;
  
      public SpringOsgiExtension(BlueprintExtenderService blueprintExtenderService, Bundle bundle, List<URL> paths) {
          // TODO: parse Spring-Context header directives
          // TODO:   create-asynchrously
          // TODO:   wait-for-dependencies
          // TODO:   timeout
          // TODO:   publish-context
          this.blueprintExtenderService = blueprintExtenderService;
          this.bundle = bundle;
          this.paths = paths;
      }
  
      @Override
      public void start() throws Exception {
          List<Object> bpPaths = new ArrayList<Object>();
  
          Set<URI> namespaces = new LinkedHashSet<URI>();
          DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
          dbf.setNamespaceAware(true);
          for (URL url : paths) {
              InputStream is = url.openStream();
              try {
                  InputSource inputSource = new InputSource(is);
                  DocumentBuilder builder = dbf.newDocumentBuilder();
                  Document doc = builder.parse(inputSource);
                  Attr schemaLoc = doc.getDocumentElement().getAttributeNodeNS("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation");
                  if (schemaLoc != null) {
                      List<String> locs = new ArrayList<String>(Arrays.asList(schemaLoc.getValue().split("\\s+")));
                      locs.remove("");
                      for (int i = 0; i < locs.size() / 2; i++) {
                          String ns = locs.get(i * 2);
                          namespaces.add(URI.create(ns));
                          if (ns.startsWith("http://www.springframework.org/schema/osgi-compendium")) {
                              namespaces.add(URI.create(SpringOsgiCompendiumNamespaceHandler.CM_NAMESPACE));
                          }
                      }
                  }
              } finally {
                  is.close();
              }
          }
  
          File file = File.createTempFile("blueprint-spring-extender", ".xml");
          BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
          try {
              writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
              writer.write("<blueprint xmlns=\"http://www.osgi.org/xmlns/blueprint/v1.0.0\"\n");
              writer.write("\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
              writer.write("\txmlns:bean=\"http://www.springframework.org/schema/beans\"\n");
              writer.write("\txsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-" + SpringXsdVersionResolver.resolve() + ".xsd\">\n");
              for (URL url : paths) {
                  writer.write("\t<bean:import resource=\"" + url.toString() + "\"/>\n");
              }
              writer.write("</blueprint>\n");
          } finally {
              writer.close();
          }
          LOGGER.info("Generated blueprint for bundle {}/{} at {}", bundle.getSymbolicName(), bundle.getVersion(), file);
          bpPaths.add(file.toURI().toURL());
          container = blueprintExtenderService.createContainer(bundle, bpPaths, namespaces);
      }
  
      @Override
      public void destroy() throws Exception {
          // Make sure the container has not been destroyed yet
          if (container == blueprintExtenderService.getContainer(bundle)) {
              blueprintExtenderService.destroyContainer(bundle, container);
          }
      }
  
  }
  