You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by rw...@apache.org on 2011/04/06 15:14:27 UTC

svn commit: r1089443 [1/2] - in /incubator/stanbol/trunk: commons/ commons/installer/ commons/installer/bundleprovider/ commons/installer/bundleprovider/src/ commons/installer/bundleprovider/src/main/ commons/installer/bundleprovider/src/main/java/ com...

Author: rwesten
Date: Wed Apr  6 13:14:26 2011
New Revision: 1089443

URL: http://svn.apache.org/viewvc?rev=1089443&view=rev
Log:
This revision adds support to install ReferencedSites for the Entityhub by adding a Bundle to the OSGI Web Console.

STANBOL-141: Adds Support for installing SolrIndexes provided as archives with the name <indexName>.solrindex.[<compressionFormat>] where
  - indexname is the name of the core added to the EmbeddedSolrServer managed by the SolrYard
  - compressionFormat is the format used for the archive. ZIP is the default.
Open:
 - support for uninstalling Solr Indexes
 
 The implementation is part of the SolrYard Bundle.
 
 
 STANBOL-140: Adds Support for installing resources contained in Bundles that define the "Install-Path" header in there manifest.
 Open:
  - remove configuration if a Bundle is uninstalled
  - update the configuration if an bundle is updated
  - no support for Jars.
  
 The implementation can be found in"/commons/installer/bundleprovider" 
  
  
other Changes

SolrYard:
 - added the functionality to add SolrIndexes to the SolrDirectoryManager
 - moved the ConfigUtils to the impl package because it is no longer intended to be used from outside of the SolrYard bundle
 - Text Queries for multiple words now create "Word1 AND Word2 AND Wordn" type SolrQueries. Previously "Word1+Word2+Wordn" was used. This had not worked with the the Tokenizers used for  such fields. Queries in STR field (that do not use Tokenizers) still use the old pattern.
 - adapted unit test
 
 Stanboltools/Offline
  - the pom.xml now uses the parent
  
 Enhancer/Full launcher
  - added the BundleInstaller: Now it is possible to install ReferencedSites for the Entityhub by adding a Bundle to the OSGI Web Console
 

Added:
    incubator/stanbol/trunk/commons/installer/
    incubator/stanbol/trunk/commons/installer/bundleprovider/
    incubator/stanbol/trunk/commons/installer/bundleprovider/pom.xml   (with props)
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/Activator.java   (with props)
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/BundleInstaller.java   (with props)
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/resources/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/test/
    incubator/stanbol/trunk/commons/installer/bundleprovider/src/test/java/
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/ConfigUtils.java   (contents, props changed)
      - copied, changed from r1085256, incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/utils/ConfigUtils.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/install/
Removed:
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/embedded/
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/utils/ConfigUtils.java
Modified:
    incubator/stanbol/trunk/commons/pom.xml
    incubator/stanbol/trunk/commons/stanboltools/offline/pom.xml
    incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/utils/JerseyUtils.java
    incubator/stanbol/trunk/entityhub/yard/solr/pom.xml
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/SolrDirectoryManager.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/DefaultSolrDirectoryManager.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/EmbeddedSolrPorovider.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrQueryFactory.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrYard.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/queryencoders/AssignmentEncoder.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/queryencoders/RegexEncoder.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/queryencoders/WildcardEncoder.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/query/EncodedConstraintParts.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/utils/SolrUtil.java
    incubator/stanbol/trunk/entityhub/yard/solr/src/test/java/org/apache/stanbol/entityhub/yard/solr/SolrDirectoryManagerTest.java
    incubator/stanbol/trunk/parent/pom.xml

Added: incubator/stanbol/trunk/commons/installer/bundleprovider/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/commons/installer/bundleprovider/pom.xml?rev=1089443&view=auto
==============================================================================
--- incubator/stanbol/trunk/commons/installer/bundleprovider/pom.xml (added)
+++ incubator/stanbol/trunk/commons/installer/bundleprovider/pom.xml Wed Apr  6 13:14:26 2011
@@ -0,0 +1,119 @@
+<?xml version="1.0"?>
+<!--
+   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.
+-->
+<project>
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.stanbol</groupId>
+    <artifactId>stanbol-parent</artifactId>
+    <version>0.9-SNAPSHOT</version>
+    <relativePath>../../../parent/pom.xml</relativePath>
+  </parent>
+
+  <groupId>org.apache.stanbol</groupId>
+  <artifactId>org.apache.stanbol.commons.installer.bundleprovider</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>BundleProvider</name>
+  <description>Provides support for installing Configurations contained
+  within Bundles by using the Sling Installer infrastructure </description>
+  <scm>
+    <connection>
+      scm:svn:http://svn.apache.org/repos/asf/incubator/stanbol/trunk/commons/installer/bundleprovider
+    </connection>
+    <developerConnection>
+      scm:svn:https://svn.apache.org/repos/asf/incubator/stanbol/trunk/commons/installer/bundleprovider
+    </developerConnection>
+    <url>http://incubator.apache.org/stanbol</url>
+  </scm>
+
+ <build>
+    <!-- make it an OSGi bundle -->
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Activator>
+              org.apache.stanbol.commons.installer.provider.bundle.impl.Activator</Bundle-Activator>
+            <Export-Package>
+              org.apache.stanbol.commons.installer.provider.bundle
+            </Export-Package>
+            <Private-Package>
+              org.apache.stanbol.commons.installer.provider.bundle.impl
+            </Private-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+<!--      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-scr-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin> -->
+    </plugins>
+  </build>
+
+  <dependencies>
+
+    <!-- Sling installer dependency -->
+<!--    <dependency>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>org.apache.sling.launchpad.installer</artifactId>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>org.apache.sling.launchpad.api</artifactId>
+    </dependency> -->
+    <dependency>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>org.apache.sling.installer.core</artifactId>
+    </dependency>
+<!--    <dependency>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>org.apache.felix.scr.annotations</artifactId>
+    </dependency> -->
+    <dependency>
+        <groupId>commons-io</groupId>
+        <artifactId>commons-io</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+	<dependency>
+	    <groupId>org.osgi</groupId>
+	    <artifactId>org.osgi.compendium</artifactId>
+	    <scope>provided</scope>
+	</dependency>
+    <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-api</artifactId>
+        <scope>provided</scope>
+    </dependency>
+  </dependencies>
+</project>

Propchange: incubator/stanbol/trunk/commons/installer/bundleprovider/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/Activator.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/Activator.java?rev=1089443&view=auto
==============================================================================
--- incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/Activator.java (added)
+++ incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/Activator.java Wed Apr  6 13:14:26 2011
@@ -0,0 +1,99 @@
+/*
+ * 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.stanbol.commons.installer.provider.bundle.impl;
+
+import org.apache.sling.installer.api.OsgiInstaller;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Simple {@link BundleActivator} that also listens to the {@link OsgiInstaller}
+ * service.
+ * If the Bundle is active and the {@link OsgiInstaller} is available the
+ * {@link BundleInstaller} is created. If the bundle is stopped or the
+ * {@link OsgiInstaller} goes away the {@link BundleInstaller} is closed. 
+ * @author Rupert Westenthaler
+ *
+ */
+public class Activator implements BundleActivator, ServiceTrackerCustomizer {
+    
+
+    private ServiceTracker installerTracker;
+    
+    private static final Logger log = LoggerFactory.getLogger(Activator.class);
+    private BundleContext bundleContext;
+    
+    private BundleInstaller bundleInstaller;
+    
+    
+    @Override
+    public void start(BundleContext context) throws Exception {
+        bundleContext = context;
+        //Note that this class implements ServiceTrackerCustomizer to init/stop
+        // the BundleInstaller
+        installerTracker = new ServiceTracker(context,OsgiInstaller.class.getName(),this);
+        installerTracker.open();
+    }
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        closeBundleInstaller();
+        installerTracker.close();
+        bundleContext = null;
+    }
+    
+    @Override
+    public Object addingService(ServiceReference reference) {
+        Object service = bundleContext.getService(reference);
+        if(service instanceof OsgiInstaller){
+            initBundleInstaller((OsgiInstaller)service);
+            return service;
+        } else {
+            return null;
+        }
+    }
+    /* not needed for the OsgiInstaller */
+    @Override
+    public void modifiedService(ServiceReference arg0, Object arg1) { /* unused */ }
+    @Override
+    public void removedService(ServiceReference sr, Object s) {
+        //stop the BundleInstaller
+        closeBundleInstaller();
+        //unget the service
+        bundleContext.ungetService(sr);
+    }
+    
+    private synchronized void initBundleInstaller(OsgiInstaller installer){
+        if(bundleInstaller == null){
+            log.info("start BundleInstaller");
+            bundleInstaller = new BundleInstaller(installer, bundleContext);
+        }
+    }
+    
+    private synchronized void closeBundleInstaller(){
+        if(bundleInstaller != null){
+            log.info("close BundleInstaller");
+            bundleInstaller.close();
+            bundleInstaller = null;
+        }
+    }
+
+}

