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;
}
}