Java tutorial
/** * Copyright (C) 2010-2011 BonitaSoft S.A. * BonitaSoft, 31 rue Gustave Eiffel - 38000 Grenoble * This library is free software; you can redistribute it and/or modify it under the terms * of the GNU Lesser General Public License as published by the Free Software Foundation * version 2.1 of the License. * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301, USA. **/ package org.ow2.bonita.search; import java.lang.annotation.ElementType; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.lucene.util.Version; import org.hibernate.cfg.Configuration; import org.hibernate.event.def.DefaultFlushEventListener; import org.hibernate.search.Environment; import org.hibernate.search.annotations.Index; import org.hibernate.search.annotations.Resolution; import org.hibernate.search.cfg.SearchMapping; import org.hibernate.search.event.FullTextIndexEventListener; import org.hibernate.search.store.FSDirectoryProvider; import org.ow2.bonita.facade.def.InternalProcessDefinition; import org.ow2.bonita.facade.def.majorElement.impl.DescriptionElementImpl; import org.ow2.bonita.facade.def.majorElement.impl.NamedElementImpl; import org.ow2.bonita.facade.exception.BonitaInternalException; import org.ow2.bonita.facade.identity.ContactInfo; import org.ow2.bonita.facade.identity.impl.GroupImpl; import org.ow2.bonita.facade.identity.impl.RoleImpl; import org.ow2.bonita.facade.identity.impl.UserImpl; import org.ow2.bonita.facade.runtime.ActivityInstance; import org.ow2.bonita.facade.runtime.Comment; import org.ow2.bonita.facade.runtime.TaskInstance; import org.ow2.bonita.facade.runtime.impl.ActivityInstanceImpl; import org.ow2.bonita.facade.runtime.impl.CaseImpl; import org.ow2.bonita.facade.runtime.impl.CommentImpl; import org.ow2.bonita.facade.runtime.impl.InternalActivityInstance; import org.ow2.bonita.facade.runtime.impl.InternalProcessInstance; import org.ow2.bonita.facade.runtime.impl.ProcessInstanceImpl; import org.ow2.bonita.facade.runtime.impl.RuntimeRecordImpl; import org.ow2.bonita.light.LightActivityInstance; import org.ow2.bonita.light.impl.LightActivityInstanceImpl; import org.ow2.bonita.light.impl.LightProcessDefinitionImpl; import org.ow2.bonita.light.impl.LightProcessInstanceImpl; import org.ow2.bonita.search.index.ActivityInstanceIndex; import org.ow2.bonita.search.index.CaseIndex; import org.ow2.bonita.search.index.CommentIndex; import org.ow2.bonita.search.index.ContactInfoIndex; import org.ow2.bonita.search.index.GroupIndex; import org.ow2.bonita.search.index.ProcessDefinitionIndex; import org.ow2.bonita.search.index.ProcessInstanceIndex; import org.ow2.bonita.search.index.RoleIndex; import org.ow2.bonita.search.index.UserIndex; import org.ow2.bonita.util.BonitaConstants; /** * * @author Matthieu Chaffotte * */ public class SearchUtil { private static final Logger LOG = Logger.getLogger(SearchUtil.class.getName()); public static final Version LUCENE_VERSION = Version.LUCENE_29; private static boolean disableSearchConfiguration(final Configuration configuration) { boolean disable = false; String sysValue = System.getProperty("bonita.search.use"); if ("false".equals(sysValue)) { disable = true; } else { String useSearch = configuration.getProperty("bonita.search.use"); if (!"true".equals(useSearch)) { disable = true; } } return disable; } public static void addSearchConfiguration(final Configuration configuration) { boolean disable = disableSearchConfiguration(configuration); if (disable) { if (LOG.isLoggable(Level.INFO)) { LOG.info("Disable Bonita Indexes"); } } else { if (LOG.isLoggable(Level.INFO)) { LOG.info("Configuring indexes"); } SearchMapping mapping = new SearchMapping(); mapping.entity(InternalProcessDefinition.class).indexed().indexName("process_definition") .property("dbid", ElementType.FIELD).documentId().name(ProcessDefinitionIndex.DBID) .entity(LightProcessDefinitionImpl.class).property("uuid", ElementType.FIELD).field() .name(ProcessDefinitionIndex.UUID).bridge(UUIDFieldBridge.class) .property("categoryNames", ElementType.METHOD).field() .name(ProcessDefinitionIndex.CATEGORY_NAME).bridge(StringSetFieldBridge.class) .entity(NamedElementImpl.class).property("name", ElementType.METHOD).field() .name(ProcessDefinitionIndex.NAME).entity(DescriptionElementImpl.class) // share with All DescriptionElement: processes, groups, ... .property("description", ElementType.METHOD).field().name(ProcessDefinitionIndex.DESCRIPTION) .entity(InternalProcessInstance.class).indexed().indexName("process_instance") .property("dbid", ElementType.FIELD).documentId().name(ProcessInstanceIndex.DBID) .entity(ProcessInstanceImpl.class).property("commentFeed", ElementType.METHOD).indexEmbedded() .property("involvedUsers", ElementType.METHOD).field().name(ProcessInstanceIndex.INVOLVED_USER) .bridge(StringSetFieldBridge.class).property("activities", ElementType.METHOD).indexEmbedded() .property("lastKnownVariableValues", ElementType.METHOD).field().name("variable") .bridge(ObjectMapFieldBridge.class).property("activeUsers", ElementType.METHOD).field() .name(ProcessInstanceIndex.ACTIVE_USER).bridge(StringSetFieldBridge.class) .entity(LightProcessInstanceImpl.class).property("nb", ElementType.FIELD).field() .name(ProcessInstanceIndex.NB).property("startedBy", ElementType.METHOD).field() .name(ProcessInstanceIndex.STARTED_BY).property("endedBy", ElementType.METHOD).field() .name(ProcessInstanceIndex.ENDED_BY).property("startedDate", ElementType.METHOD).field() .name(ProcessInstanceIndex.STARTED_DATE).index(Index.UN_TOKENIZED) .dateBridge(Resolution.MILLISECOND).property("endedDate", ElementType.METHOD).field() .name(ProcessInstanceIndex.ENDED_DATE).index(Index.UN_TOKENIZED) .dateBridge(Resolution.MILLISECOND).property("lastUpdate", ElementType.METHOD).field() .name(ProcessInstanceIndex.LAST_UPDATE).index(Index.UN_TOKENIZED) .dateBridge(Resolution.MILLISECOND).entity(RuntimeRecordImpl.class) .property("processDefinitionUUID", ElementType.METHOD).field() .name(ProcessInstanceIndex.PROCESS_DEFINITION_UUID).bridge(UUIDFieldBridge.class) .property("processInstanceUUID", ElementType.METHOD).field() .name(ProcessInstanceIndex.PROCESS_INSTANCE_UUID).bridge(UUIDFieldBridge.class) .property("rootInstanceUUID", ElementType.METHOD).field() .name(ProcessInstanceIndex.PROCESS_ROOT_INSTANCE_UUID).bridge(UUIDFieldBridge.class) .entity(CommentImpl.class).indexed().indexName("comment").property("dbid", ElementType.FIELD) .documentId().name(CommentIndex.DBID).entity(Comment.class) .property("message", ElementType.METHOD).field().name(CommentIndex.MESSAGE) .property("userId", ElementType.METHOD).field().name(CommentIndex.AUTHOR) .property("date", ElementType.METHOD).field().name(CommentIndex.DATE).index(Index.UN_TOKENIZED) .dateBridge(Resolution.MILLISECOND) .entity(InternalActivityInstance.class).indexed().indexName("activity_instance") .property("dbid", ElementType.FIELD).documentId().name(ActivityInstanceIndex.DBID) .entity(TaskInstance.class).property("taskCandidates", ElementType.METHOD).field() .name(ActivityInstanceIndex.CANDIDATE).bridge(StringSetFieldBridge.class) .entity(ActivityInstanceImpl.class).property("taskCandidates", ElementType.METHOD).field() .name(ActivityInstanceIndex.CANDIDATE).bridge(StringSetFieldBridge.class) .property("lastKnownVariableValues", ElementType.METHOD).field().name("variable") .bridge(ObjectMapFieldBridge.class).entity(LightActivityInstanceImpl.class) .property("activityName", ElementType.METHOD).field().name(ActivityInstanceIndex.NAME) .property("state", ElementType.METHOD).field().name(ActivityInstanceIndex.STATE) .property("priority", ElementType.METHOD).field().name(ActivityInstanceIndex.PRIORITY) .index(Index.UN_TOKENIZED).property("lastUpdate", ElementType.METHOD).field() .name(ActivityInstanceIndex.LAST_UPDATE).index(Index.UN_TOKENIZED) .dateBridge(Resolution.MILLISECOND).property("expectedEndDate", ElementType.METHOD).field() .name(ActivityInstanceIndex.EXPECTED_END_DATE).index(Index.UN_TOKENIZED) .dateBridge(Resolution.MILLISECOND).entity(ActivityInstance.class) .property("activityName", ElementType.METHOD).field().name(ActivityInstanceIndex.NAME) .property("state", ElementType.METHOD).field().name(ActivityInstanceIndex.STATE) .property("lastKnownVariableValues", ElementType.METHOD).field().name("variable") .bridge(ObjectMapFieldBridge.class).entity(LightActivityInstance.class) .property("activityDescription", ElementType.METHOD).field() .name(ActivityInstanceIndex.DESCRIPTION).property("priority", ElementType.METHOD).field() .name(ActivityInstanceIndex.PRIORITY).index(Index.UN_TOKENIZED) .property("lastUpdate", ElementType.METHOD).field().name(ActivityInstanceIndex.LAST_UPDATE) .index(Index.UN_TOKENIZED).dateBridge(Resolution.MILLISECOND) .property("expectedEndDate", ElementType.METHOD).field() .name(ActivityInstanceIndex.EXPECTED_END_DATE).index(Index.UN_TOKENIZED) .dateBridge(Resolution.MILLISECOND) .entity(UserImpl.class).indexed().indexName("user").property("dbid", ElementType.FIELD) .documentId().name(UserIndex.DBID).property("username", ElementType.FIELD).field() .name(UserIndex.NAME).property("firstName", ElementType.FIELD).field() .name(UserIndex.FIRST_NAME).property("lastName", ElementType.FIELD).field() .name(UserIndex.LAST_NAME).property("manager", ElementType.FIELD).field() .name(UserIndex.MANAGER).property("delegate", ElementType.FIELD).field() .name(UserIndex.DELEGATE).property("title", ElementType.FIELD).field().name(UserIndex.TITLE) .property("jobTitle", ElementType.FIELD).field().name(UserIndex.JOB_TITLE) .property("professionalContactInfo", ElementType.FIELD).indexEmbedded() .property("personalContactInfo", ElementType.FIELD).indexEmbedded().entity(ContactInfo.class) .property("email", ElementType.METHOD).field().name(ContactInfoIndex.EMAIL) .property("phoneNumber", ElementType.METHOD).field().name(ContactInfoIndex.PHONE_NUMBER) .property("faxNumber", ElementType.METHOD).field().name(ContactInfoIndex.FAX_NUMBER) .property("building", ElementType.METHOD).field().name(ContactInfoIndex.BUILDING) .property("room", ElementType.METHOD).field().name(ContactInfoIndex.ROOM) .property("address", ElementType.METHOD).field().name(ContactInfoIndex.ADDRESS) .property("zipCode", ElementType.METHOD).field().name(ContactInfoIndex.ZIP_CODE) .property("city", ElementType.METHOD).field().name(ContactInfoIndex.CITY) .property("state", ElementType.METHOD).field().name(ContactInfoIndex.STATE) .property("country", ElementType.METHOD).field().name(ContactInfoIndex.COUNTRY) .property("website", ElementType.METHOD).field().name(ContactInfoIndex.WEBSITE) .entity(RoleImpl.class).indexed().indexName("role").property("dbid", ElementType.FIELD) .documentId().name(RoleIndex.DBID).property("name", ElementType.FIELD).field() .name(RoleIndex.NAME).property("label", ElementType.FIELD).field().name(RoleIndex.LABEL) .entity(GroupImpl.class).indexed().indexName("group").property("dbid", ElementType.FIELD) .documentId().name(GroupIndex.DBID).property("name", ElementType.METHOD).field() .name(GroupIndex.NAME).property("label", ElementType.METHOD).field().name(GroupIndex.LABEL) .entity(CaseImpl.class).indexed().indexName("case").property("dbid", ElementType.FIELD) .documentId().name(CaseIndex.DBID).property("labelName", ElementType.FIELD).field() .name(CaseIndex.LABEL_NAME).property("ownerName", ElementType.FIELD).field() .name(CaseIndex.OWNER_NAME).property("uuid", ElementType.FIELD).field() .name(CaseIndex.PROCESS_INSTANCE_UUID).bridge(UUIDFieldBridge.class); configuration.getProperties().put(Environment.MODEL_MAPPING, mapping); configuration.setProperty("hibernate.search.default.directory_provider", FSDirectoryProvider.class.getName()); String path = getDefaultIndexesDirectorPath(configuration); configuration.setProperty("hibernate.search.default.indexBase", path); configuration.setProperty("hibernate.search.autoregister_listeners", "false"); String fullTextIndexListener = FullTextIndexEventListener.class.getName(); configuration.setListener("post-update", fullTextIndexListener); configuration.setListener("post-insert", fullTextIndexListener); configuration.setListener("post-delete", fullTextIndexListener); configuration.setListener("post-collection-recreate", fullTextIndexListener); configuration.setListener("post-collection-remove", fullTextIndexListener); configuration.setListener("post-collection-update", fullTextIndexListener); String[] listeners = new String[] { DefaultFlushEventListener.class.getName(), fullTextIndexListener }; configuration.setListeners("flush", listeners); } } public static String getIndexesDirectoryPath(final Configuration configuration) { if (disableSearchConfiguration(configuration)) { return null; } else { return configuration.getProperty("hibernate.search.default.indexBase"); } } private static String getDefaultIndexesDirectorPath(final Configuration configuration) { String indexBasePath = getIndexesDirectoryPath(configuration); if (indexBasePath == null || "".equals(indexBasePath.trim())) { throw new BonitaInternalException("The hibernate.search.default.indexBase property is not set"); } if (indexBasePath.startsWith("${" + BonitaConstants.HOME + "}")) { indexBasePath = indexBasePath.replace("${" + BonitaConstants.HOME + "}", System.getProperty(BonitaConstants.HOME)); } return indexBasePath; } }