Propchange: incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/Activator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/BundleInstaller.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/BundleInstaller.java?rev=1089443&view=auto
==============================================================================
--- incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/BundleInstaller.java (added)
+++ incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/BundleInstaller.java Wed Apr  6 13:14:26 2011
@@ -0,0 +1,238 @@
+/*
+ * 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.stanbol.commons.installer.provider.bundle.impl;
+
+import static org.apache.stanbol.commons.installer.provider.bundle.BundleInstallerConstants.BUNDLE_INSTALLER_HEADER;
+import static org.apache.stanbol.commons.installer.provider.bundle.BundleInstallerConstants.PROVIDER_SCHEME;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.sling.installer.api.InstallableResource;
+import org.apache.sling.installer.api.OsgiInstaller;
+import org.apache.sling.installer.api.tasks.ResourceTransformer;
+import org.apache.stanbol.commons.installer.provider.bundle.BundleInstallerConstants;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Installs resources within bundles by using the Apache Sling Installer
+ * framework.<p>
+ * NOTE that currently installed resources are not removed if the bundle is
+ * deactivated because it is not clear if this is a good thing to do. maybe one
+ * should use {@link Bundle#UNINSTALLED} for that. However this needs some
+ * additional testing.
+ * <p>
+ * The OSGi extender pattern (as described at [1]) is used. The value of the 
+ * {@link BundleInstallerConstants#BUNDLE_INSTALLER_HEADER} 
+ * ({@value BundleInstallerConstants#BUNDLE_INSTALLER_HEADER}) is used as relative path within 
+ * the bundle to search for installable  resources. Also files in sub folders 
+ * are considered as installable resources.<p>
+ * The files are installed in the order as returned by
+ * {@link Bundle#findEntries(String, String, boolean)}. Directories are 
+ * ignored.<p>
+ * All resources installed by this provider do use 
+ * {@link BundleInstallerConstants#PROVIDER_SCHEME} ({@value BundleInstallerConstants#PROVIDER_SCHEME}) as
+ * scheme and the path additional to the value of 
+ * {@link BundleInstallerConstants#BUNDLE_INSTALLER_HEADER}.<p>
+ * To give an example:<p>
+ * If the Bundle header notes<br>
+ * <pre><code>
+ *     {@value BundleInstallerConstants#BUNDLE_INSTALLER_HEADER}=resources
+ * </pre></code><br>
+ * and the bundle contains the resource <br>
+ * <pre><code>
+ *     resources/bundles/10/myBundle.jar
+ *     resources/config/myComponent.cfg
+ *     resoruces/data/myIndex.solrondex.zip
+ * </pre></code><br>
+ * than the following resources will be installed
+ * <pre><code>
+ *     {@value BundleInstallerConstants#PROVIDER_SCHEME}:bundles/10/myBundle.jar
+ *     {@value BundleInstallerConstants#PROVIDER_SCHEME}:config/myComponent.cfg
+ *     {@value BundleInstallerConstants#PROVIDER_SCHEME}:data/myIndex.solrondex.zip
+ * </pre></code><br>
+ * That means that {@link ResourceTransformer}s can both use the original name
+ * of the resource and the path relative to the install folder.
+ * <p>
+ * [1]  <a href="http://www.aqute.biz/Snippets/Extender"> The OSGi extender  pattern </a>
+ * <p>
+ * @author Rupert Westenthaler
+ *
+ */
+public class BundleInstaller implements BundleListener {
+
+    private static final Logger log = LoggerFactory.getLogger(BundleInstaller.class);
+    /** The scheme we use to register our resources. */
+
+    private final OsgiInstaller installer;
+    private final BundleContext context;
+    
+    /**
+     * contains all active bundles as key and the path to the config directory
+     * as value. A <code>null</code> value indicates that this bundle needs not
+     * to be processed. 
+     */
+    private final Map<Bundle,String> activated = new HashMap<Bundle,String>();
+
+    public BundleInstaller(OsgiInstaller installer,BundleContext context){
+        if(installer == null){
+            throw new IllegalArgumentException("The OsgiInstaller service MUST NOT be NULL");
+        }
+        if(context == null){
+            throw new IllegalArgumentException("The BundleContext MUST NOT be NULL");
+        }
+        this.installer = installer;
+        this.context = context;
+        this.context.addBundleListener(this);
+        //register the already active bundles
+        registerActive(this.context);
+    }
+    /**
+     * Uses the parsed bundle context to register the already active (and currently
+     * starting) bundles.
+     */
+    private void registerActive(BundleContext context) {
+        for (Bundle bundle : context.getBundles()){
+            if ((bundle.getState() & (Bundle.STARTING | Bundle.ACTIVE)) != 0) {
+                register(bundle);
+            }
+        }
+    }
+    @Override
+    public void bundleChanged(BundleEvent event) {
+        switch (event.getType()) {
+            case BundleEvent.STARTED:
+              register(event.getBundle());
+              break;
+              
+            case BundleEvent.STOPPED:
+              unregister(event.getBundle());
+              break;
+            
+            case BundleEvent.UPDATED:
+              unregister(event.getBundle());
+              register(event.getBundle());
+        }
+    }
+
+    /**
+     * Registers the bundle to the {@link #activated} map.
+     * @param bundle the bundle to register
+     */
+    @SuppressWarnings("unchecked")
+    private void register(Bundle bundle){
+        synchronized (activated) {
+            if(activated.containsKey(bundle)){
+                return;
+            } 
+        }
+        log.info("Register Bundle "+bundle.getSymbolicName()+" with BundleInstaller");
+        Dictionary<String,Object> headers = (Dictionary<String,Object>)bundle.getHeaders();
+//        log.info("With Headers:");
+//        for(Enumeration<String> keys = headers.keys();keys.hasMoreElements();){
+//            String key = keys.nextElement();
+//            log.info(" > "+key+"="+headers.get(key));
+//        }
+        String path = (String)headers.get(BUNDLE_INSTALLER_HEADER);
+        activated.put(bundle, path);
+        if(path != null){
+            log.info(" ... process configuration within path "+path);
+            ArrayList<InstallableResource> updated = new ArrayList<InstallableResource>();
+            for(Enumeration<URL> resources = (Enumeration<URL>)bundle.findEntries(path, null, true);resources.hasMoreElements();){
+                InstallableResource resource = createInstallableResource(bundle, path,resources.nextElement());
+                if(resource != null){
+                    updated.add(resource);
+                }
+            }
+            installer.updateResources(PROVIDER_SCHEME, updated.toArray(new InstallableResource[updated.size()]), new String[]{});
+        } else {
+            log.info("  ... no Configuration to process");
+        }
+    }
+    /**
+     * Creates an {@link InstallableResource} for {@link URL}s of files within
+     * the parsed bundle. 
+     * @param bundle the bundle containing the parsed resource
+     * @param bundleResource a resource within the bundle that need to be installed
+     * @return the installable resource or <code>null</code> in case of an error
+     */
+    private InstallableResource createInstallableResource(Bundle bundle, String path, URL bundleResource) {
+        //define the id
+        String id = bundleResource.toString();
+        String relPath = id.substring(id.lastIndexOf(path)+path.length(),id.length());
+        String name = FilenameUtils.getName(relPath);
+        if(name == null || name.isEmpty()){
+            return null; //ignore directories!
+        }
+        
+        InstallableResource resource;
+        try {
+            /*
+             * Notes:
+             *  - use bundleinstaller:<relativepath> as id
+             *  - parse null as type to enable autodetection for configs as
+             *    implemented by InternalReseouce.create(..)
+             *  - we use the modification date of the bundle as digest
+             *  - the Dictionary will be ignored if an input stream is present
+             *    so it is best to parse null
+             *  - No idea how the priority is used by the Sling Installer. For
+             *    now parse null than the default priority is used.
+             */
+            resource = new InstallableResource(
+                BundleInstallerConstants.PROVIDER_SCHEME+':'+relPath,
+                bundleResource.openStream(), null, 
+                String.valueOf(bundle.getLastModified()), null, null);
+            log.info(" ... found installable resource "+id);
+        } catch (IOException e) {
+            log.error(String.format("Unable to process configuration File %s from Bundle %s",
+                id,bundle.getSymbolicName()),e);
+            return null;
+        }
+        return resource;
+    }
+    private void unregister(Bundle bundle) {
+        String path;
+        synchronized (activated) {
+            if (!activated.containsKey(bundle)){
+                return;
+            }
+            path = activated.remove(bundle);
+        }
+        if(path != null) {
+            //remove the files ...
+            //TODO: Maybe removing installed stuff when the bundle is stopped is
+            //      not so a good Idea! Maybe it is ?!
+        }
+    }
+    /**
+     * removes the bundle listener
+     */
+    public void close(){
+        context.removeBundleListener(this);
+    }
+}

