http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/IndexRepositoryImpl.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/IndexRepositoryImpl.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/IndexRepositoryImpl.java new file mode 100644 index 0000000..8c7754a --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/IndexRepositoryImpl.java @@ -0,0 +1,182 @@ +/* + * 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; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.lucene.internal.LuceneIndexStats; +import com.gemstone.gemfire.cache.lucene.internal.repository.serializer.LuceneSerializer; +import com.gemstone.gemfire.cache.lucene.internal.repository.serializer.SerializerUtil; +import com.gemstone.gemfire.distributed.internal.DistributionConfig; +import com.gemstone.gemfire.internal.logging.LogService; +import org.apache.logging.log4j.Logger; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.*; +import org.apache.lucene.store.AlreadyClosedException; + +import java.io.IOException; +import java.util.function.IntSupplier; + +/** + * A repository that writes to a single lucene index writer + */ +public class IndexRepositoryImpl implements IndexRepository { + + private static final boolean APPLY_ALL_DELETES = System + .getProperty(DistributionConfig.GEMFIRE_PREFIX + "IndexRepository.APPLY_ALL_DELETES", "true") + .equalsIgnoreCase("true"); + + private final IndexWriter writer; + private final LuceneSerializer serializer; + private final SearcherManager searcherManager; + private Region<?,?> region; + private Region<?,?> userRegion; + private LuceneIndexStats stats; + private DocumentCountSupplier documentCountSupplier; + + private static final Logger logger = LogService.getLogger(); + + public IndexRepositoryImpl(Region<?,?> region, IndexWriter writer, LuceneSerializer serializer, LuceneIndexStats stats, Region<?, ?> userRegion) throws IOException { + this.region = region; + this.userRegion = userRegion; + this.writer = writer; + searcherManager = new SearcherManager(writer, APPLY_ALL_DELETES, true, null); + this.serializer = serializer; + this.stats = stats; + documentCountSupplier = new DocumentCountSupplier(); + stats.addDocumentsSupplier(documentCountSupplier); + } + + @Override + public void create(Object key, Object value) throws IOException { + long start = stats.startUpdate(); + try { + Document doc = new Document(); + SerializerUtil.addKey(key, doc); + serializer.toDocument(value, doc); + writer.addDocument(doc); + } finally { + stats.endUpdate(start); + } + } + + @Override + public void update(Object key, Object value) throws IOException { + long start = stats.startUpdate(); + try { + Document doc = new Document(); + SerializerUtil.addKey(key, doc); + serializer.toDocument(value, doc); + writer.updateDocument(SerializerUtil.getKeyTerm(doc), doc); + } finally { + stats.endUpdate(start); + } + } + + @Override + public void delete(Object key) throws IOException { + long start = stats.startUpdate(); + try { + Term keyTerm = SerializerUtil.toKeyTerm(key); + writer.deleteDocuments(keyTerm); + } finally { + stats.endUpdate(start); + } + } + + @Override + public void query(Query query, int limit, IndexResultCollector collector) throws IOException { + long start = stats.startQuery(); + int totalHits = 0; + IndexSearcher searcher = searcherManager.acquire(); + try { + TopDocs docs = searcher.search(query, limit); + totalHits = docs.totalHits; + for(ScoreDoc scoreDoc : docs.scoreDocs) { + Document doc = searcher.doc(scoreDoc.doc); + Object key = SerializerUtil.getKey(doc); + if (logger.isDebugEnabled()) { + logger.debug("query found doc:"+doc+":"+scoreDoc); + } + collector.collect(key, scoreDoc.score); + } + } finally { + searcherManager.release(searcher); + stats.endQuery(start, totalHits); + } + } + + @Override + public synchronized void commit() throws IOException { + long start = stats.startCommit(); + try { + writer.commit(); + searcherManager.maybeRefresh(); + } finally { + stats.endCommit(start); + } + } + + public IndexWriter getWriter() { + return writer; + } + + @Override + public Region<?, ?> getRegion() { + return region; + } + + public LuceneSerializer getSerializer() { + return serializer; + } + + @Override + public boolean isClosed() { + return userRegion.isDestroyed(); + } + + @Override + public void cleanup() { + stats.removeDocumentsSupplier(documentCountSupplier); + try { + writer.close(); + } + catch (IOException e) { + logger.warn("Unable to clean up index repository", e); + } + } + + private class DocumentCountSupplier implements IntSupplier { + @Override + public int getAsInt() { + if(isClosed()) { + stats.removeDocumentsSupplier(this); + return 0; + } + try { + return writer.numDocs(); + } catch(AlreadyClosedException e) { + //ignore + return 0; + } + } + } +}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/IndexResultCollector.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/IndexResultCollector.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/IndexResultCollector.java new file mode 100644 index 0000000..7fd9e2a --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/IndexResultCollector.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.internal.repository; + +import com.gemstone.gemfire.annotations.Experimental; + +/** + * Interface for collection results of a query on + * an IndexRepository. See {@link IndexRepository#query(org.apache.lucene.search.Query, int, IndexResultCollector)} + */ +@Experimental +public interface IndexResultCollector { + /** + * @return Name/identifier of this collector + */ + public String getName(); + + /** + * @return Number of results collected by this collector + */ + public int size(); + + /** + * Collect a single document + * + * @param key the gemfire key of the object + * @param score the lucene score of this object + */ + void collect(Object key, float score); +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/RepositoryManager.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/RepositoryManager.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/RepositoryManager.java new file mode 100644 index 0000000..8f8d202 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/RepositoryManager.java @@ -0,0 +1,44 @@ +/* + * 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; + +import java.util.Collection; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.execute.RegionFunctionContext; +import com.gemstone.gemfire.internal.cache.BucketNotFoundException; + +/** + * {@link RepositoryManager} instances will be used to get {@link IndexRepository} instances hosting index data for + * {@link Region}s + */ +public interface RepositoryManager { + + IndexRepository getRepository(Region region, Object key, Object callbackArg) throws BucketNotFoundException; + + /** + * Returns a collection of {@link IndexRepository} instances hosting index data of the input list of bucket ids. The + * bucket needs to be present on this member. + * + * @return a collection of {@link IndexRepository} instances + * @throws BucketNotFoundException if any of the requested buckets is not found on this member + */ + Collection<IndexRepository> getRepositories(RegionFunctionContext context) throws BucketNotFoundException; +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/package-info.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/package-info.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/package-info.java new file mode 100644 index 0000000..894b464 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/package-info.java @@ -0,0 +1,25 @@ +/* + * 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. + */ +/** + * The repository package contains classes for managing a Lucene index in geode. + * + * All lucene index access should be through the {@link com.gemstone.gemfire.cache.lucene.internal.repository.IndexRepository} + * class. + */ +package com.gemstone.gemfire.cache.lucene.internal.repository; \ 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/repository/serializer/HeterogeneousLuceneSerializer.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/HeterogeneousLuceneSerializer.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/HeterogeneousLuceneSerializer.java new file mode 100644 index 0000000..271f0fd --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/HeterogeneousLuceneSerializer.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.repository.serializer; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.logging.log4j.Logger; +import org.apache.lucene.document.Document; + +import com.gemstone.gemfire.cache.lucene.LuceneIndex; +import com.gemstone.gemfire.cache.lucene.LuceneService; +import com.gemstone.gemfire.internal.logging.LogService; +import com.gemstone.gemfire.internal.util.concurrent.CopyOnWriteWeakHashMap; +import com.gemstone.gemfire.pdx.PdxInstance; + +/** + * An implementation of LuceneSerializer that reads the fields + * of a given object using reflection or from a PDX instance and + * writes them to a lucene document. + */ +public class HeterogeneousLuceneSerializer implements LuceneSerializer { + /** + * The set of indexed fields for this mapper + */ + private String[] indexedFields; + + /** + * A mapper for converting a PDX object into a document + */ + private LuceneSerializer pdxMapper; + + /** + * Mappers for each individual class type that this class has seen. + * + * Weak so that entry will be removed if a class is garbage collected. + */ + private Map<Class<?>, LuceneSerializer> mappers = new CopyOnWriteWeakHashMap<Class<?>, LuceneSerializer>(); + + private static final Logger logger = LogService.getLogger(); + + public HeterogeneousLuceneSerializer(String[] indexedFields) { + this.indexedFields = indexedFields; + pdxMapper = new PdxLuceneSerializer(indexedFields); + + + addSerializersForPrimitiveValues(); + } + + /** + * Add serializers for the primitive value types (String, Number, etc.) + * if the user has requested that the whole value be serialized + */ + private void addSerializersForPrimitiveValues() { + if(Arrays.asList(indexedFields).contains(LuceneService.REGION_VALUE_FIELD)) { + final PrimitiveSerializer primitiveSerializer = new PrimitiveSerializer(); + SerializerUtil.supportedPrimitiveTypes().stream() + .forEach(type -> mappers.put(type, primitiveSerializer)); + } + } + + @Override + public void toDocument(Object value, Document doc) { + + LuceneSerializer mapper = getFieldMapper(value); + + mapper.toDocument(value, doc); + if (logger.isDebugEnabled()) { + logger.debug("HeterogeneousLuceneSerializer.toDocument:"+doc); + } + } + + /** + * Get the field mapper based on the type of the given object. + */ + private LuceneSerializer getFieldMapper(Object value) { + if(value instanceof PdxInstance) { + return pdxMapper; + } else { + Class<?> clazz = value.getClass(); + LuceneSerializer mapper = mappers.get(clazz); + if(mapper == null) { + mapper = new ReflectionLuceneSerializer(clazz, indexedFields); + mappers.put(clazz, mapper); + } + return mapper; + } + } + + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/LuceneSerializer.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/LuceneSerializer.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/LuceneSerializer.java new file mode 100644 index 0000000..421dc0b --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/LuceneSerializer.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.repository.serializer; + +import org.apache.lucene.document.Document; + +/** + * An interface for writing the fields of an + * object into a lucene document + */ +public interface LuceneSerializer { + + /** + * Add the fields of the given value to the document + */ + void toDocument(Object value, Document doc); + +} \ 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/repository/serializer/PdxLuceneSerializer.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/PdxLuceneSerializer.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/PdxLuceneSerializer.java new file mode 100644 index 0000000..13465d7 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/PdxLuceneSerializer.java @@ -0,0 +1,57 @@ +/* + * 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 org.apache.logging.log4j.Logger; +import org.apache.lucene.document.Document; + +import com.gemstone.gemfire.internal.logging.LogService; +import com.gemstone.gemfire.pdx.PdxInstance; + +/** + * LuceneSerializer which can handle any PdxInstance + */ +class PdxLuceneSerializer implements LuceneSerializer { + + private String[] indexedFields; + + private static final Logger logger = LogService.getLogger(); + + public PdxLuceneSerializer(String[] indexedFields) { + this.indexedFields = indexedFields; + } + + @Override + public void toDocument(Object value, Document doc) { + PdxInstance pdx = (PdxInstance) value; + for(String field : indexedFields) { + if(pdx.hasField(field)) { + Object fieldValue = pdx.getField(field); + if (fieldValue == null) { + continue; + } + SerializerUtil.addField(doc, field, fieldValue); + } + } + if (logger.isDebugEnabled()) { + logger.debug("PdxLuceneSerializer.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/org/apache/geode/cache/lucene/internal/repository/serializer/PrimitiveSerializer.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/PrimitiveSerializer.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/PrimitiveSerializer.java new file mode 100644 index 0000000..d096637 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/PrimitiveSerializer.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.repository.serializer; + +import com.gemstone.gemfire.cache.lucene.LuceneService; + +import org.apache.lucene.document.Document; + +/** + * A LuceneSerializer that can serialize a primitive value (String, int, long, double) + * by creating a document with a special field containing the value + */ +public class PrimitiveSerializer implements LuceneSerializer { + + @Override + public void toDocument(final Object value, final Document doc) { + SerializerUtil.addField(doc, LuceneService.REGION_VALUE_FIELD, value); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/05e6d966/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java new file mode 100644 index 0000000..e06f99e --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/ReflectionLuceneSerializer.java @@ -0,0 +1,85 @@ +/* + * 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/org/apache/geode/cache/lucene/internal/repository/serializer/SerializerUtil.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/SerializerUtil.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/SerializerUtil.java new file mode 100644 index 0000000..4d563c1 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/SerializerUtil.java @@ -0,0 +1,190 @@ +/* + * 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/org/apache/geode/cache/lucene/internal/repository/serializer/package-info.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/package-info.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/package-info.java new file mode 100644 index 0000000..dca7737 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/repository/serializer/package-info.java @@ -0,0 +1,23 @@ +/* + * 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/org/apache/geode/cache/lucene/internal/xml/LuceneIndexCreation.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneIndexCreation.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneIndexCreation.java new file mode 100644 index 0000000..98233b0 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneIndexCreation.java @@ -0,0 +1,113 @@ +/* + * 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/org/apache/geode/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java new file mode 100644 index 0000000..37c9ca2 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneIndexXmlGenerator.java @@ -0,0 +1,70 @@ +/* + * 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/org/apache/geode/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java new file mode 100644 index 0000000..c449f47 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneServiceXmlGenerator.java @@ -0,0 +1,39 @@ +/* + * 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/org/apache/geode/cache/lucene/internal/xml/LuceneXmlConstants.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneXmlConstants.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneXmlConstants.java new file mode 100644 index 0000000..91d1643 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneXmlConstants.java @@ -0,0 +1,32 @@ +/* + * 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/org/apache/geode/cache/lucene/internal/xml/LuceneXmlParser.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneXmlParser.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneXmlParser.java new file mode 100644 index 0000000..5bdbe04 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/LuceneXmlParser.java @@ -0,0 +1,119 @@ +/* + * 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/org/apache/geode/cache/lucene/internal/xml/package-info.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/package-info.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/package-info.java new file mode 100644 index 0000000..4eb1ca3 --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/xml/package-info.java @@ -0,0 +1,24 @@ +/* + * 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/org/apache/geode/cache/lucene/package-info.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/package-info.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/package-info.java new file mode 100644 index 0000000..0e0c89b --- /dev/null +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/package-info.java @@ -0,0 +1,32 @@ +/* + * 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
