001 /**
002 * $RCSfile: MCRLuceneCommands.java,v $
003 * $Revision: 1.0 $ $Date: 22.10.2008 06:48:51 $
004 *
005 * This file is part of ** M y C o R e **
006 * Visit our homepage at http://www.mycore.de/ for details.
007 *
008 * This program is free software; you can use it, redistribute it
009 * and / or modify it under the terms of the GNU General Public License
010 * (GPL) as published by the Free Software Foundation; either version 2
011 * of the License or (at your option) any later version.
012 *
013 * This program is distributed in the hope that it will be useful, but
014 * WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program, normally in the file license.txt.
020 * If not, write to the Free Software Foundation Inc.,
021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
022 *
023 **/
024 package org.mycore.frontend.cli;
025
026 import java.io.IOException;
027 import java.util.ArrayList;
028 import java.util.GregorianCalendar;
029 import java.util.List;
030 import java.util.Properties;
031 import java.util.Map.Entry;
032
033 import org.apache.log4j.Logger;
034 import org.hibernate.CacheMode;
035 import org.hibernate.Criteria;
036 import org.hibernate.ScrollMode;
037 import org.hibernate.ScrollableResults;
038 import org.hibernate.Session;
039 import org.hibernate.criterion.Restrictions;
040 import org.jdom.Document;
041 import org.jdom.Element;
042 import org.jdom.JDOMException;
043 import org.jdom.Namespace;
044
045 import org.mycore.backend.hibernate.MCRHIBConnection;
046 import org.mycore.backend.hibernate.tables.MCRFSNODES;
047 import org.mycore.backend.hibernate.tables.MCRXMLTABLE;
048 import org.mycore.common.MCRConfiguration;
049 import org.mycore.common.MCRConstants;
050 import org.mycore.common.xml.MCRXMLResource;
051 import org.mycore.datamodel.ifs.MCRFile;
052 import org.mycore.datamodel.ifs.MCRFileMetadataManager;
053 import org.mycore.services.fieldquery.MCRData2Fields;
054 import org.mycore.services.fieldquery.MCRFieldDef;
055 import org.mycore.services.fieldquery.MCRFieldValue;
056 import org.mycore.services.fieldquery.MCRSearcher;
057 import org.mycore.services.fieldquery.MCRSearcherFactory;
058
059 /**
060 * provides static methods to manipulate MCRSearcher indexes.
061 *
062 * @author Thomas Scheffler (yagee)
063 */
064
065 public class MCRSearcherCommands extends MCRAbstractCommands {
066 private static final String INDEX_TYPE_CONTENT = "file";
067
068 private static final String INDEX_TYPE_METADATA = "object";
069
070 private static Logger LOGGER = Logger.getLogger(MCRSearcherCommands.class);
071
072 private static final String SEARCHER_PROPERTY_START = "MCR.Searcher.";
073
074 private static final String SEARCHER_CLASS_SUFFIX = ".Class";
075
076 private static final String SEARCHER_INDEX_SUFFIX = ".Index";
077
078 public MCRSearcherCommands() {
079 super();
080 command.add(new MCRCommand("rebuild metadata index", "org.mycore.frontend.cli.MCRSearcherCommands.repairMetaIndex", "Repairs metadata index"));
081 command.add(new MCRCommand("rebuild content index", "org.mycore.frontend.cli.MCRSearcherCommands.repairContentIndex", "Repairs metadata index"));
082 }
083
084 /**
085 * repairs all metadata indexes
086 *
087 * @throws IOException
088 * @throws JDOMException
089 */
090 public static void repairMetaIndex() throws IOException, JDOMException {
091 List<String> indexes = getIndexes();
092 List<String> metaSearcher = new ArrayList<String>(1);
093 for (String index : indexes) {
094 if (isIndexType(index, INDEX_TYPE_METADATA))
095 metaSearcher.add(index);
096 }
097 for (String searcherID : metaSearcher) {
098 MCRSearcher searcher = MCRSearcherFactory.getSearcher(searcherID);
099 LOGGER.info("clearing index " + searcherID);
100 searcher.clearIndex();
101 searcher.notifySearcher("insert");
102 Session session = MCRHIBConnection.instance().getSession();
103 Criteria xmlCriteria = session.createCriteria(MCRXMLTABLE.class);
104 xmlCriteria.setCacheMode(CacheMode.IGNORE);
105 ScrollableResults results = xmlCriteria.scroll(ScrollMode.FORWARD_ONLY);
106 while (results.next()) {
107 MCRXMLTABLE xmlEntry = (MCRXMLTABLE) results.get(0);
108 if (xmlEntry.getType().equals("derivate"))
109 continue;
110 addMetaToIndex(xmlEntry, false, searcher);
111 session.evict(xmlEntry);
112 }
113 searcher.notifySearcher("finish");
114 LOGGER.info("Done building index " + searcherID);
115 }
116 }
117
118 /**
119 * repairs all content indexes
120 *
121 * @throws IOException
122 * @throws JDOMException
123 */
124 public static void repairContentIndex() throws IOException, JDOMException {
125 List<String> indexes = getIndexes();
126 List<String> contentSearcher = new ArrayList<String>(1);
127 for (String index : indexes) {
128 if (isIndexType(index, INDEX_TYPE_CONTENT))
129 contentSearcher.add(index);
130 }
131 for (String searcherID : contentSearcher) {
132 MCRSearcher searcher = MCRSearcherFactory.getSearcher(searcherID);
133 LOGGER.info("clearing index " + searcherID);
134 searcher.clearIndex();
135 searcher.notifySearcher("insert");
136 Session session = MCRHIBConnection.instance().getSession();
137 Criteria fileCriteria = session.createCriteria(MCRFSNODES.class);
138 fileCriteria.add(Restrictions.eq("type", "F"));
139 fileCriteria.setCacheMode(CacheMode.IGNORE);
140 ScrollableResults results = fileCriteria.scroll(ScrollMode.FORWARD_ONLY);
141 while (results.next()) {
142 MCRFSNODES node = (MCRFSNODES) results.get(0);
143 GregorianCalendar greg = new GregorianCalendar();
144 greg.setTime(node.getDate());
145 MCRFile file = (MCRFile) MCRFileMetadataManager.instance().buildNode(node.getType(), node.getId(), node.getPid(), node.getOwner(),
146 node.getName(), node.getLabel(), node.getSize(), greg, node.getStoreid(), node.getStorageid(), node.getFctid(), node.getMd5(),
147 node.getNumchdd(), node.getNumchdf(), node.getNumchtd(), node.getNumchtf());
148 addFileToIndex(file, false, searcher);
149 session.evict(node);
150 }
151 searcher.notifySearcher("finish");
152 LOGGER.info("Done building index " + searcherID);
153 }
154 }
155
156 private static List<String> getIndexes() {
157 Properties searcherProps = MCRConfiguration.instance().getProperties(SEARCHER_PROPERTY_START);
158 List<String> luceneIndexes = new ArrayList<String>(2);
159 for (Entry<Object, Object> property : searcherProps.entrySet()) {
160 if (property.getKey().toString().endsWith(SEARCHER_CLASS_SUFFIX)) {
161 luceneIndexes.add(property.getKey().toString().split("\\.")[2]);
162 }
163 }
164 LOGGER.info("Found MCRSearcher indexes: " + luceneIndexes);
165 return luceneIndexes;
166 }
167
168 private static boolean isIndexType(String index, String type) throws IOException, JDOMException {
169 Document searchFields = MCRXMLResource.instance().getResource("searchfields.xml");
170 final String indexKey = MCRConfiguration.instance().getString(SEARCHER_PROPERTY_START + index + SEARCHER_INDEX_SUFFIX);
171 for (Object indexElement : searchFields.getRootElement().getChildren("index", MCRConstants.MCR_NAMESPACE)) {
172 final Element indexE = (Element) indexElement;
173 if (indexE.getAttributeValue("id").equals(indexKey))
174 for (Object fieldElement : indexE.getChildren("field", MCRConstants.MCR_NAMESPACE)) {
175 String source = ((Element) fieldElement).getAttributeValue("source");
176 if (source.startsWith(type)) {
177 return true;
178 }
179 }
180 }
181 return false;
182 }
183
184 private static void addMetaToIndex(MCRXMLTABLE xmlEntry, boolean update, MCRSearcher searcher) {
185 List<MCRFieldValue> fields = MCRData2Fields.buildFields(xmlEntry.getXmlByteArray(), searcher.getIndex(), MCRFieldDef.OBJECT_METADATA
186 + MCRFieldDef.OBJECT_CATEGORY, xmlEntry.getType());
187 if (update)
188 searcher.removeFromIndex(xmlEntry.getId());
189 searcher.addToIndex(xmlEntry.getId(), xmlEntry.getId(), fields);
190 }
191
192 private static void addFileToIndex(MCRFile file, boolean update, MCRSearcher searcher) {
193 List<MCRFieldValue> fields = MCRData2Fields.buildFields(file, searcher.getIndex());
194 String entryID = file.getID();
195 String returnID = searcher.getReturnID(file);
196 if (update)
197 searcher.removeFromIndex(entryID);
198 searcher.addToIndex(entryID, returnID, fields);
199 }
200 }