Propchange: incubator/stanbol/trunk/commons/installer/bundleprovider/src/main/java/org/apache/stanbol/commons/installer/provider/bundle/impl/BundleInstaller.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/stanbol/trunk/commons/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/commons/pom.xml?rev=1089443&r1=1089442&r2=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/commons/pom.xml (original)
+++ incubator/stanbol/trunk/commons/pom.xml Wed Apr  6 13:14:26 2011
@@ -32,5 +32,9 @@
     <module>testing/http</module>
     <module>testing/stanbol</module>
     <module>stanboltools/offline</module>
-  </modules>
+    <module>installer/bundleprovider</module>
+    <!-- not in a stable state right now 
+    <module>installer/jarprovider</module>
+    -->
+    </modules>
 </project>

Modified: incubator/stanbol/trunk/commons/stanboltools/offline/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/commons/stanboltools/offline/pom.xml?rev=1089443&r1=1089442&r2=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/commons/stanboltools/offline/pom.xml (original)
+++ incubator/stanbol/trunk/commons/stanboltools/offline/pom.xml Wed Apr  6 13:14:26 2011
@@ -1,10 +1,15 @@
 <?xml version="1.0"?>
 <project>
   <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.stanbol</groupId>
+    <artifactId>stanbol-parent</artifactId>
+    <version>0.9-SNAPSHOT</version>
+    <relativePath>../../../parent/pom.xml</relativePath>
+  </parent>
 
   <groupId>org.apache.stanbol</groupId>
   <artifactId>org.apache.stanbol.commons.stanboltools.offline</artifactId>
-  <version>0.9-SNAPSHOT</version>
   <packaging>bundle</packaging>
 
   <name>Apache Stanbol Offline Utilities</name>
@@ -38,15 +43,6 @@
           </instructions>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>2.3.1</version>
-        <configuration>
-          <source>1.6</source>
-          <target>1.6</target>
-        </configuration>
-      </plugin>
     </plugins>
   </build>
 
@@ -54,12 +50,10 @@
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
-      <version>1.5.2</version>
     </dependency>
     <dependency>
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.core</artifactId>
-      <version>4.1.0</version>
     </dependency>
   </dependencies>
 </project>
\ No newline at end of file

Modified: incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/utils/JerseyUtils.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/utils/JerseyUtils.java?rev=1089443&r1=1089442&r2=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/utils/JerseyUtils.java (original)
+++ incubator/stanbol/trunk/entityhub/jersey/src/main/java/org/apache/stanbol/entityhub/jersey/utils/JerseyUtils.java Wed Apr  6 13:14:26 2011
@@ -105,7 +105,7 @@ public final class JerseyUtils {
             try {
                 fieldQuery = JSONToFieldQuery.fromJSON(queryFactory,query);
             } catch (JSONException e) {
-                log.warn("unable to parse FieldQuery from \"application/x-www-form-urlencoded\" encoded query string "+query);
+                log.warn("unable to parse FieldQuery from \"application/x-www-form-urlencoded\" encoded query string "+query,e);
                 fieldQuery = null;
                 exception = e;
             }
@@ -117,12 +117,12 @@ public final class JerseyUtils {
             } catch (IOException e) {
                 throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
             } catch (JSONException e) {
-                log.warn("unable to parse FieldQuery from \"multipart/form-data\" encoded query string "+query);
+                log.warn("unable to parse FieldQuery from \"multipart/form-data\" encoded query string "+query,e);
                 exception = e;
             }
         }//fieldquery already initialised or no query via multipart/form-data parsed
         if(fieldQuery == null){
-            throw new WebApplicationException(new IllegalArgumentException("Unable to parse FieldQuery for the parsed query\n"+query, exception),Response.Status.BAD_REQUEST);
+            throw new WebApplicationException(new IllegalArgumentException("Unable to parse FieldQuery form the parsed query String:"+query, exception),Response.Status.BAD_REQUEST);
         }
         return fieldQuery;
     }

