Package org.apache.aries.application.modelling.impl

Source Code of org.apache.aries.application.modelling.impl.ModelledResourceManagerImpl$ZipBlueprintIterator

/*
* 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 WARRANTIESOR 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.application.modelling.impl;

import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.aries.application.InvalidAttributeException;
import org.apache.aries.application.modelling.ExportedService;
import org.apache.aries.application.modelling.ImportedService;
import org.apache.aries.application.modelling.ModelledResource;
import org.apache.aries.application.modelling.ModelledResourceManager;
import org.apache.aries.application.modelling.ModellerException;
import org.apache.aries.application.modelling.ModellingManager;
import org.apache.aries.application.modelling.ParsedServiceElements;
import org.apache.aries.application.modelling.ParserProxy;
import org.apache.aries.application.modelling.ServiceModeller;
import org.apache.aries.application.modelling.internal.BundleBlueprintParser;
import org.apache.aries.application.modelling.internal.MessageUtil;
import org.apache.aries.util.filesystem.FileSystem;
import org.apache.aries.util.filesystem.ICloseableDirectory;
import org.apache.aries.util.filesystem.IDirectory;
import org.apache.aries.util.filesystem.IFile;
import org.apache.aries.util.io.IOUtils;
import org.apache.aries.util.manifest.BundleManifest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class ModelledResourceManagerImpl implements ModelledResourceManager
{
  private final Logger _logger = LoggerFactory.getLogger(ModelledResourceManagerImpl.class);
  private ParserProxy _parserProxy;
  private ModellingManager _modellingManager;
  private Collection<ServiceModeller> modellingPlugins;

  public void setModellingPlugins(Collection<ServiceModeller> modellingPlugins) {
    this.modellingPlugins = modellingPlugins;
  }

  public void setModellingManager (ModellingManager m) {
    _modellingManager = m;
  }

  public void setParserProxy (ParserProxy p) {
    _parserProxy = p;
  }
 
  public ParserProxy getParserProxy() {
    return _parserProxy;
  }

  /**
   * For a given file, which we know to be a bundle, parse out all the
   * service, reference and reference-list elements. This method will return
   * all such services, including anonymous ones,
   * but should not return indistinguishable duplicates.
   * @param archive CommonArchive. The caller is responsible for closing this afterwards.
   * @return ParsedServiceElementsImpl
   * @throws OpenFailureException
   */
  public ParsedServiceElements getServiceElements (IDirectory archive) throws ModellerException {
      BundleManifest bm = BundleManifest.fromBundle(archive);
      return getServiceElements(bm, archive);
  }
 
  public ParsedServiceElements getServiceElements(InputStreamProvider archive) throws ModellerException {
      ICloseableDirectory dir = null;
      try {
          dir = FileSystem.getFSRoot(archive.open());
          BundleManifest bm = BundleManifest.fromBundle(dir);
          return getServiceElements(bm, dir);
      } catch (IOException e) {
          throw new ModellerException(e);
      } finally {
          IOUtils.close(dir);
      }
  }
 
  private ParsedServiceElements getServiceElements (BundleManifest bundleMf, IDirectory archive) throws ModellerException {
     
      Set<ExportedService> services = new HashSet<ExportedService>();
      Set<ImportedService> references = new HashSet<ImportedService>();
   
      try {
          ParsedServiceElements pse = getBlueprintServiceElements(bundleMf,
                      findBlueprints(bundleMf, archive));
          services.addAll(pse.getServices());
          references.addAll(pse.getReferences());
          for (ServiceModeller sm : modellingPlugins) {
            pse = sm.modelServices(bundleMf, archive);
            services.addAll(pse.getServices());
            references.addAll(pse.getReferences());
          }
          return new ParsedServiceElementsImpl(services, references);
      } catch (Exception e) {
          throw new ModellerException(e);
      }
  }
 
  private ParsedServiceElements getBlueprintServiceElements (BundleManifest bundleMf, Iterable<InputStream> blueprints) throws ModellerException {
    _logger.debug(LOG_ENTRY,"getServiceElements", new Object[] {bundleMf, blueprints} );

    Set<ExportedService> services = new HashSet<ExportedService>();
    Set<ImportedService> references = new HashSet<ImportedService>();
    try {
      for (InputStream is : blueprints) {
        try {
          ParsedServiceElements pse = getParserProxy().parseAllServiceElements(is);
          services.addAll(pse.getServices());
          references.addAll(pse.getReferences());
        } finally {
          IOUtils.close(is);
        }
      }
    } catch (Exception e) {
      ModellerException m = new ModellerException(e);
      _logger.debug(LOG_EXIT, "getServiceElements", m);
      throw m;
    }
    ParsedServiceElements result = _modellingManager.getParsedServiceElements(services, references);
    _logger.debug(LOG_EXIT, "getServiceElements", result);
    return result;
  }

  public ModelledResource getModelledResource(IDirectory bundle) throws ModellerException {
      try {
          return getModelledResource(bundle.toURL().toURI().toString(), bundle);
      } catch (MalformedURLException mue) {
          throw new ModellerException(mue);
      } catch (URISyntaxException use) {
          throw new ModellerException(use);
      }
  }

  public ModelledResource getModelledResource(String uri, InputStreamProvider bundle) throws ModellerException {
      ICloseableDirectory dir = null;
      try {
          dir = FileSystem.getFSRoot(bundle.open());
          return getModelledResource(uri, dir);
      } catch (IOException e) {
          throw new ModellerException(e);
      } finally {
          IOUtils.close(dir);
      }
  }
 
  public ModelledResource getModelledResource(String uri, IDirectory bundle) throws ModellerException{
    _logger.debug(LOG_ENTRY, "getModelledResource", new Object[]{uri, bundle});

    if (bundle != null) {
        BundleManifest bm = BundleManifest.fromBundle(bundle);
        ParsedServiceElements pse = getServiceElements(bm, bundle);
        return model(uri, bm, pse);
    } else {
      // The bundle does not exist
      ModellerException me = new ModellerException(MessageUtil.getMessage("INVALID_BUNDLE_LOCATION", bundle));
      _logger.debug(LOG_EXIT, "getModelledResource", me);
      throw me;
    }

  }
 
  private ModelledResource model(String uri, BundleManifest bm, ParsedServiceElements pse) throws ModellerException {
      Attributes attributes = bm.getRawAttributes();
      ModelledResource mbi = null;
      try {
        mbi = _modellingManager.getModelledResource(uri, attributes, pse.getReferences(), pse.getServices());
      } catch (InvalidAttributeException iae) {
        ModellerException me = new ModellerException(iae);
        _logger.debug(LOG_EXIT, "getModelledResource", me);
        throw me;
      }
      _logger.debug(LOG_EXIT, "getModelledResource", mbi);
      return mbi;     
  }

  /**
   * Helper method to pass a single bundle into findBlueprints
   * @param bundleMf The bundle manifest
   * @param oneBundle a single bundle
   * @return Files for all the blueprint files within the bundle
   * @throws URISyntaxException
   * @throws IOException
   */
  private Iterable<InputStream> findBlueprints(BundleManifest bundleMf, IDirectory bundle) throws IOException
  {
    _logger.debug(LOG_ENTRY, "findBlueprints", bundle);

    Collection<IFile> blueprints = new ArrayList<IFile>();
    BundleBlueprintParser bpParser = new BundleBlueprintParser(bundleMf);
    List<IFile> files = bundle.listAllFiles();
    Iterator<IFile> it = files.iterator();
    while (it.hasNext()) {
        IFile file = it.next();        
        String directoryFullPath = file.getName();
        String directoryName = "";
        String fileName = "";
        if (directoryFullPath.lastIndexOf("/") != -1) {
          // This bundle may be nested within another archive. In that case, we need to trim
          // /bundleFileName.jar from the front of the directory.
          int bundleNameLength = bundle.getName().length();
            directoryName = directoryFullPath.substring(bundleNameLength, directoryFullPath.lastIndexOf("/"));
            if (directoryName.startsWith("/") && directoryName.length() > 1) {
              directoryName = directoryName.substring(1);
            }
            fileName = directoryFullPath.substring(directoryFullPath.lastIndexOf("/") + 1);
        } else {
            if (file.isFile()) {
                directoryName="";
                fileName = directoryFullPath;
            }

        }
        if (bpParser.isBPFile(directoryName, fileName)) {
            blueprints.add(file);
        }
    }
   
    Collection<InputStream> result = new ArrayList<InputStream>();
    try {
        for (IFile bp : blueprints) result.add(bp.open());
    } catch (IOException e) {
        // if something went wrong, make sure we still clean up
        for (InputStream is : result) IOUtils.close(is);
       
        throw e;
    }
   
    _logger.debug(LOG_EXIT, "findBlueprints", result);
    return result;
  }

  private class ZipBlueprintIterator implements Iterator<InputStream> {
      private final ZipInputStream zip;
      private final BundleBlueprintParser bpParser;
      private boolean valid;
     
      public ZipBlueprintIterator(ZipInputStream zip, BundleBlueprintParser bpParser) {
          this.zip = zip;
          this.bpParser = bpParser;
      }

      public boolean hasNext() {
          valid = false;
          ZipEntry entry;
         
          try {
              while (!valid && (entry = zip.getNextEntry()) != null) {
                  if (!entry.isDirectory()) {
                      String name = entry.getName();
                      String directory = "";
                      int index = name.lastIndexOf('/');
                      if (index != -1) {
                          directory = name.substring(0, index);
                          name = name.substring(index+1);
                      }
                     
                      if (bpParser.isBPFile(directory, name)) {
                          valid = true;
                      }
                     
                  }
              }
          } catch (IOException e) {
              _logger.error("Could not open next zip entry", e);
          }
         
          return valid;
      }

      public InputStream next() {
          if (!valid) throw new IllegalStateException();
         
          return new InputStream() {
            public int read() throws IOException {
                return zip.read();
            }
             
            @Override
            public void close() {
                // intercept close so that the zipinputstream stays open
            }
          };
      }

      public void remove() {
          throw new UnsupportedOperationException();
      }
     
  }
 
  /**
   * Internal use only. Different to the general Iterable interface this can return an Iterator only once.
   */
  private Iterable<InputStream> findBlueprints(BundleManifest bundleMf, InputStream stream) {
      final BundleBlueprintParser bpParser = new BundleBlueprintParser(bundleMf);
      final ZipInputStream zip = new ZipInputStream(stream);
     
      return new Iterable<InputStream>() {
        public Iterator<InputStream> iterator() {
            return new ZipBlueprintIterator(zip, bpParser);
        }
    };
  }

}
TOP

Related Classes of org.apache.aries.application.modelling.impl.ModelledResourceManagerImpl$ZipBlueprintIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.