You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by hi...@apache.org on 2016/09/13 22:44:36 UTC
[48/61] [abbrv] incubator-geode git commit: GEODE-37 change package
name from com.gemstone.gemfire (for
./geode-lucene/src/main/java/com/gemstone/gemfire)to org.apache.geode for(to
./geode-lucene/src/main/java/org/apache/geode)
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java
deleted file mode 100644
index e06f99e..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java
+++ /dev/null
@@ -1,85 +0,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.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.repository.serializer;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.lucene.document.Document;
-
-import com.gemstone.gemfire.internal.logging.LogService;
-
-/**
- * A lucene serializer that handles a single class and can
- * map an instance of that class to a document using reflection.
- */
-class ReflectionLuceneSerializer implements LuceneSerializer {
-
- private Field[] fields;
-
- private static final Logger logger = LogService.getLogger();
-
- public ReflectionLuceneSerializer(Class<? extends Object> clazz,
- String[] indexedFields) {
- Set<String> fieldSet = new HashSet<String>();
- fieldSet.addAll(Arrays.asList(indexedFields));
-
- //Iterate through all declared fields and save them
- //in a list if they are an indexed field and have the correct
- //type.
- ArrayList<Field> foundFields = new ArrayList<Field>();
- while(clazz != Object.class) {
- for(Field field : clazz.getDeclaredFields()) {
- Class<?> type = field.getType();
- if(fieldSet.contains(field.getName())
- && SerializerUtil.isSupported(type)) {
- field.setAccessible(true);
- foundFields.add(field);
- }
- }
-
- clazz = clazz.getSuperclass();
- }
-
- this.fields = foundFields.toArray(new Field[foundFields.size()]);
- }
-
- @Override
- public void toDocument(Object value, Document doc) {
- for(Field field: fields) {
- try {
- Object fieldValue = field.get(value);
- if (fieldValue == null) {
- continue;
- }
- SerializerUtil.addField(doc, field.getName(), fieldValue);
- } catch (IllegalArgumentException | IllegalAccessException e) {
- //TODO - what to do if we can't read a field?
- }
- }
- if (logger.isDebugEnabled()) {
- logger.debug("ReflectionLuceneSerializer.toDocument:"+doc);
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java
deleted file mode 100644
index 4d563c1..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/SerializerUtil.java
+++ /dev/null
@@ -1,190 +0,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.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.repository.serializer;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.DoublePoint;
-import org.apache.lucene.document.Field.Store;
-import org.apache.lucene.document.FloatPoint;
-import org.apache.lucene.document.IntPoint;
-import org.apache.lucene.document.LongPoint;
-import org.apache.lucene.document.StringField;
-import org.apache.lucene.document.TextField;
-import org.apache.lucene.index.IndexableField;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.util.BytesRef;
-
-import com.gemstone.gemfire.DataSerializer;
-import com.gemstone.gemfire.InternalGemFireError;
-import com.gemstone.gemfire.internal.util.BlobHelper;
-
-/**
- * Static utility functions for mapping objects to lucene documents
- */
-public class SerializerUtil {
- private static final String KEY_FIELD = "_KEY";
-
- private static final Set<Class> SUPPORTED_PRIMITIVE_TYPES;
-
- static {
- HashSet<Class> primitiveTypes = new HashSet<>();
- primitiveTypes.add(String.class);
- primitiveTypes.add(long.class);
- primitiveTypes.add(int.class);
- primitiveTypes.add(float.class);
- primitiveTypes.add(double.class);
- primitiveTypes.add(Long.class);
- primitiveTypes.add(Integer.class);
- primitiveTypes.add(Float.class);
- primitiveTypes.add(Double.class);
-
- SUPPORTED_PRIMITIVE_TYPES = Collections.unmodifiableSet(primitiveTypes);
- }
-
- /**
- * A small buffer for converting keys to byte[] arrays.
- */
- private static ThreadLocal<ByteArrayOutputStream> LOCAL_BUFFER = new ThreadLocal<ByteArrayOutputStream>() {
- @Override
- protected ByteArrayOutputStream initialValue() {
- return new ByteArrayOutputStream();
- }
- };
-
- private SerializerUtil() {
- }
-
- /**
- * Add a gemfire key to a document
- */
- public static void addKey(Object key, Document doc) {
- if(key instanceof String) {
- doc.add(new StringField(KEY_FIELD, (String) key, Store.YES));
- } else {
- doc.add(new StringField(KEY_FIELD, keyToBytes(key), Store.YES));
- }
- }
-
- /**
- * Add a field to the document.
- *
- * @return true if the field was successfully added
- */
- public static boolean addField(Document doc, String field, Object fieldValue) {
- Class<?> clazz = fieldValue.getClass();
- if(clazz == String.class) {
- doc.add(new TextField(field, (String)fieldValue, Store.NO));
- } else if (clazz == Long.class) {
- doc.add(new LongPoint(field, (Long) fieldValue));
- } else if (clazz == Integer.class) {
- doc.add(new IntPoint(field, (Integer) fieldValue));
- } else if (clazz == Float.class) {
- doc.add(new FloatPoint(field, (Float) fieldValue));
- } else if (clazz == Double.class) {
- doc.add(new DoublePoint(field, (Double) fieldValue));
- } else {
- return false;
- }
-
- return true;
- }
-
- /**
- * Return true if a field type can be written to a lucene document.
- */
- public static boolean isSupported(Class<?> type) {
- return SUPPORTED_PRIMITIVE_TYPES.contains(type);
- }
-
- public static Collection<Class> supportedPrimitiveTypes() {
- return SUPPORTED_PRIMITIVE_TYPES;
- }
-
- /**
- * Extract the gemfire key from a lucene document
- */
- public static Object getKey(Document doc) {
- IndexableField field = doc.getField(KEY_FIELD);
- if(field.stringValue() != null) {
- return field.stringValue();
- } else {
- return keyFromBytes(field.binaryValue());
- }
- }
-
- /**
- * Extract the gemfire key term from a lucene document
- */
- public static Term getKeyTerm(Document doc) {
- IndexableField field = doc.getField(KEY_FIELD);
- if(field.stringValue() != null) {
- return new Term(KEY_FIELD, field.stringValue());
- } else {
- return new Term(KEY_FIELD, field.binaryValue());
- }
- }
-
- /**
- * Convert a gemfire key into a key search term that can be used to
- * update or delete the document associated with this key.
- */
- public static Term toKeyTerm(Object key) {
- if(key instanceof String) {
- return new Term(KEY_FIELD, (String) key);
- } else {
- return new Term(KEY_FIELD, keyToBytes(key));
- }
- }
-
- private static Object keyFromBytes(BytesRef bytes) {
- try {
- return BlobHelper.deserializeBlob(bytes.bytes);
- } catch (ClassNotFoundException | IOException e) {
- throw new InternalGemFireError(e);
- }
- }
-
- /**
- * Convert a key to a byte array.
- */
- private static BytesRef keyToBytes(Object key) {
- ByteArrayOutputStream buffer = LOCAL_BUFFER.get();
-
- try {
- DataOutputStream out = new DataOutputStream(buffer);
- DataSerializer.writeObject(key, out);
- out.flush();
- BytesRef result = new BytesRef(buffer.toByteArray());
- buffer.reset();
- return result;
- } catch (IOException e) {
- throw new InternalGemFireError("Unable to serialize key", e);
- }
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java
deleted file mode 100644
index dca7737..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/repository/serializer/package-info.java
+++ /dev/null
@@ -1,23 +0,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.
- */
-/**
- * Classes for converting gemfire objects into lucene documents.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.repository.serializer;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java
deleted file mode 100644
index 98233b0..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexCreation.java
+++ /dev/null
@@ -1,113 +0,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.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
-
-import java.util.*;
-
-import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
-import org.apache.lucene.analysis.standard.StandardAnalyzer;
-
-import com.gemstone.gemfire.cache.Cache;
-import com.gemstone.gemfire.cache.Region;
-import com.gemstone.gemfire.cache.lucene.LuceneIndex;
-import com.gemstone.gemfire.cache.lucene.LuceneService;
-import com.gemstone.gemfire.cache.lucene.LuceneServiceProvider;
-import com.gemstone.gemfire.cache.lucene.internal.LuceneServiceImpl;
-import com.gemstone.gemfire.internal.cache.extension.Extensible;
-import com.gemstone.gemfire.internal.cache.extension.Extension;
-import com.gemstone.gemfire.internal.cache.xmlcache.XmlGenerator;
-
-public class LuceneIndexCreation implements LuceneIndex, Extension<Region<?, ?>> {
- private Region region;
- private String name;
- private Set<String> fieldNames = new LinkedHashSet<String>();
- private Map<String, Analyzer> fieldAnalyzers;
-
-
- public void setRegion(Region region) {
- this.region = region;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public void setFieldAnalyzers(
- Map<String, Analyzer> fieldAnalyzers) {
- this.fieldAnalyzers = fieldAnalyzers;
- }
-
- @Override
- public Map<String, Analyzer> getFieldAnalyzers() {
- if (this.fieldAnalyzers == null) {
- this.fieldAnalyzers = new HashMap<>();
- }
- return this.fieldAnalyzers;
- }
-
- public String getName() {
- return name;
- }
-
- public String[] getFieldNames() {
- return fieldNames.toArray(new String[fieldNames.size()]);
- }
-
- @Override
- public String getRegionPath() {
- return region.getFullPath();
- }
-
- @Override
- public XmlGenerator<Region<?, ?>> getXmlGenerator() {
- return new LuceneIndexXmlGenerator(this);
- }
-
- @Override
- public void beforeCreate(Extensible<Region<?, ?>> source, Cache cache) {
- LuceneServiceImpl service = (LuceneServiceImpl) LuceneServiceProvider.get(cache);
- Analyzer analyzer = this.fieldAnalyzers == null
- ? new StandardAnalyzer()
- : new PerFieldAnalyzerWrapper(new StandardAnalyzer(), this.fieldAnalyzers);
- service.createIndex(getName(), getRegionPath(), analyzer, this.fieldAnalyzers, getFieldNames());
- }
-
- @Override
- public void onCreate(Extensible<Region<?, ?>> source, Extensible<Region<?, ?>> target) {}
-
- protected void addField(String name) {
- this.fieldNames.add(name);
- }
-
- protected void addFieldAndAnalyzer(String name, Analyzer analyzer) {
- this.fieldNames.add(name);
- getFieldAnalyzers().put(name, analyzer);
- }
-
- public void addFieldNames(String[] fieldNames) {
- this.fieldNames.addAll(Arrays.asList(fieldNames));
- }
-
- @Override
- public boolean waitUntilFlushed(int maxWaitInMillisecond) {
- return true;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java
deleted file mode 100644
index 37c9ca2..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java
+++ /dev/null
@@ -1,70 +0,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.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
-
-import static com.gemstone.gemfire.cache.lucene.internal.xml.LuceneXmlConstants.*;
-
-import org.apache.lucene.analysis.Analyzer;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.AttributesImpl;
-
-import com.gemstone.gemfire.cache.Region;
-import com.gemstone.gemfire.cache.lucene.LuceneIndex;
-import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator;
-import com.gemstone.gemfire.internal.cache.xmlcache.XmlGenerator;
-import com.gemstone.gemfire.internal.cache.xmlcache.XmlGeneratorUtils;
-
-public class LuceneIndexXmlGenerator implements XmlGenerator<Region<?, ?>> {
- private final LuceneIndex index;
-
- public LuceneIndexXmlGenerator(LuceneIndex index) {
- this.index = index;
- }
-
- @Override
- public String getNamspaceUri() {
- return NAMESPACE;
- }
-
- @Override
- public void generate(CacheXmlGenerator cacheXmlGenerator)
- throws SAXException {
- final ContentHandler handler = cacheXmlGenerator.getContentHandler();
-
- handler.startPrefixMapping(PREFIX, NAMESPACE);
-
- AttributesImpl attr = new AttributesImpl();
- //TODO - should the type be xs:string ?
- XmlGeneratorUtils.addAttribute(attr, NAME, index.getName());
- XmlGeneratorUtils.startElement(handler, PREFIX, INDEX, attr);
- for(String field : index.getFieldNames()) {
- AttributesImpl fieldAttr = new AttributesImpl();
- XmlGeneratorUtils.addAttribute(fieldAttr, NAME, field);
- Analyzer analyzer = index.getFieldAnalyzers().get(field);
- if (analyzer != null) {
- XmlGeneratorUtils.addAttribute(fieldAttr, ANALYZER, analyzer.getClass().getName());
- }
- XmlGeneratorUtils.emptyElement(handler, PREFIX, FIELD, fieldAttr);
- }
- XmlGeneratorUtils.endElement(handler, PREFIX, INDEX);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java
deleted file mode 100644
index c449f47..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java
+++ /dev/null
@@ -1,39 +0,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.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
-
-import org.xml.sax.SAXException;
-
-import com.gemstone.gemfire.cache.Cache;
-import com.gemstone.gemfire.internal.cache.xmlcache.CacheXmlGenerator;
-import com.gemstone.gemfire.internal.cache.xmlcache.XmlGenerator;
-
-public final class LuceneServiceXmlGenerator implements XmlGenerator<Cache> {
- @Override
- public String getNamspaceUri() {
- return LuceneXmlConstants.NAMESPACE;
- }
-
- @Override
- public void generate(CacheXmlGenerator cacheXmlGenerator)
- throws SAXException {
- //Nothing to to the xml at the service level at the moment.
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java
deleted file mode 100644
index 91d1643..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlConstants.java
+++ /dev/null
@@ -1,32 +0,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.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
-
-public class LuceneXmlConstants {
- public static final String NAMESPACE= "http://geode.apache.org/schema/lucene";
- public static final String PREFIX = "lucene";
- public static final String SERVICE = "service";
- public static final String NAME = "name";
- public static final String REGION = "index";
- public static final String INDEX = "index";
- public static final String FIELD = "field";
- public static final String ANALYZER = "analyzer";
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java
deleted file mode 100644
index 5bdbe04..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/LuceneXmlParser.java
+++ /dev/null
@@ -1,119 +0,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.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
-
-import static com.gemstone.gemfire.cache.lucene.internal.xml.LuceneXmlConstants.*;
-
-import com.gemstone.gemfire.cache.CacheXmlException;
-import com.gemstone.gemfire.internal.InternalDataSerializer;
-import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
-import org.apache.lucene.analysis.Analyzer;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-import com.gemstone.gemfire.cache.lucene.internal.LuceneServiceImpl;
-import com.gemstone.gemfire.internal.cache.xmlcache.AbstractXmlParser;
-import com.gemstone.gemfire.internal.cache.xmlcache.RegionAttributesCreation;
-import com.gemstone.gemfire.internal.cache.xmlcache.RegionCreation;
-
-public class LuceneXmlParser extends AbstractXmlParser {
-
- @Override
- public String getNamspaceUri() {
- return NAMESPACE;
- }
-
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes atts) throws SAXException {
-
- if(!NAMESPACE.equals(uri)) {
- return;
- }
- if(INDEX.equals(localName)) {
- startIndex(atts);
- }
- if(FIELD.equals(localName)) {
- startField(atts);
- }
- }
-
- private void startField(Attributes atts) {
- //Ignore any whitespace noise between fields
- if(stack.peek() instanceof StringBuffer) {
- stack.pop();
- }
- LuceneIndexCreation creation = (LuceneIndexCreation) stack.peek();
- String name = atts.getValue(NAME);
- String className = atts.getValue(ANALYZER);
- if (className == null) {
- creation.addField(name);
- } else {
- Analyzer analyzer = createAnalyzer(className);
- creation.addFieldAndAnalyzer(name, analyzer);
- }
- }
-
- private void startIndex(Attributes atts) {
- final RegionCreation region = (RegionCreation) stack.peek();
- String name = atts.getValue(NAME);
- LuceneIndexCreation indexCreation = new LuceneIndexCreation();
- indexCreation.setName(name);
- indexCreation.setRegion(region);
- region.getExtensionPoint().addExtension(indexCreation);
- stack.push(indexCreation);
- }
-
- @Override
- public void endElement(String uri, String localName, String qName)
- throws SAXException {
- if(!NAMESPACE.equals(uri)) {
- return;
- }
- if(INDEX.equals(localName)) {
- endIndex();
- }
- }
-
- private void endIndex() {
- //Ignore any whitespace noise between fields
- if(stack.peek() instanceof StringBuffer) {
- stack.pop();
- }
-
- //Remove the index creation from the stack
- stack.pop();
- }
-
- private Analyzer createAnalyzer(String className) {
- Object obj;
- try {
- Class c = InternalDataSerializer.getCachedClass(className);
- obj = c.newInstance();
- }
- catch (Exception ex) {
- throw new CacheXmlException(LocalizedStrings.CacheXmlParser_WHILE_INSTANTIATING_A_0.toLocalizedString(className), ex);
- }
- if (!(obj instanceof Analyzer)) {
- throw new CacheXmlException(LocalizedStrings.LuceneXmlParser_CLASS_0_IS_NOT_AN_INSTANCE_OF_ANALYZER.toLocalizedString(className));
- }
- return (Analyzer) obj;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java
deleted file mode 100644
index 4eb1ca3..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/internal/xml/package-info.java
+++ /dev/null
@@ -1,24 +0,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.
- */
-/**
- * Classes for parsing lucene index elements a cache.xml file. See the lucene-1.0.xsd file for
- * the schema.
- */
-
-package com.gemstone.gemfire.cache.lucene.internal.xml;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java b/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java
deleted file mode 100644
index 0e0c89b..0000000
--- a/geode-lucene/src/main/java/com/gemstone/gemfire/cache/lucene/package-info.java
+++ /dev/null
@@ -1,32 +0,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.
- */
-/**
- * This package provides an integration with Apache Lucene that allows Geode regions to be indexed in a distributed
- * Lucene index and queries using Lucene queries.
- * <p>
- * All indexing and query operations are performed through the {@link com.gemstone.gemfire.cache.lucene.LuceneService} class.
- * See {@link com.gemstone.gemfire.cache.lucene.LuceneService} for an example of how to add a lucene index to a geode region.
- * <p>
- *
- * The Lucene indexes created using this API are stored in geode and colocated with the indexed region, which means they
- * have the same availability guarantees as the underlying region. The indexes are maintained asynchronously, so changes
- * to the region may not be immediately visible in the lucene index.
- */
-
-package com.gemstone.gemfire.cache.lucene;
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java
new file mode 100644
index 0000000..6b1a4b4
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneIndex.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene;
+
+import java.util.Map;
+
+import org.apache.lucene.analysis.Analyzer;
+
+import com.gemstone.gemfire.annotations.Experimental;
+
+
+/**
+ * An lucene index is built over the data stored in a GemFire Region.
+ * <p>
+ * An index is specified using a index name, field names, region name.
+ * <p>
+ * The index name and region name together uniquely identifies the lucene index.
+ * <p>
+ *
+ */
+@Experimental
+public interface LuceneIndex {
+
+ /**
+ * @return the index name of this index
+ */
+ public String getName();
+
+ /**
+ * @return the region name for this index
+ */
+ public String getRegionPath();
+
+ /**
+ * @return the indexed field names in a Set
+ */
+ public String[] getFieldNames();
+
+ /**
+ * @return the field to analyzer map
+ */
+ public Map<String, Analyzer> getFieldAnalyzers();
+
+ /*
+ * wait until the current entries in cache are indexed
+ * @param maxWaitInMilliseconds max wait time in millisecond
+ * @return if entries are flushed within maxWait
+ */
+ public boolean waitUntilFlushed(int maxWaitInMillisecond);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java
new file mode 100644
index 0000000..7cc0977
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQuery.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene;
+
+import java.util.Collection;
+import java.util.List;
+
+import com.gemstone.gemfire.annotations.Experimental;
+
+/**
+ * Provides wrapper object of Lucene's Query object and execute the search.
+ * <p>Instances of this interface are created using
+ * {@link LuceneQueryFactory#create}.
+ *
+ */
+@Experimental
+public interface LuceneQuery<K, V> {
+ /**
+ * Execute search and return keys.
+ */
+ public Collection<K> findKeys() throws LuceneQueryException;
+
+ /**
+ * Execute search and return values.
+ */
+ public Collection<V> findValues() throws LuceneQueryException;
+
+ /**
+ * Execute search and return list of LuceneResultStruct.
+ */
+ public List<LuceneResultStruct<K, V>> findResults() throws LuceneQueryException;
+ /**
+ * Execute the search and get results.
+ */
+ public PageableLuceneQueryResults<K, V> findPages() throws LuceneQueryException;
+
+ /**
+ * Get page size setting of current query.
+ */
+ public int getPageSize();
+
+ /**
+ * Get limit size setting of current query.
+ */
+ public int getLimit();
+
+ /**
+ * Get projected fields setting of current query.
+ */
+ public String[] getProjectedFieldNames();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.java
new file mode 100644
index 0000000..fb03b4a
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryException.java
@@ -0,0 +1,40 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene;
+
+import com.gemstone.gemfire.GemFireCheckedException;
+
+/**
+ * Thrown when a lucene query fails.
+ */
+public class LuceneQueryException extends GemFireCheckedException {
+
+ public LuceneQueryException(final String message) {
+ super(message);
+ }
+
+ public LuceneQueryException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ public LuceneQueryException(final Throwable cause) {
+ super(cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java
new file mode 100644
index 0000000..8e36bbb
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryFactory.java
@@ -0,0 +1,98 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene;
+
+import org.apache.lucene.queryparser.classic.ParseException;
+
+import com.gemstone.gemfire.annotations.Experimental;
+
+/**
+ * Factory for creating instances of {@link LuceneQuery}.
+ * To get an instance of this factory call {@link LuceneService#createLuceneQueryFactory}.
+ * <P>
+ * To use this factory configure it with the <code>set</code> methods and then
+ * call {@link #create} to produce a {@link LuceneQuery} instance.
+ *
+ */
+@Experimental
+public interface LuceneQueryFactory {
+
+ /**
+ * Default query result limit is 100
+ */
+ public static final int DEFAULT_LIMIT = 100;
+
+ /**
+ * Default page size of result is 0, which means no pagination
+ */
+ public static final int DEFAULT_PAGESIZE = 0;
+
+ /**
+ * Set page size for a query result. The default page size is 0 which means no pagination.
+ * If specified negative value, throw IllegalArgumentException
+ * @param pageSize
+ * @return itself
+ */
+ LuceneQueryFactory setPageSize(int pageSize);
+
+ /**
+ * Set max limit of result for a query
+ * If specified limit is less or equal to zero, throw IllegalArgumentException
+ * @param limit
+ * @return itself
+ */
+ LuceneQueryFactory setResultLimit(int limit);
+
+ /**
+ * Set a list of fields for result projection.
+ *
+ * @param fieldNames
+ * @return itself
+ *
+ * @deprecated TODO This feature is not yet implemented
+ */
+ @Deprecated
+ LuceneQueryFactory setProjectionFields(String... fieldNames);
+
+ /**
+ * Create wrapper object for lucene's QueryParser object using default standard analyzer.
+ * The queryString is using lucene QueryParser's syntax. QueryParser is for easy-to-use
+ * with human understandable syntax.
+ *
+ * @param regionName region name
+ * @param indexName index name
+ * @param queryString query string in lucene QueryParser's syntax
+ * @param defaultField default field used by the Lucene Query Parser
+ * @param <K> the key type in the query results
+ * @param <V> the value type in the query results
+ * @return LuceneQuery object
+ */
+ public <K, V> LuceneQuery<K, V> create(String indexName, String regionName, String queryString, String defaultField);
+
+ /**
+ * Creates a wrapper object for Lucene's Query object. This {@link LuceneQuery} builder method could be used in
+ * advanced cases, such as cases where Lucene's Query object construction needs Lucene's API over query string.
+ *
+ * @param indexName index name
+ * @param regionName region name
+ * @param provider constructs and provides a Lucene Query object
+ * @param <K> the key type in the query results
+ * @param <V> the value type in the query results
+ * @return LuceneQuery object
+ */
+ public <K, V> LuceneQuery<K, V> create(String indexName, String regionName, LuceneQueryProvider provider);
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java
new file mode 100644
index 0000000..7f1c269
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneQueryProvider.java
@@ -0,0 +1,47 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene;
+
+import java.io.Serializable;
+
+import org.apache.lucene.search.Query;
+
+import com.gemstone.gemfire.annotations.Experimental;
+import com.gemstone.gemfire.cache.query.QueryException;
+
+/**
+ * The instances of this class will be used for distributing Lucene Query objects and re-constructing the Query object.
+ * If necessary the implementation needs to take care of serializing and de-serializing Lucene Query object. Geode
+ * respects the DataSerializable contract to provide optimal object serialization. For instance,
+ * {@link LuceneQueryProvider}'s toData method will be used to serialize it when it is sent to another member of the
+ * distributed system. Implementation of DataSerializable can provide a zero-argument constructor that will be invoked
+ * when they are read with DataSerializer.readObject.
+ */
+@Experimental
+public interface LuceneQueryProvider extends Serializable {
+ /**
+ * @return A Lucene Query object which could be used for executing Lucene Search on indexed data
+ * @param index local lucene index the query is being constructed against.
+ * @throws LuceneQueryException if the provider fails to construct the query object
+ */
+
+ public Query getQuery(LuceneIndex index) throws LuceneQueryException;
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java
new file mode 100644
index 0000000..bc587f5
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneResultStruct.java
@@ -0,0 +1,61 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene;
+
+import com.gemstone.gemfire.annotations.Experimental;
+
+/**
+ * <p>
+ * Abstract data structure for one item in query result.
+ *
+ */
+@Experimental
+public interface LuceneResultStruct<K, V> {
+ /**
+ * Return the value associated with the given field name
+ *
+ * @param fieldName the String name of the field
+ * @return the value associated with the specified field
+ * @throws IllegalArgumentException If this struct does not have a field named fieldName
+ */
+ public Object getProjectedField(String fieldName);
+
+ /**
+ * Return key of the entry
+ *
+ * @return key
+ * @throws IllegalArgumentException If this struct does not contain key
+ */
+ public K getKey();
+
+ /**
+ * Return value of the entry
+ *
+ * @return value the whole domain object
+ * @throws IllegalArgumentException If this struct does not contain value
+ */
+ public V getValue();
+
+ /**
+ * Return score of the query
+ *
+ * @return score
+ * @throws IllegalArgumentException If this struct does not contain score
+ */
+ public float getScore();
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java
new file mode 100644
index 0000000..cf1f735
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneService.java
@@ -0,0 +1,129 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.lucene.analysis.Analyzer;
+
+import com.gemstone.gemfire.annotations.Experimental;
+import com.gemstone.gemfire.cache.GemFireCache;
+import com.gemstone.gemfire.cache.lucene.internal.LuceneIndexCreationProfile;
+
+/**
+ * LuceneService instance is a singleton for each cache.
+ *
+ * It provides handle for managing the {@link LuceneIndex} and create the {@link LuceneQuery}
+ * via {@link LuceneQueryFactory}
+ *
+ * </p>
+ * Example: <br>
+ *
+ * <pre>
+ * At client and server JVM, initializing cache will create the LuceneServiceImpl object,
+ * which is a singleton at each JVM.
+ *
+ * At each server JVM, for data region to create index, create the index on fields with default analyzer:
+ * LuceneIndex index = luceneService.createIndex(indexName, regionName, "field1", "field2", "field3");
+ * or create index on fields with specified analyzer:
+ * LuceneIndex index = luceneService.createIndex(indexName, regionName, analyzerPerField);
+ *
+ * We can also create index via cache.xml or gfsh.
+ *
+ * At client side, create query and run the search:
+ *
+ * LuceneQuery query = luceneService.createLuceneQueryFactory().setLimit(200).setPageSize(20)
+ * .setResultTypes(SCORE, VALUE, KEY).setFieldProjection("field1", "field2")
+ * .create(indexName, regionName, querystring, analyzer);
+ *
+ * The querystring is using lucene's queryparser syntax, such as "field1:zhou* AND field2:gzhou@pivotal.io"
+ *
+ * PageableLuceneQueryResults results = query.search();
+ *
+ * If pagination is not specified:
+ * List list = results.getNextPage(); // return all results in one getNextPage() call
+ * or if paging is specified:
+ * if (results.hasNextPage()) {
+ * List page = results.nextPage(); // return resules page by page
+ * }
+ *
+ * The item of the list is either the domain object or instance of {@link LuceneResultStruct}
+ * </pre>
+ *
+ *
+ */
+@Experimental
+public interface LuceneService {
+
+ /**
+ * A special field name that indicates that the entire region value should
+ * be indexed. This will only work if the region value is a String or Number, in
+ * which case a lucene document will be created with a single field with this name.
+ */
+ String REGION_VALUE_FIELD = "__REGION_VALUE_FIELD";
+
+ /**
+ * Create a lucene index using default analyzer.
+ * @param fields The fields of the object to index. Only fields listed here will be stored
+ * in the index. Fields should map to PDX fieldNames if the object is serialized with PDX, or
+ * to java fields on the object otherwise. The special field name {{@link #REGION_VALUE_FIELD}}
+ * indicates that the entire value should be stored as a single field in the index.
+ */
+ public void createIndex(String indexName, String regionPath, String... fields);
+
+ /**
+ * Create a lucene index using specified analyzer per field
+ *
+ * @param indexName index name
+ * @param regionPath region name
+ * @param analyzerPerField A map of fields to analyzers. See {{@link #createIndex(String, String, String...)}}
+ * for details on valid values for fields. Each field will be tokenized using the provided Analyzer.
+ */
+ public void createIndex(String indexName, String regionPath,
+ Map<String, Analyzer> analyzerPerField);
+
+ /**
+ * Destroy the lucene index
+ *
+ * @param index index object
+ * @deprecated TODO This feature is not yet implemented
+ */
+ @Deprecated
+ public void destroyIndex(LuceneIndex index);
+
+ /**
+ * Get the lucene index object specified by region name and index name
+ * @param indexName index name
+ * @param regionPath region name
+ * @return LuceneIndex object
+ */
+ public LuceneIndex getIndex(String indexName, String regionPath);
+
+ /**
+ * get all the lucene indexes.
+ * @return all index objects in a Collection
+ */
+ public Collection<LuceneIndex> getAllIndexes();
+
+ /**
+ * create LuceneQueryFactory
+ * @return LuceneQueryFactory object
+ */
+ public LuceneQueryFactory createLuceneQueryFactory();
+
+ }
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java
new file mode 100644
index 0000000..f83dffa
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/LuceneServiceProvider.java
@@ -0,0 +1,45 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene;
+
+import com.gemstone.gemfire.annotations.Experimental;
+import com.gemstone.gemfire.cache.GemFireCache;
+import com.gemstone.gemfire.cache.lucene.internal.InternalLuceneService;
+import com.gemstone.gemfire.internal.cache.InternalCache;
+
+/**
+ * Class for retrieving or creating the currently running
+ * instance of the LuceneService.
+ *
+ */
+@Experimental
+public class LuceneServiceProvider {
+ /**
+ * Retrieve or create the lucene service for this cache
+ */
+ public static LuceneService get(GemFireCache cache) {
+ InternalCache internalCache = (InternalCache) cache;
+ return internalCache.getService(InternalLuceneService.class);
+ }
+
+ private LuceneServiceProvider() {
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java
new file mode 100644
index 0000000..c2def44
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/PageableLuceneQueryResults.java
@@ -0,0 +1,58 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene;
+
+import java.util.Iterator;
+import java.util.List;
+
+import com.gemstone.gemfire.annotations.Experimental;
+
+/**
+ * <p>
+ * Defines the interface for a container of lucene query result collected from function execution.<br>
+ *
+ *
+ * @param <K> The type of the key
+ * @param <V> The type of the value
+ */
+@Experimental
+public interface PageableLuceneQueryResults<K, V> extends Iterator<List<LuceneResultStruct<K,V>>> {
+ /**
+ * @return total number of hits for this query
+ */
+ public int size();
+
+ /**
+ * Returns the maximum score value encountered. Note that in case scores are not tracked, this returns {@link Float#NaN}.
+ */
+ public float getMaxScore();
+
+ /**
+ * Get the next page of results.
+ *
+ * @return a page of results, or null if there are no more pages
+ */
+ public List<LuceneResultStruct<K, V>> next();
+
+ /**
+ * True if there another page of results.
+ */
+ public boolean hasNext();
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java
new file mode 100755
index 0000000..1dc716c
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/AbstractPartitionedRepositoryManager.java
@@ -0,0 +1,124 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene.internal;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.gemstone.gemfire.InternalGemFireError;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.execute.RegionFunctionContext;
+import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository;
+import com.gemstone.gemfire.cache.lucene.internal.repository.RepositoryManager;
+import com.gemstone.gemfire.cache.lucene.internal.repository.serializer.LuceneSerializer;
+import com.gemstone.gemfire.internal.cache.BucketNotFoundException;
+import com.gemstone.gemfire.internal.cache.BucketRegion;
+import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+import com.gemstone.gemfire.internal.cache.execute.InternalRegionFunctionContext;
+
+public abstract class AbstractPartitionedRepositoryManager implements RepositoryManager {
+
+ /** map of the parent bucket region to the index repository
+ *
+ * This is based on the BucketRegion in case a bucket is rebalanced, we don't want to
+ * return a stale index repository. If a bucket moves off of this node and
+ * comes back, it will have a new BucketRegion object.
+ *
+ * It is weak so that the old BucketRegion will be garbage collected.
+ */
+ protected final ConcurrentHashMap<Integer, IndexRepository> indexRepositories = new ConcurrentHashMap<Integer, IndexRepository>();
+
+ /** The user region for this index */
+ protected final PartitionedRegion userRegion;
+ protected final LuceneSerializer serializer;
+ protected final LuceneIndexImpl index;
+
+ public AbstractPartitionedRepositoryManager(
+ LuceneIndexImpl index,
+ LuceneSerializer serializer) {
+ this.index = index;
+ this.userRegion = (PartitionedRegion)index.getCache().getRegion(index.getRegionPath());
+ this.serializer = serializer;
+ }
+
+ @Override
+ public IndexRepository getRepository(Region region, Object key,
+ Object callbackArg) throws BucketNotFoundException {
+ BucketRegion userBucket = userRegion.getBucketRegion(key, callbackArg);
+ if(userBucket == null) {
+ throw new BucketNotFoundException("User bucket was not found for region " + region + "key " + key + " callbackarg " + callbackArg);
+ }
+
+ return getRepository(userBucket.getId());
+ }
+
+ @Override
+ public Collection<IndexRepository> getRepositories(RegionFunctionContext ctx) throws BucketNotFoundException {
+ Region<Object, Object> region = ctx.getDataSet();
+ Set<Integer> buckets = ((InternalRegionFunctionContext) ctx).getLocalBucketSet(region);
+ ArrayList<IndexRepository> repos = new ArrayList<IndexRepository>(buckets.size());
+ for(Integer bucketId : buckets) {
+ BucketRegion userBucket = userRegion.getDataStore().getLocalBucketById(bucketId);
+ if(userBucket == null) {
+ throw new BucketNotFoundException("User bucket was not found for region " + region + "bucket id " + bucketId);
+ } else {
+ repos.add(getRepository(userBucket.getId()));
+ }
+ }
+
+ return repos;
+ }
+
+ public abstract IndexRepository createOneIndexRepository(final Integer bucketId,
+ LuceneSerializer serializer,
+ LuceneIndexImpl index, PartitionedRegion userRegion) throws IOException;
+
+ /**
+ * Return the repository for a given user bucket
+ */
+ protected IndexRepository getRepository(Integer bucketId) throws BucketNotFoundException {
+ IndexRepository repo = indexRepositories.get(bucketId);
+ if(repo != null && !repo.isClosed()) {
+ return repo;
+ }
+
+ repo = indexRepositories.compute(bucketId, (key, oldRepository) -> {
+ if(oldRepository != null && !oldRepository.isClosed()) {
+ return oldRepository;
+ }
+ if(oldRepository != null) {
+ oldRepository.cleanup();
+ }
+
+ try {
+ return createOneIndexRepository(bucketId, serializer, index, userRegion);
+ } catch(IOException e) {
+ throw new InternalGemFireError("Unable to create index repository", e);
+ }
+
+ });
+
+ if(repo == null) {
+ throw new BucketNotFoundException("Colocated index buckets not found for bucket id " + bucketId);
+ }
+
+ return repo;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java
new file mode 100644
index 0000000..c9c03a5
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListener.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene.internal;
+
+import com.gemstone.gemfire.cache.lucene.LuceneIndex;
+import org.apache.lucene.analysis.Analyzer;
+
+import java.util.Map;
+
+public interface IndexListener {
+
+ public void beforeIndexCreated(final String indexName, String regionPath,
+ final Analyzer analyzer, final Map<String, Analyzer> fieldAnalyzers,
+ final String... fields);
+
+ public void afterIndexCreated(LuceneIndex index);
+
+ public void beforeIndexDestroyed(LuceneIndex index);
+
+ public void afterIndexDestroyed(LuceneIndex index);
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.java
new file mode 100644
index 0000000..dd916ac
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexListenerAdapter.java
@@ -0,0 +1,41 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene.internal;
+
+import com.gemstone.gemfire.cache.lucene.LuceneIndex;
+import org.apache.lucene.analysis.Analyzer;
+
+import java.util.Map;
+
+public class IndexListenerAdapter implements IndexListener {
+ @Override
+ public void beforeIndexCreated(String indexName, String regionPath, Analyzer analyzer,
+ Map<String, Analyzer> fieldAnalyzers, String... fields) {
+ }
+
+ @Override
+ public void afterIndexCreated(LuceneIndex index) {
+ }
+
+ @Override
+ public void beforeIndexDestroyed(LuceneIndex index) {
+ }
+
+ @Override
+ public void afterIndexDestroyed(LuceneIndex index) {
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java
new file mode 100644
index 0000000..e6f01b0
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/IndexRepositoryFactory.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene.internal;
+
+import java.io.IOException;
+
+import com.gemstone.gemfire.cache.lucene.internal.directory.RegionDirectory;
+import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository;
+import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepositoryImpl;
+import com.gemstone.gemfire.cache.lucene.internal.repository.serializer.LuceneSerializer;
+import com.gemstone.gemfire.internal.cache.BucketNotFoundException;
+import com.gemstone.gemfire.internal.cache.BucketRegion;
+import com.gemstone.gemfire.internal.cache.PartitionedRegion;
+
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+
+public class IndexRepositoryFactory {
+
+ public IndexRepositoryFactory() {
+ }
+
+ public IndexRepository createIndexRepository(final Integer bucketId,
+ LuceneSerializer serializer,
+ LuceneIndexImpl index, PartitionedRegion userRegion)
+ throws IOException
+ {
+ final IndexRepository repo;
+ LuceneIndexForPartitionedRegion indexForPR = (LuceneIndexForPartitionedRegion)index;
+ BucketRegion fileBucket = getMatchingBucket(indexForPR.getFileRegion(), bucketId);
+ BucketRegion chunkBucket = getMatchingBucket(indexForPR.getChunkRegion(), bucketId);
+ BucketRegion dataBucket = getMatchingBucket(userRegion, bucketId);
+ if(fileBucket == null || chunkBucket == null) {
+ return null;
+ }
+ RegionDirectory dir = new RegionDirectory(fileBucket, chunkBucket, indexForPR.getFileSystemStats());
+ IndexWriterConfig config = new IndexWriterConfig(indexForPR.getAnalyzer());
+ IndexWriter writer = new IndexWriter(dir, config);
+ repo = new IndexRepositoryImpl(fileBucket, writer, serializer, indexForPR.getIndexStats(), dataBucket);
+ return repo;
+ }
+
+ /**
+ * Find the bucket in region2 that matches the bucket id from region1.
+ */
+ protected BucketRegion getMatchingBucket(PartitionedRegion region, Integer bucketId) {
+ //Force the bucket to be created if it is not already
+ region.getOrCreateNodeForBucketWrite(bucketId, null);
+
+ return region.getDataStore().getLocalBucketById(bucketId);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java
new file mode 100644
index 0000000..27b4820
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneIndex.java
@@ -0,0 +1,34 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene.internal;
+
+import com.gemstone.gemfire.cache.lucene.LuceneIndex;
+import com.gemstone.gemfire.cache.lucene.internal.repository.RepositoryManager;
+
+public interface InternalLuceneIndex extends LuceneIndex {
+
+ public RepositoryManager getRepositoryManager();
+
+ /**
+ * Dump the files for this index to the given directory.
+ */
+ public void dumpFiles(String directory);
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java
new file mode 100644
index 0000000..403853e
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/InternalLuceneService.java
@@ -0,0 +1,29 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene.internal;
+
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.lucene.LuceneService;
+import com.gemstone.gemfire.internal.cache.CacheService;
+import com.gemstone.gemfire.internal.cache.extension.Extension;
+
+public interface InternalLuceneService extends LuceneService, Extension<Cache>, CacheService {
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java
new file mode 100644
index 0000000..29fb159
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneEventListener.java
@@ -0,0 +1,107 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene.internal;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.logging.log4j.Logger;
+
+import com.gemstone.gemfire.InternalGemFireError;
+import com.gemstone.gemfire.cache.Operation;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionDestroyedException;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEvent;
+import com.gemstone.gemfire.cache.asyncqueue.AsyncEventListener;
+import com.gemstone.gemfire.cache.lucene.internal.repository.RepositoryManager;
+import com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository;
+import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
+import com.gemstone.gemfire.internal.cache.BucketNotFoundException;
+import com.gemstone.gemfire.internal.cache.CacheObserverHolder;
+import com.gemstone.gemfire.internal.cache.PrimaryBucketException;
+import com.gemstone.gemfire.internal.cache.partitioned.Bucket;
+import com.gemstone.gemfire.internal.cache.tier.sockets.CacheClientProxy.TestHook;
+import com.gemstone.gemfire.internal.logging.LogService;
+
+/**
+ * An Async event queue listener that writes all of the
+ * events in batches to Lucene
+ */
+public class LuceneEventListener implements AsyncEventListener {
+ Logger logger = LogService.getLogger();
+
+ private final RepositoryManager repositoryManager;
+
+ public LuceneEventListener(RepositoryManager repositoryManager) {
+ this.repositoryManager = repositoryManager;
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public boolean processEvents(List<AsyncEvent> events) {
+ // Try to get a PDX instance if possible, rather than a deserialized object
+ DefaultQuery.setPdxReadSerialized(true);
+
+ Set<IndexRepository> affectedRepos = new HashSet<IndexRepository>();
+
+ try {
+ for (AsyncEvent event : events) {
+ Region region = event.getRegion();
+ Object key = event.getKey();
+ Object callbackArgument = event.getCallbackArgument();
+
+ IndexRepository repository = repositoryManager.getRepository(region, key, callbackArgument);
+
+ Operation op = event.getOperation();
+
+ if (op.isCreate()) {
+ repository.update(key, event.getDeserializedValue());
+ } else if (op.isUpdate()) {
+ repository.update(key, event.getDeserializedValue());
+ } else if (op.isDestroy()) {
+ repository.delete(key);
+ } else if (op.isInvalidate()) {
+ repository.delete(key);
+ } else {
+ throw new InternalGemFireError("Unhandled operation " + op + " on " + event.getRegion());
+ }
+ affectedRepos.add(repository);
+ }
+
+ for(IndexRepository repo : affectedRepos) {
+ repo.commit();
+ }
+ return true;
+ } catch(BucketNotFoundException | RegionDestroyedException | PrimaryBucketException e) {
+ logger.debug("Bucket not found while saving to lucene index: " + e.getMessage());
+ return false;
+ } catch(IOException e) {
+ logger.error("Unable to save to lucene index", e);
+ return false;
+ } finally {
+ DefaultQuery.setPdxReadSerialized(false);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java
----------------------------------------------------------------------
diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java
new file mode 100644
index 0000000..de331ea
--- /dev/null
+++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneIndexCreationProfile.java
@@ -0,0 +1,172 @@
+/*
+ * 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 com.gemstone.gemfire.cache.lucene.internal;
+
+import com.gemstone.gemfire.DataSerializable;
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.internal.Version;
+import com.gemstone.gemfire.internal.cache.CacheServiceProfile;
+import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.*;
+
+public class LuceneIndexCreationProfile implements CacheServiceProfile, DataSerializable {
+
+ private String indexName;
+
+ private String[] fieldNames;
+
+ private String analyzerClass;
+
+ private Map<String, String> fieldAnalyzers;
+
+ private String regionPath;
+
+ /* Used by DataSerializer */
+ public LuceneIndexCreationProfile() {}
+
+ public LuceneIndexCreationProfile(String indexName, String regionPath, String[] fieldNames, Analyzer analyzer,
+ Map<String, Analyzer> fieldAnalyzers) {
+ this.indexName = indexName;
+ this.regionPath = regionPath;
+ this.fieldNames = fieldNames;
+ this.analyzerClass = analyzer.getClass().getSimpleName();
+ initializeFieldAnalyzers(fieldAnalyzers);
+ }
+
+ public String getIndexName() {
+ return this.indexName;
+ }
+
+ public String[] getFieldNames() {
+ return this.fieldNames;
+ }
+
+ public String getAnalyzerClass() {
+ return this.analyzerClass;
+ }
+
+ public Map<String, String> getFieldAnalyzers() {
+ return this.fieldAnalyzers;
+ }
+
+ protected void initializeFieldAnalyzers(Map<String, Analyzer> fieldAnalyzers) {
+ this.fieldAnalyzers = new HashMap<>();
+ for (String field : fieldNames) {
+ if(fieldAnalyzers != null && !fieldAnalyzers.isEmpty()) {
+ this.fieldAnalyzers.put(field, fieldAnalyzers.get(field) == null ? StandardAnalyzer.class.getSimpleName() : fieldAnalyzers.get(field).getClass().getSimpleName());
+ } else {
+ this.fieldAnalyzers.put(field, StandardAnalyzer.class.getSimpleName());
+ }
+ }
+ }
+
+ @Override
+ public String getId() {
+ return "lucene_"+LuceneServiceImpl.getUniqueIndexName(indexName, regionPath);
+ }
+
+ @Override
+ public String checkCompatibility(String regionPath, CacheServiceProfile profile) {
+ String result = null;
+ LuceneIndexCreationProfile remoteProfile = (LuceneIndexCreationProfile) profile;
+ if (remoteProfile == null) {
+ // TODO This can occur if one member defines no indexes but another one does. Currently this is caught by the async event id checks.
+ } else {
+ // Verify fields are the same
+ if (!Arrays.equals(remoteProfile.getFieldNames(), getFieldNames())) {
+ return LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_FIELDS_2_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_FIELDS_3
+ .toString(getIndexName(), regionPath, Arrays.toString(getFieldNames()), Arrays.toString(remoteProfile.getFieldNames()));
+ }
+
+ // Verify the analyzer class is the same
+ // Note: This test will currently only fail if per-field analyzers are used in one member but not another,
+ // This condition will be caught in the tests below so this test is commented out. If we ever allow the user
+ // to configure a single analyzer for all fields, then this test will be useful again.
+ /*
+ if (!remoteLuceneIndexProfile.getAnalyzerClass().isInstance(getAnalyzer())) {
+ result = LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_ANALYZER_2_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_ANALYZER_3
+ .toString(indexName, regionPath, remoteLuceneIndexProfile.getAnalyzerClass().getName(), analyzer.getClass().getName());
+ }
+ */
+
+ // Iterate the existing analyzers and compare them to the input analyzers
+ // Note: This is currently destructive to the input field analyzers map which should be ok since its a transient object.
+ if (!getFieldAnalyzers().equals(remoteProfile.getFieldAnalyzers())) {
+ if (getFieldAnalyzers().size() != remoteProfile.getFieldAnalyzers().size()) {
+ return LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_FIELDS_2_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_FIELDS_3
+ .toString(getIndexName(), regionPath,
+ Arrays.toString(getFieldAnalyzers().keySet().toArray()),
+ Arrays.toString(remoteProfile.getFieldAnalyzers().keySet().toArray()));
+ }
+ // now the 2 maps should have the same size
+ for (String field:getFieldAnalyzers().keySet()) {
+ if (!remoteProfile.getFieldAnalyzers().get(field).equals(getFieldAnalyzers().get(field))) {
+ return LocalizedStrings.LuceneService_CANNOT_CREATE_INDEX_0_ON_REGION_1_WITH_ANALYZER_2_ON_FIELD_3_BECAUSE_ANOTHER_MEMBER_DEFINES_THE_SAME_INDEX_WITH_ANALYZER_4_ON_THAT_FIELD
+ .toString(getIndexName(), regionPath,
+ getFieldAnalyzers().get(field), field,
+ remoteProfile.getFieldAnalyzers().get(field));
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void toData(DataOutput out) throws IOException {
+ DataSerializer.writeString(this.indexName, out);
+ DataSerializer.writeString(this.regionPath, out);
+ DataSerializer.writeStringArray(this.fieldNames, out);
+ DataSerializer.writeString(this.analyzerClass, out);
+ DataSerializer.writeHashMap(this.fieldAnalyzers, out);
+ }
+
+ @Override
+ public void fromData(DataInput in) throws IOException, ClassNotFoundException {
+ this.indexName = DataSerializer.readString(in);
+ this.regionPath = DataSerializer.readString(in);
+ this.fieldNames = DataSerializer.readStringArray(in);
+ this.analyzerClass = DataSerializer.readString(in);
+ this.fieldAnalyzers = DataSerializer.readHashMap(in);
+ }
+
+ public String toString() {
+ return new StringBuilder()
+ .append(getClass().getSimpleName())
+ .append("[")
+ .append("indexName=")
+ .append(this.indexName)
+ .append("; fieldNames=")
+ .append(Arrays.toString(this.fieldNames))
+ .append("; analyzerClass=")
+ .append(this.analyzerClass)
+ .append("; fieldAnalyzers=")
+ .append(this.fieldAnalyzers)
+ .append("]")
+ .toString();
+ }
+
+ public String getRegionPath() {
+ return this.regionPath;
+ }
+}