Modified: incubator/stanbol/trunk/entityhub/yard/solr/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/pom.xml?rev=1089443&r1=1089442&r2=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/pom.xml (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/pom.xml Wed Apr  6 13:14:26 2011
@@ -77,7 +77,8 @@
             </Import-Package>
             <Private-Package>
               org.apache.stanbol.entityhub.yard.solr.impl;version=${pom.version},
-              org.apache.stanbol.entityhub.yard.solr.impl.queryencoders;version=${pom.version}
+              org.apache.stanbol.entityhub.yard.solr.impl.queryencoders;version=${pom.version},
+              org.apache.stanbol.entityhub.yard.solr.impl.install;version=${pom.version}
             </Private-Package>
             <Embed-Dependency>
               solr-solrj,commons-httpclient,
@@ -208,7 +209,16 @@
       <groupId>org.apache.felix</groupId>
       <artifactId>org.apache.felix.scr.annotations</artifactId>
     </dependency>
-
+    <!-- for the Solr Index Installer -->
+    <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.installer.core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-compress</artifactId>
+    </dependency>
+    <!-- Logging -->
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>

Modified: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/SolrDirectoryManager.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/SolrDirectoryManager.java?rev=1089443&r1=1089442&r2=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/SolrDirectoryManager.java (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/SolrDirectoryManager.java Wed Apr  6 13:14:26 2011
@@ -17,12 +17,14 @@
 package org.apache.stanbol.entityhub.yard.solr;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.Map;
 
+import org.apache.commons.compress.archivers.ArchiveInputStream;
 import org.apache.solr.client.solrj.SolrServer;
 import org.apache.solr.core.CoreContainer;
 import org.apache.stanbol.entityhub.yard.solr.SolrServerProvider.Type;
-import org.apache.stanbol.entityhub.yard.solr.utils.ConfigUtils;
+import org.apache.stanbol.entityhub.yard.solr.impl.ConfigUtils;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.component.ComponentContext;
 
@@ -101,20 +103,33 @@ public interface SolrDirectoryManager {
     Map<String,File> getManagedIndices() throws IllegalStateException;
 
     /**
-     * Getter for the directory of the parsed index. In case the requested index
-     * does not already exist (in the managed solr directory) it is initialised
-     * by using the default solr core configuration contained in this bundle.<p>
+     * Getter for the directory of the parsed index. Implementations need to 
+     * ensure that returned directories are valid Solr indices (or Solr Cores)<p>
      * Directories returned by this method are typically used as second parameter
      * of {@link SolrServerProvider#getSolrServer(Type, String, String...)} to
      * create an {@link SolrServer} instance.
      * @param solrPathOrUri the name of the requested solr index. If no index
      * with that name does exist a new one will be initialised base on the
      * default core configuration part of this bundle.
+     * @param If <code>true</code> the Solr directory is created  and initialised
+     * with the default configuration if it does not already exist.
+     * @return the directory (instanceDir) of the index or <code>null</code> if
+     * <code>false</code> was parsed as create and the index does not already
+     * exist. 
+     * @throws IllegalArgumentException if the parsed solrIndexName is 
+     * <code>null</code> or empty
+     */
+    File getSolrDirectory(final String solrIndexName,boolean create) throws IllegalArgumentException;
+    /**
+     * 
+     * @param solrIndexName the name of the index to create
+     * @param ais the stream providing the data for the new index
      * @return the directory (instanceDir) of the index.
+     * @throws IOException On any error while reading from the parsed input stream
      * @throws IllegalArgumentException if the parsed solrIndexName is 
      * <code>null</code> or empty
      */
-    File getSolrDirectory(final String solrIndexName) throws IllegalArgumentException;
+    File createSolrDirectory(final String solrIndexName, ArchiveInputStream ais) throws IllegalArgumentException, IOException;
 
     /**
      * Getter for the managed Solr Directory.

Copied: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/ConfigUtils.java (from r1085256, incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/utils/ConfigUtils.java)
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/ConfigUtils.java?p2=incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/ConfigUtils.java&p1=incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/utils/ConfigUtils.java&r1=1085256&r2=1089443&rev=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/utils/ConfigUtils.java (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/ConfigUtils.java Wed Apr  6 13:14:26 2011
@@ -14,22 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.stanbol.entityhub.yard.solr.utils;
+package org.apache.stanbol.entityhub.yard.solr.impl;
 
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Enumeration;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
 
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveInputStream;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipFile;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
-import org.apache.stanbol.entityhub.yard.solr.impl.EmbeddedSolrPorovider;
 import org.osgi.framework.Bundle;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -129,17 +132,17 @@ public final class ConfigUtils {
         if(sourceRoot.isFile()){
             ZipFile archive = new ZipFile(sourceRoot);
             log.info(String.format("Copy Default Config from jar-file %s to %s (override=%s)",
-                archive.getName(),rootDir.getAbsolutePath(),override));
+                sourceRoot.getName(),rootDir.getAbsolutePath(),override));
             try {
-                for(Enumeration<? extends ZipEntry> entries = archive.entries();entries.hasMoreElements();){
-                    ZipEntry entry = entries.nextElement();
+                for(Enumeration<ZipArchiveEntry> entries = (Enumeration<ZipArchiveEntry>)archive.getEntries();entries.hasMoreElements();){
+                    ZipArchiveEntry entry = entries.nextElement();
                     if(entry.getName().startsWith(CONFIG_DIR)){
                         copyResource(rootDir, archive, entry, CONFIG_DIR, override);
                     }
                 }
             } finally {
                 //regardless what happens we need to close the archive!
-                archive.close();
+                ZipFile.closeQuietly(archive);
             }
         } else { //load from file
             File source = new File(sourceRoot,CONFIG_DIR);
@@ -209,7 +212,7 @@ public final class ConfigUtils {
      * be deleted
      * @throws IOException in case of an error while reading or writing the resource
      */
-    private static void copyResource(File rootDir,ZipFile archive, ZipEntry entry,String context,boolean override) throws IOException {
+    private static void copyResource(File rootDir,ZipFile archive, ZipArchiveEntry entry,String context,boolean override) throws IOException {
         File file = prepairCopy(entry.getName(), rootDir, context);
         if(file != null){
             boolean overrideState = false;
@@ -218,8 +221,17 @@ public final class ConfigUtils {
                 overrideState = true;
             }
             if(!file.exists()) {
-                IOUtils.copy(archive.getInputStream(entry), FileUtils.openOutputStream(file));
-                log.debug(String.format(" > %s %s",overrideState?"override":"copy",file));
+                OutputStream os = null;
+                InputStream is = null;
+                try {
+                    os = FileUtils.openOutputStream(file);
+                    is = archive.getInputStream(entry);
+                    IOUtils.copy(is, os);
+                    log.debug(String.format(" > %s %s",overrideState?"override":"copy",file));
+                } finally {
+                    IOUtils.closeQuietly(is);
+                    IOUtils.closeQuietly(os);
+                }
             }
         } //else can not cppy logging already provided
         
@@ -305,6 +317,75 @@ public final class ConfigUtils {
         }
     }
     /**
+     * Copies a core from the parsed archive input stream to the target location
+     * @param ais The input stream of the archive (not closed by this method)
+     * @param coreDir the directory for the core
+     * @param coreName the name of the core (used as context when reading relative
+     * paths from the archive
+     * @param override if existing files should be overridden
+     * @throws IOException On any error while accessing the data of the archive
+     * @throws IllegalArgumentException if any of the parameter is <code>null</code>
+     * or if the coreDir exists but is not an directory or if the core name is
+     * empty
+     */
+    public static void copyCore(ArchiveInputStream ais, File coreDir,String coreName,boolean override) throws IOException{
+        if(ais == null){
+            throw new IllegalArgumentException("The parsed ArchiveInputStream MUST NOT be NULL!");
+        }
+        if(coreDir == null){
+            throw new IllegalArgumentException("The parsed core directory MUST NOT be NULL!");
+        }
+        if(coreDir.exists() && !coreDir.isDirectory()){
+            throw new IllegalStateException("The parsed core directory "+coreDir.getAbsolutePath()+" extists but is not a directory!");
+        }
+        if(coreName== null || coreName.isEmpty()){
+            throw new IllegalArgumentException("The parsed core name MUST NOT be NULL or empty!");
+        }
+        ArchiveEntry entry;
+        while((entry = ais.getNextEntry())!=null){
+            if(!entry.isDirectory()){
+                copyArchiveEntry(ais, entry, coreDir, coreName, override);
+                /*
+                 * NOTE: Here we use the coreName as context (last argument to 
+                 * prepairCopy(..)). This ensures that it matter if the archive 
+                 * contains the data directly in the root or within an folder 
+                 * with the name of the core.
+                 */
+            } //else - directories are created automatically and empty directories are not needed
+        }
+    }
+    /**
+     * Copy an Entry of an Archive to the target (File) within the Core Directory
+     * @param ais the ArchiveInputStream
+     * @param entry The Entry to copy
+     * @param coreDir the root directory
+     * @param context the context used to calculate the relative path of the
+     * resource within the target directory
+     * @param override if an existing resource within the target directory should
+     * be deleted
+     * @throws IOException in case of an error while reading or writing the resource
+     */
+    private static void copyArchiveEntry(ArchiveInputStream ais, ArchiveEntry entry, File coreDir, String context, boolean override) throws IOException {
+        File file = prepairCopy(entry.getName(), coreDir, context);
+        if(file != null){
+            boolean overrideState = false;
+            if(file.exists() && override){
+                FileUtils.deleteQuietly(file);
+                overrideState = true;
+            }
+            if(!file.exists()) {
+                OutputStream os = null;
+                try {
+                    os= FileUtils.openOutputStream(file);
+                    IOUtils.copy(ais, os);
+                    log.debug(String.format(" > %s %s",overrideState?"override":"copy",file));
+                }finally {
+                    IOUtils.closeQuietly(os);
+                }
+            }
+        } //else can not cppy logging already provided
+    }
+    /**
      * Copy the configuration of an core.
      * @param clazzInArchive This class is used to identify the archive containing
      * the default configuration. Parsing <code>null</code> causes this class to
@@ -338,17 +419,17 @@ public final class ConfigUtils {
         if(sourceRoot.isFile()){
             ZipFile archive = new ZipFile(sourceRoot);
             log.info(String.format("Copy core %s config from jar-file %s to %s (override=%s)",
-                (coreName == null?"":coreName),archive.getName(),coreDir.getAbsolutePath(),override));
+                (coreName == null?"":coreName),sourceRoot.getName(),coreDir.getAbsolutePath(),override));
             try {
-                for(Enumeration<? extends ZipEntry> entries = archive.entries();entries.hasMoreElements();){
-                    ZipEntry entry = entries.nextElement();
+                for(Enumeration<ZipArchiveEntry> entries = (Enumeration<ZipArchiveEntry>)archive.getEntries();entries.hasMoreElements();){
+                    ZipArchiveEntry entry = entries.nextElement();
                     if(entry.getName().startsWith(context)){
                         copyResource(coreDir, archive, entry, context, override);
                     }
                 }
             } finally {
                 //regardless what happens we need to close the archive!
-                archive.close();
+                ZipFile.closeQuietly(archive);
             }
         } else { //load from file
             File source = new File(sourceRoot,context);

Propchange: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/ConfigUtils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/DefaultSolrDirectoryManager.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/DefaultSolrDirectoryManager.java?rev=1089443&r1=1089442&r2=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/DefaultSolrDirectoryManager.java (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/DefaultSolrDirectoryManager.java Wed Apr  6 13:14:26 2011
@@ -19,8 +19,11 @@ package org.apache.stanbol.entityhub.yar
 import java.io.File;
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
+import org.apache.commons.compress.archivers.ArchiveInputStream;
 import org.apache.commons.io.filefilter.DirectoryFileFilter;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -29,8 +32,10 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.stanbol.entityhub.yard.solr.SolrDirectoryManager;
-import org.apache.stanbol.entityhub.yard.solr.utils.ConfigUtils;
+import org.osgi.framework.BundleContext;
 import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Implementation of the {@link SolrDirectoryManager} interface that supports
@@ -46,9 +51,12 @@ import org.osgi.service.component.Compon
            @Property(name=SolrDirectoryManager.MANAGED_SOLR_DIR_PROPERTY,value=SolrDirectoryManager.DEFAULT_SOLR_DATA_DIR)
     })
 public class DefaultSolrDirectoryManager implements SolrDirectoryManager {
-    //private final Logger log = LoggerFactory.getLogger(DefaultSolrDirectoryManager.class);
+    private final Logger log = LoggerFactory.getLogger(DefaultSolrDirectoryManager.class);
     /**
-     * The directory used by the internally managed embedded solr server.
+     * The directory used by the internally managed embedded solr server. 
+     * Use {@link #lookupManagedSolrDir()} instead of using this member, because
+     * this member is not initialised within the constructor or the 
+     * {@link #activate(ComponentContext)} method.
      */
     private File solrDataDir;
     
@@ -66,6 +74,18 @@ public class DefaultSolrDirectoryManager
      * change!
      */
     private boolean withinOSGI = false;
+    /**
+     * Initialising Solr Indexes with a lot of data may take some time. Especially
+     * if the data need to be copied to the managed directory. Therefore it is
+     * important to wait for the initialisation to be complete before opening
+     * an Solr Index on it.<p>
+     * To this set all cores that are currently initialised are added. As soon
+     * as an initialisation completed this set is notified.
+     */
+    private Set<String> initCores = new HashSet<String>();
+    
+    public DefaultSolrDirectoryManager() {
+    }
     
     /* (non-Javadoc)
      * @see org.apache.stanbol.entityhub.yard.solr.impl.ManagedSolrDirectory#isSolrDir(java.lang.String)
@@ -78,13 +98,13 @@ public class DefaultSolrDirectoryManager
             throw new IllegalArgumentException("The parsed name of the Solr index MUST NOT be empty");
         }
         //also here we need to initialise the SolrDirectory if not already done
-        return new File(initSolrDirectory(null),solrIndexName).exists();
+        return new File(lookupManagedSolrDir(componentContext),solrIndexName).exists();
     }
     /* (non-Javadoc)
      * @see org.apache.stanbol.entityhub.yard.solr.impl.ManagedSolrDirectory#getManagedIndices()
      */
     public final Map<String,File> getManagedIndices() throws IllegalStateException {
-        File solrDir = initSolrDirectory(null);
+        File solrDir = lookupManagedSolrDir(componentContext);
         String[] indexNames = solrDir.list(DirectoryFileFilter.INSTANCE);
         Map<String,File> indexes = new HashMap<String,File>();
         for(String indexName:indexNames){
@@ -96,51 +116,55 @@ public class DefaultSolrDirectoryManager
     /* (non-Javadoc)
      * @see org.apache.stanbol.entityhub.yard.solr.impl.ManagedSolrDirectory#getSolrDirectory(java.lang.String)
      */
-    public final File getSolrDirectory(final String solrIndexName) throws IllegalArgumentException {
-        if(solrIndexName == null){
-            throw new IllegalArgumentException("The parsed name of the Solr index MUST NOT be NULL");
-        }
-        if(solrIndexName.isEmpty()){
-            throw new IllegalArgumentException("The parsed name of the Solr index MUST NOT be empty");
-        }
-        return initSolrDirectory(solrIndexName);
+    public final File getSolrDirectory(final String solrIndexName,boolean create) throws IllegalArgumentException {
+        return initSolrDirectory(solrIndexName,null,create,componentContext);
+    }
+    public final File createSolrDirectory(final String solrIndexName, ArchiveInputStream ais){
+        return initSolrDirectory(solrIndexName,ais,true,componentContext);
     }
     /**
      * Internally used to get/init the Solr directory of a SolrCore or the root
      * Solr directory (if <code>null</code> is parsed)
      * @param solrIndexName the name of the Core or <code>null</code> to get/init
      * the root solr directory
+     * @param ais The Input stream of the Archive to load the index from or
+     * <code>null</code> to load the default core configuration.
+     * @param create If <code>true</code> a new core is initialised if not already
+     * present. Make sure this is set to <code>true</code> if parsing an InputStream.
+     * Otherwise the index will not be created from the parsed stream!
+     * @param context A reference to the component context or <code>null</code> if
+     * running outside an OSGI container. This is needed to avoid that 
+     * {@link #deactivate(ComponentContext)} sets the context to <code>null</code> 
+     * during this method does its initialisation work.
      * @return the Solr directory or <code>null</code> in case this component is
      * deactivated
      * @throws IllegalStateException in case this method is called when this
      * component is running within an OSGI environment and it is deactivated or
      * the initialisation for the parsed index failed.
+     * @throws IllegalArgumentException if the parsed solrIndexName is <code>null</code> or
+     * empty.
      */
-    private final File initSolrDirectory(final String solrIndexName) throws IllegalStateException {
-        File managedCoreContainerDirectory = lookupManagedSolrDir();
-        ComponentContext context = componentContext;
-        if(!managedCoreContainerDirectory.exists()){
-            try {
-                if(context != null){ //load via bundle
-                    managedCoreContainerDirectory = ConfigUtils.copyDefaultConfig(
-                        context.getBundleContext().getBundle(),managedCoreContainerDirectory, false);
-                } else { //load from jar
-                    managedCoreContainerDirectory = ConfigUtils.copyDefaultConfig(
-                        (Class<?>)null, managedCoreContainerDirectory, false);
-                }
-            } catch (IOException e) {
-                throw new IllegalStateException(
-                    String.format("Unable to copy default configuration for the manages Solr Directory to the configured path %s!"
-                        , managedCoreContainerDirectory.getAbsoluteFile()),e);
-            }
+    private final File initSolrDirectory(final String solrIndexName,ArchiveInputStream ais,boolean create,ComponentContext context) throws IllegalStateException {
+        if(solrIndexName == null){
+            throw new IllegalArgumentException("The parsed name of the Solr index MUST NOT be NULL");
+        }
+        if(solrIndexName.isEmpty()){
+            throw new IllegalArgumentException("The parsed name of the Solr index MUST NOT be empty");
         }
+        File managedCoreContainerDirectory = lookupManagedSolrDir(context);
         if(solrIndexName == null){
             return managedCoreContainerDirectory;
         }
         File coreDir = new File(managedCoreContainerDirectory,solrIndexName);
-        if(!coreDir.exists()){
+        if(create && !coreDir.exists()){
+            synchronized (initCores) {
+                log.info(" > start initializing SolrIndex "+solrIndexName);
+                initCores.add(solrIndexName);
+            }
             try {
-                if(context != null){ //load via bundle
+                if(ais != null){
+                    ConfigUtils.copyCore(ais, coreDir, solrIndexName, false);
+                } else if(context != null){ //load via bundle
                     ConfigUtils.copyCore(context.getBundleContext().getBundle(),
                         coreDir, null, false);
                 } else { //load from jar
@@ -150,6 +174,26 @@ public class DefaultSolrDirectoryManager
                 throw new IllegalStateException(
                     String.format("Unable to copy default configuration for Solr Index %s to the configured path %s"
                         ,solrIndexName==null?"":solrIndexName,managedCoreContainerDirectory.getAbsoluteFile()),e);
+            } finally {
+                synchronized (initCores) {
+                    initCores.remove(solrIndexName);
+                    log.info("   ... finished inizializaiton of SolrIndex "+solrIndexName);
+                    //notify that the initialisation completed or failed
+                    initCores.notifyAll(); 
+                }
+            }
+        } else { //the dir exists
+            //check if still initialising ... and wait until the initialisation
+            //is complete
+            synchronized (initCores) {
+                while(initCores.contains(solrIndexName)){
+                    log.info(" > wait for initialisation of SolrIndex "+solrIndexName);
+                    try {
+                        initCores.wait();
+                    } catch (InterruptedException e) {
+                        // a core is initialised ... back to work
+                    }
+                }
             }
         }
         return coreDir;
@@ -159,20 +203,20 @@ public class DefaultSolrDirectoryManager
      * @see org.apache.stanbol.entityhub.yard.solr.impl.ManagedSolrDirectory#getManagedSolrDir()
      */
     public File getManagedDirectory() {
-        // call initSolrDirectory(null) to initialise the internally managed
-        // Solr directory in case it is not already initialised.
-        return initSolrDirectory(null);
+        return lookupManagedSolrDir(componentContext);
     }
     /**
-     * Lookup the location of the managed Solr directory
+     * Lookup the location of the managed Solr directory. Also initialised the
+     * default configuration if the directory does not yet exist.
+     * @param context A reference to the component context or <code>null</code> if
+     * running outside an OSGI container. This is needed to avoid that 
+     * {@link #deactivate(ComponentContext)} sets the context to <code>null</code> 
+     * during this method does its initialisation work.
      * @return the directory based on the current configuration
      * @throws IllegalStateException in case this method is called when this
      * component is running within an OSGI environment and it is deactivated.
      */
-    private File lookupManagedSolrDir() throws IllegalStateException {
-        //local copy to avoid NullPointerExceptions when deactivate is called
-        //during this method
-        ComponentContext context = componentContext;
+    private File lookupManagedSolrDir(ComponentContext context) throws IllegalStateException {
         if(solrDataDir == null){
             String configuredDataDir;
             if(context == null){ //load via system properties
@@ -186,7 +230,8 @@ public class DefaultSolrDirectoryManager
                 }
             }
             //property substitution
-            configuredDataDir = substituteProperty(configuredDataDir);
+            configuredDataDir = substituteProperty(configuredDataDir,
+                context != null?context.getBundleContext():null);
             //determine the directory holding the SolrIndex
             /*
              * NOTE:
@@ -200,6 +245,21 @@ public class DefaultSolrDirectoryManager
             } else { //set the the absolute path
                 solrDataDir = new File(configuredDataDir);
             }
+            if(!solrDataDir.exists()){
+                try {
+                    if(context != null){ //load via bundle
+                        solrDataDir = ConfigUtils.copyDefaultConfig(
+                            context.getBundleContext().getBundle(),solrDataDir, false);
+                    } else { //load from jar
+                        solrDataDir = ConfigUtils.copyDefaultConfig(
+                            (Class<?>)null, solrDataDir, false);
+                    }
+                } catch (IOException e) {
+                    throw new IllegalStateException(
+                        String.format("Unable to copy default configuration for the manages Solr Directory to the configured path %s!"
+                            , solrDataDir.getAbsoluteFile()),e);
+                }
+            }
         }
         return solrDataDir;
     }
@@ -208,11 +268,17 @@ public class DefaultSolrDirectoryManager
      * Substitutes ${property.name} with the values retrieved via
      * {@link System#getProperty(String, String)}. An empty string is used as
      * default<p>
+     * Nested substitutions are NOTE supported. However multiple substitutions
+     * are supported. <p>
      * If someone knows a default implementation feel free to replace!
      * @param value the value to substitute
+     * @param bundleContext If not <code>null</code> the 
+     * {@link BundleContext#getProperty(String)} is used instead of the 
+     * {@link System#getProperty(String)}. By that it is possible to use
+     * OSGI only properties for substitution.
      * @return the substituted value
      */
-    private static String substituteProperty(String value) {
+    private static String substituteProperty(String value,BundleContext bundleContext) {
         int prevAt = 0;
         int foundAt = 0;
         StringBuilder substitution = new StringBuilder();
@@ -220,19 +286,22 @@ public class DefaultSolrDirectoryManager
             substitution.append(value.substring(prevAt, foundAt));
             String propertyName = value.substring(
                 foundAt+2,value.indexOf('}',foundAt));
-            substitution.append(System.getProperty(propertyName, ""));
-            prevAt = foundAt+propertyName.length()+3;
+            String propertyValue = bundleContext == null? //if no bundleContext is available
+                    System.getProperty(propertyName): //use the System properties
+                        bundleContext.getProperty(propertyName);
+            substitution.append(propertyValue==null?"":propertyValue);
+            prevAt = foundAt+propertyName.length()+3; //+3 -> "${}".length
         }
         substitution.append(value.substring(prevAt, value.length()));
         return substitution.toString();
     }
     @Activate
     protected void activate(ComponentContext context) {
-        this.componentContext = context;
-        this.withinOSGI = true;
+        componentContext = context;
+        withinOSGI = true;
     }
     @Deactivate
     protected void deactivate(ComponentContext context) {
-        this.componentContext = null;
+        componentContext = null;
     }
 }

Modified: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/EmbeddedSolrPorovider.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/EmbeddedSolrPorovider.java?rev=1089443&r1=1089442&r2=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/EmbeddedSolrPorovider.java (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/EmbeddedSolrPorovider.java Wed Apr  6 13:14:26 2011
@@ -37,7 +37,6 @@ import org.apache.solr.core.CoreDescript
 import org.apache.solr.core.SolrCore;
 import org.apache.stanbol.entityhub.yard.solr.SolrServerProvider;
 import org.apache.stanbol.entityhub.yard.solr.SolrServerProvider.Type;
-import org.apache.stanbol.entityhub.yard.solr.utils.ConfigUtils;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

Modified: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrQueryFactory.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrQueryFactory.java?rev=1089443&r1=1089442&r2=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrQueryFactory.java (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrQueryFactory.java Wed Apr  6 13:14:26 2011
@@ -256,17 +256,18 @@ public class SolrQueryFactory {
      */
     private void initIndexConstraint(IndexConstraint indexConstraint, TextConstraint textConstraint) {
         Text text = valueFactory.createText(textConstraint.getText());
+        IndexValue textValue = indexValueFactory.createIndexValue(text);
         indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.DATATYPE, text);
         indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.LANG, textConstraint.getLanguages());
         switch (textConstraint.getPatternType()) {
         case none:
-            indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.EQ, text);
+            indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.EQ, textValue);
             break;
         case wildcard:
-            indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.WILDCARD, textConstraint.getText());
+            indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.WILDCARD, textValue);
             break;
         case regex:
-            indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.REGEX, textConstraint.getText());
+            indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.REGEX, textValue);
             break;
         default:
             indexConstraint.setInvalied(String.format("PatterType %s not supported for Solr Index Queries!",
@@ -525,50 +526,89 @@ public class SolrQueryFactory {
         }
         private StringBuilder encodeSolrConstraint(StringBuilder queryString,EncodedConstraintParts encodedConstraintParts) {
             //list of all constraints that need to be connected with OR
-            List<StringBuilder> constraints = new ArrayList<StringBuilder>();
+            List<List<StringBuilder>> constraints = new ArrayList<List<StringBuilder>>();
             //init with a single constraint
-            constraints.add(new StringBuilder());
-            for(Entry<ConstraintTypePosition, Set<String>> entry : encodedConstraintParts){
+            constraints.add(new ArrayList<StringBuilder>(Arrays.asList(new StringBuilder())));
+            for(Entry<ConstraintTypePosition, Set<Set<String>>> entry : encodedConstraintParts){
                 //one position may contain multiple options that need to be connected with OR
-                Set<String> parts = entry.getValue();
+                Set<Set<String>> orParts = entry.getValue();
                 int i=0;
                 int constraintsSize = constraints.size();
-                for(String part : parts){
+                for(Set<String> andParts : orParts){
                     i++;
-                    if(i == parts.size()){
+                    //add the and constraints to all or
+                    List<StringBuilder> andConstaints;
+                    if(i == orParts.size()){
                         //for the last iteration, append the part to the existing constraints
                         for(int j=0;j<constraintsSize;j++){
-                            constraints.get(j).append(part);
+                            encodeAndParts(andParts, constraints.get(j));
                         }
                     } else {
                         //if there is more than one value, we need to generate new variants for
                         //every option other than the last.
                         for(int j=0;j<constraintsSize;j++){
-                            StringBuilder additional = new StringBuilder(constraints.get(j));
-                            additional.append(part);
+                            List<StringBuilder> additional = new ArrayList<StringBuilder>(constraints.get(j));
+                            encodeAndParts(andParts, additional);
+//                            additional.append(part);
                             constraints.add(additional);
                         }
                     }
                 }
             }
             //now combine the different options to a single query string
-            boolean first = true;
-            for(StringBuilder constraint : constraints){
-                if(constraint.length()>0){
-                    if(first){
+            boolean firstOr = true;
+            for(List<StringBuilder> constraint : constraints){
+                if(constraint.size()>0){
+                    if(firstOr){
                         queryString.append('(');
-                        first = false;
+                        firstOr = false;
                     } else {
-                        queryString.append(" OR ");
+                        queryString.append(" OR (");
+                    }
+                    boolean firstAnd = true;
+                    for(StringBuilder andConstraint: constraint){
+                        if(andConstraint.length()>0){
+                            if(firstAnd){
+                                queryString.append('(');
+                                firstAnd = false;
+                            } else {
+                                queryString.append(" AND (");
+                            }
+                            queryString.append(andConstraint);
+                            queryString.append(')');
+                        }
                     }
-                    queryString.append(constraint);
                 } //else ignore empty constraints
             }
-            if(!first){
-                queryString.append(')');
-            }
+            queryString.append(')');
             return queryString;
         }
+        /**
+         * @param andParts
+         * @param andConstaint
+         */
+        private void encodeAndParts(Set<String> andParts, List<StringBuilder> andConstaint) {
+            int andConstaintSize = andConstaint.size();
+            int k = 0;
+            for(String part : andParts){
+                k++;
+                //add the AND part of this constraint position with all parts of the others
+                if(k == andParts.size()){
+                    //for the last iteration, append the part to the existing constraints
+                    for(int j=0;j<andConstaintSize;j++){
+                        andConstaint.get(j).append(part);
+                    }
+                } else {
+                    //if there is more than one value, we need to generate new variants for
+                    //every option other than the last.
+                    for(int j=0;j<andConstaintSize;j++){
+                        StringBuilder additional = new StringBuilder(andConstaint.get(j));
+                        additional.append(part);
+                        andConstaint.add(additional);
+                    }
+                }
+            }
+        }
 
 //        /**
 //         * NOTE: removed, because currently not needed. If re-added, this Method needs also

Modified: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrYard.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrYard.java?rev=1089443&r1=1089442&r2=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrYard.java (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/SolrYard.java Wed Apr  6 13:14:26 2011
@@ -43,6 +43,8 @@ import org.apache.solr.client.solrj.Solr
 import org.apache.solr.client.solrj.SolrServer;
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.SolrRequest.METHOD;
+import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
+import org.apache.solr.client.solrj.impl.StreamingUpdateSolrServer;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.client.solrj.response.SolrPingResponse;
 import org.apache.solr.common.SolrDocument;
@@ -69,7 +71,6 @@ import org.apache.stanbol.entityhub.yard
 import org.apache.stanbol.entityhub.yard.solr.model.IndexValue;
 import org.apache.stanbol.entityhub.yard.solr.model.IndexValueFactory;
 import org.apache.stanbol.entityhub.yard.solr.query.IndexConstraintTypeEnum;
-import org.apache.stanbol.entityhub.yard.solr.utils.ConfigUtils;
 import org.apache.stanbol.entityhub.yard.solr.utils.SolrUtil;
 import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.component.ComponentContext;
@@ -236,10 +237,26 @@ public class SolrYard extends AbstractYa
     
     /**
      * Manager used to create the {@link SolrServer} instance used by this yard.
+     * Supports also {@link Type#STREAMING} and {@link Type#LOAD_BALANCE} type
+     * of servers.
+     * TODO: In case a remove SolrServer is configured by the
+     * {@link SolrYardConfig#getSolrServerLocation()}, than it would be possible
+     * to create both an {@link StreamingUpdateSolrServer} (by parsing 
+     * {@link Type#STREAMING}) and an normal {@link CommonsHttpSolrServer}. The
+     * streaming update one should be used for indexing requests and the
+     * commons http one for all other requests. This would provide performance
+     * advantages when updating {@link Representation}s stored in a SolrYard
+     * using an remote SolrServer.
      */
     @Reference
     private SolrServerProviderManager solrServerProviderManager;
-    
+    /**
+     * Used to retrieve (and init if not already present) the Solr Index directory
+     * for relative paths parsed for {@link SolrYardConfig#getSolrServerLocation()}.
+     * Note that the {@link SolrDirectoryManager} only provides the path to the
+     * files. The {@link SolrServer} instance is created by the
+     * {@link SolrServerProviderManager}!
+     */
     @Reference
     private SolrDirectoryManager solrDirectoryManager;
     /**
@@ -269,6 +286,17 @@ public class SolrYard extends AbstractYa
             new IllegalArgumentException("Unable to initialise SolrYard with the provided configuration",e);
         }
     }
+    /**
+     * Builds an {@link SolrYardConfig} instance based on the parsed {@link ComponentContext}
+     * and forwards to {@link #activate(SolrYardConfig)}.
+     * @param context The component context only used to create the {@link SolrYardConfig}
+     * based on {@link ComponentContext#getProperties()}.
+     * @throws ConfigurationException If the configuration is not valid
+     * @throws IOException In case the initialisation of the Solr index was not
+     * possible
+     * @throws SolrServerException Indicates that the referenced SolrServer has
+     * some problems (usually an invalid configuration).
+     */
     @SuppressWarnings("unchecked")
     @Activate
     protected final void activate(ComponentContext context) throws ConfigurationException,IOException,SolrServerException {
@@ -282,9 +310,11 @@ public class SolrYard extends AbstractYa
      * Internally used to configure an instance (within and without an OSGI
      * container
      * @param config The configuration
-     * @throws ConfigurationException
-     * @throws IOException
-     * @throws SolrServerException
+     * @throws ConfigurationException If the configuration is not valid
+     * @throws IOException In case the initialisation of the Solr index was not
+     * possible
+     * @throws SolrServerException Indicates that the referenced SolrServer has
+     * some problems (usually an invalid configuration).
      */
     private void activate(SolrYardConfig config) throws ConfigurationException,IOException,SolrServerException {
         //init with the default implementations of the ValueFactory and the QueryFactory
@@ -309,7 +339,10 @@ public class SolrYard extends AbstractYa
             File indexDirectory = ConfigUtils.toFile(config.getSolrServerLocation());
             if(!indexDirectory.isAbsolute()){ //relative paths
                 // need to be resolved based on the internally managed Solr directory
-                indexDirectory = solrDirectoryManager.getSolrDirectory(indexDirectory.toString());
+                //TODO: for now parse TRUE to allow automatic creation if the index
+                //      does not already exist. We might add this as an additional
+                //      parameter to the SolrIndexConfig 
+                indexDirectory = solrDirectoryManager.getSolrDirectory(indexDirectory.toString(),true);
             }
             solrIndexLocation = indexDirectory.toString();
         } else {
@@ -333,10 +366,14 @@ public class SolrYard extends AbstractYa
         this.documentBoostFieldName = config.getDocumentBoostFieldName();
         this.fieldBoostMap = config.getFieldBoosts();
     }
+    /**
+     * Deactivates this SolrYard instance after committing remaining changes
+     * @param context
+     */
     @Deactivate
     protected final void deactivate(ComponentContext context) {
-        log.info("in "+SolrYard.class+" deactivate with context "+context);
         SolrYardConfig config = (SolrYardConfig)getConfig();
+        log.info("... deactivating SolrYard "+config.getName()+" (id="+config.getId()+")");
         try {
             this.server.commit();
         } catch (SolrServerException e) {
@@ -353,13 +390,22 @@ public class SolrYard extends AbstractYa
         super.deactivate(); //deactivate the super implementation
     }
 
+    /**
+     * Calls the {@link #deactivate(ComponentContext)} with <code>null</code>
+     * as component context
+     */
+    @Override
+    protected void finalize() throws Throwable {
+        deactivate(null);
+        super.finalize();
+    }
 
     @Override
     public final QueryResultList<Representation> find(final FieldQuery parsedQuery) throws YardException{
         return find(parsedQuery,SELECT.QUERY);
     }
     private QueryResultList<Representation> find(final FieldQuery parsedQuery,SELECT select) throws YardException {
-        log.debug(String.format("find %s",parsedQuery));
+        log.debug("find "+parsedQuery);
         long start = System.currentTimeMillis();
         SolrQuery query = solrQueryFactoy.parseFieldQuery(parsedQuery,select);
         long queryGeneration = System.currentTimeMillis();
@@ -472,20 +518,16 @@ public class SolrYard extends AbstractYa
         }
         Representation rep = getValueFactory().createRepresentation(id.toString());
         for(String fieldName : doc.getFieldNames()){
-//            log.debug(String.format(" > process SolrDocument.field: %s",fieldName));
             IndexField indexField = fieldMapper.getField(fieldName);
             if(indexField != null && indexField.getPath().size() == 1){
                 String lang = indexField.getLanguages().isEmpty()?null:indexField.getLanguages().iterator().next();
                 if(fields == null || fields.contains(indexField.getPath().get(0))){
-//                    log.debug(String.format("   -> process IndexField %s ...",indexField));
                     for(Object value : doc.getFieldValues(fieldName)){
-//                        log.debug(String.format("   -> index value %s (type=%s)",value,value!=null?value.getClass():"---"));
                         if(value != null){
                             IndexDataTypeEnum dataTypeEnumEntry = IndexDataTypeEnum.forIndexType(indexField.getDataType());
                             if(dataTypeEnumEntry != null){
                                 Object javaValue = indexValueFactory.createValue(dataTypeEnumEntry.getJavaType(), indexField.getDataType(),value,lang);
                                 if(javaValue != null){
-//                                    log.debug(String.format("   <- java value %s (type=%s)",javaValue,javaValue.getClass()));
                                     rep.add(indexField.getPath().iterator().next(), javaValue);
                                 } else {
                                     log.warn(String.format("java value=null for index value %s",value));
@@ -495,14 +537,10 @@ public class SolrYard extends AbstractYa
                             }
                         } //else index value == null -> ignore
                     } //end for all values
-//                } else {
-//                    log.debug(String.format("   - IndexField %s filtered, because Path is not selected",indexField));
                 }
             } else {
                 if(indexField != null){
                     log.warn(String.format("Unable to prozess Index Field %s (for IndexDocument Field: %s)",indexField,fieldName));
-//                } else {
-//                    log.debug(String.format("IndexDocument Field %s does not represent a IndexField", fieldName));
                 }
             }
         } //end for all fields
@@ -642,9 +680,14 @@ public class SolrYard extends AbstractYa
         return added;
     }
     /**
-     * boost if present!
-     * @param representation
-     * @return
+     * Internally used to create Solr input documents for parsed representations.<p>
+     * This method supports boosting of fields. The boost is calculated by combining<ol>
+     * <li> the boot for the whole representation - by calling 
+     * {@link #getDocumentBoost(Representation)}
+     * <li> the boost of each field - by using the configured {@link #fieldBoostMap}
+     * </ol>
+     * @param representation the representation
+     * @return the Solr document for indexing
      */
     protected final SolrInputDocument createSolrInputDocument(Representation representation) {
         SolrYardConfig config = (SolrYardConfig)getConfig();
@@ -660,10 +703,11 @@ public class SolrYard extends AbstractYa
         for(Iterator<String> fields = representation.getFieldNames();fields.hasNext();){
             //TODO: maybe add some functionality to prevent indexing of the
             //      field configured as documentBoostFieldName!
+            //      But this would also prevent the possibility to intentionally
+            //      override the boost. 
             String field = fields.next();
             Float fieldBoost = fieldBoostMap == null ? null : fieldBoostMap.get(field);
             float boost = fieldBoost == null ? documentBoost : fieldBoost >= 0 ? fieldBoost * documentBoost: documentBoost;
-//            log.debug(String.format(" > Process Representation Field %s",field));
             for(Iterator<Object> values = representation.get(field);values.hasNext();){
                 //now we need to get the indexField for the value
                 Object next = values.next();
@@ -671,7 +715,6 @@ public class SolrYard extends AbstractYa
                 try {
                     value = indexValueFactory.createIndexValue(next);
                     for(String fieldName : fieldMapper.getFieldNames(Arrays.asList(field), value)){
-//                        log.debug(String.format("  - add: %s=%s",fieldName,value));
                         inputDocument.addField(fieldName, value.getValue(),boost);
                     }
                 }catch(Exception e){

Modified: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/queryencoders/AssignmentEncoder.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/queryencoders/AssignmentEncoder.java?rev=1089443&r1=1089442&r2=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/queryencoders/AssignmentEncoder.java (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/queryencoders/AssignmentEncoder.java Wed Apr  6 13:14:26 2011
@@ -19,6 +19,8 @@ package org.apache.stanbol.entityhub.yar
 import java.util.Arrays;
 import java.util.Collection;
 
+import org.apache.stanbol.entityhub.yard.solr.defaults.IndexDataTypeEnum;
+import org.apache.stanbol.entityhub.yard.solr.model.IndexDataType;
 import org.apache.stanbol.entityhub.yard.solr.model.IndexValue;
 import org.apache.stanbol.entityhub.yard.solr.model.IndexValueFactory;
 import org.apache.stanbol.entityhub.yard.solr.query.ConstraintTypePosition;
@@ -58,14 +60,18 @@ public class AssignmentEncoder implement
         } else {
             indexValue = indexValueFactory.createIndexValue(value);
         }
-        String eqConstraint = EQ;
-        if(value != null){
-            String escapedValue = SolrUtil.escapeSolrSpecialChars(indexValue.getValue());
-            //now we need to replace spaces with '+' because only than the query
-            //is treated as EQUALS by solr
-            eqConstraint = EQ+escapedValue.replace(' ', '+');
+        //encode the value based on the type
+        String[] queryConstraints = SolrUtil.encodeQueryValue(indexValue);
+        String[] eqConstraints;
+        if(queryConstraints != null){
+            eqConstraints = new String[queryConstraints.length];
+            for(int i=0;i<eqConstraints.length;i++){
+                eqConstraints[i] = EQ+queryConstraints[i];
+            }
+        } else {
+            eqConstraints = new String[]{EQ};
         }
-        constraint.addEncoded(POS, eqConstraint);
+        constraint.addEncoded(POS, eqConstraints);
     }
 
     @Override

Modified: incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/queryencoders/RegexEncoder.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/queryencoders/RegexEncoder.java?rev=1089443&r1=1089442&r2=1089443&view=diff
==============================================================================
--- incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/queryencoders/RegexEncoder.java (original)
+++ incubator/stanbol/trunk/entityhub/yard/solr/src/main/java/org/apache/stanbol/entityhub/yard/solr/impl/queryencoders/RegexEncoder.java Wed Apr  6 13:14:26 2011
@@ -18,12 +18,19 @@ package org.apache.stanbol.entityhub.yar
 
 import java.util.Arrays;
 import java.util.Collection;
-
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.stanbol.entityhub.yard.solr.defaults.IndexDataTypeEnum;
+import org.apache.stanbol.entityhub.yard.solr.model.IndexDataType;
+import org.apache.stanbol.entityhub.yard.solr.model.IndexValue;
 import org.apache.stanbol.entityhub.yard.solr.query.ConstraintTypePosition;
 import org.apache.stanbol.entityhub.yard.solr.query.EncodedConstraintParts;
 import org.apache.stanbol.entityhub.yard.solr.query.IndexConstraintTypeEncoder;
 import org.apache.stanbol.entityhub.yard.solr.query.IndexConstraintTypeEnum;
 import org.apache.stanbol.entityhub.yard.solr.query.ConstraintTypePosition.PositionType;
+import org.apache.stanbol.entityhub.yard.solr.utils.SolrUtil;
 
 
 /**
@@ -33,17 +40,28 @@ import org.apache.stanbol.entityhub.yard
  * @author Rupert Westenthaler
  *
  */
-public class RegexEncoder implements IndexConstraintTypeEncoder<String>{
+public class RegexEncoder implements IndexConstraintTypeEncoder<IndexValue>{
 
     private static final ConstraintTypePosition POS = new ConstraintTypePosition(PositionType.value);
 
+    private static final Set<IndexDataType> SUPPORTED_TYPES;
+    static {
+        Set<IndexDataType> types = new HashSet<IndexDataType>();
+        types.add(IndexDataTypeEnum.TXT.getIndexType());
+        types.add(IndexDataTypeEnum.STR.getIndexType());
+        SUPPORTED_TYPES = Collections.unmodifiableSet(types);
+    }
+
     @Override
-    public void encode(EncodedConstraintParts constraint, String value) {
+    public void encode(EncodedConstraintParts constraint, IndexValue value) {
         if(value == null){
             throw new IllegalArgumentException("This encoder does not support the NULL IndexValue!");
+        } else if(!SUPPORTED_TYPES.contains(value.getType())){
+            throw new IllegalArgumentException(String.format("This encoder does not support the IndexDataType %s (supported: %s)",
+                value.getType(),SUPPORTED_TYPES));
         } else {
             //TODO: Implement some REGEX to WILDCard conversion for Solr
-            constraint.addEncoded(POS, value.toLowerCase());
+            constraint.addEncoded(POS, value.getValue().toLowerCase());
         }
     }
 
@@ -63,8 +81,8 @@ public class RegexEncoder implements Ind
     }
 
     @Override
-    public Class<String> acceptsValueType() {
-        return String.class;
+    public Class<IndexValue> acceptsValueType() {
+        return IndexValue.class;
     }
 
 }