/* * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed 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. * * Contributors: * Florent Guillaume * Stephane Lacoin */ package org.nuxeo.ecm.core.storage; import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.ecm.core.api.CoreSession; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.DocumentRef; import org.nuxeo.ecm.core.api.IdRef; import org.nuxeo.ecm.core.work.AbstractWork; import org.nuxeo.ecm.core.work.api.WorkManager; /** * Work task that inserts the fulltext (extracted manually by the session at save time, or through * FulltextExtractorWork) into the fulltext table. * <p> * This is done single-threaded through the use of a {@link WorkManager} queue with only one thread. */ public class FulltextUpdaterWork extends AbstractWork { private static final long serialVersionUID = 1L; private static final Log log = LogFactory.getLog(FulltextUpdaterWork.class); public static final String SYSPROP_FULLTEXT_SIMPLE = "fulltextSimple"; public static final String SYSPROP_FULLTEXT_BINARY = "fulltextBinary"; public static final String SYSPROP_FULLTEXT_JOBID = "fulltextJobId"; public static final String FULLTEXT_DEFAULT_INDEX = "default"; protected static final String CATEGORY = "fulltextUpdater"; protected static final String TITLE = "Fulltext Updater"; /** Is this a simple text index or a binary text one. */ protected final boolean isSimpleText; /** If true, then all the documents with the id as their jobId are updated. */ protected final boolean isJob; /** The indexes and text to be updated. */ protected final List<IndexAndText> indexesAndText; public static class IndexAndText implements Serializable { private static final long serialVersionUID = 1L; public String indexName; public String text; public IndexAndText(String indexName, String text) { this.indexName = indexName; this.text = text; } } public FulltextUpdaterWork(String repositoryName, String docId, boolean isSimpleText, boolean isJob, List<IndexAndText> indexesAndText) { super(); // random id, for unique job setDocument(repositoryName, docId); this.isSimpleText = isSimpleText; this.isJob = isJob; this.indexesAndText = indexesAndText; } @Override public String getCategory() { return CATEGORY; } @Override public String getTitle() { return TITLE; } @Override public int getRetryCount() { return 1; } @Override public void work() { openSystemSession(); // if the runtime has shut down (normally because tests are finished) // this can happen, see NXP-4009 if (session.getPrincipal() == null) { return; } setProgress(Progress.PROGRESS_0_PC); setStatus("Updating"); update(); setStatus("Saving"); session.save(); setStatus("Done"); } protected void updateWithSession(CoreSession session) { CoreSession tmp = this.session; this.session = session; update(); this.session = tmp; } protected void update() { Collection<DocumentModel> docs; if (isJob) { String query = String.format("SELECT * FROM Document WHERE ecm:fulltextJobId = '%s' AND ecm:isProxy = 0", docId); docs = session.query(query); } else { DocumentRef ref = new IdRef(docId); if (!session.exists(ref)) { // doc is gone return; } DocumentModel doc = session.getDocument(ref); if (doc.isProxy()) { // proxies don't have any fulltext attached, it's // the target document that carries it return; } docs = Collections.singleton(doc); } for (DocumentModel doc : docs) { for (IndexAndText indexAndText : indexesAndText) { session.setDocumentSystemProp(doc.getRef(), getFulltextPropertyName(indexAndText.indexName), indexAndText.text); } } if (isJob) { // reset job id for (DocumentModel doc : docs) { session.setDocumentSystemProp(doc.getRef(), SYSPROP_FULLTEXT_JOBID, null); } } } protected String getFulltextPropertyName(String indexName) { String name = isSimpleText ? SYSPROP_FULLTEXT_SIMPLE : SYSPROP_FULLTEXT_BINARY; if (!FULLTEXT_DEFAULT_INDEX.equals(indexName)) { name += '_' + indexName; } return name; } }