001 /**
002 * $RCSfile: MCRClassificationMigrationHelper.java,v $ $Revision: 1.0 $ $Date: 07.07.2008 09:11:45 $ This file is part of ** M y C o R e ** Visit our homepage
003 * at http://www.mycore.de/ for details. This program is free software; you can use it, redistribute it and / or modify it under the terms of the GNU General
004 * Public License (GPL) as published by the Free Software Foundation; either version 2 of the License or (at your option) any later version. This program is
005 * 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
006 * PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program,
007 * normally in the file license.txt. If not, write to the Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
008 **/
009 package org.mycore.services.migration;
010
011 import java.net.URISyntaxException;
012 import java.util.Collection;
013 import java.util.Date;
014 import java.util.HashSet;
015 import java.util.List;
016
017 import org.apache.log4j.Logger;
018 import org.hibernate.Criteria;
019 import org.hibernate.Session;
020 import org.hibernate.criterion.Projections;
021 import org.hibernate.criterion.Restrictions;
022 import org.jdom.Document;
023 import org.jdom.Element;
024 import org.jdom.JDOMException;
025 import org.jdom.xpath.XPath;
026
027 import org.mycore.backend.hibernate.MCRHIBConnection;
028 import org.mycore.backend.hibernate.tables.MCRLINKHREF;
029 import org.mycore.datamodel.classifications2.MCRCategLinkService;
030 import org.mycore.datamodel.classifications2.MCRCategLinkServiceFactory;
031 import org.mycore.datamodel.classifications2.MCRCategory;
032 import org.mycore.datamodel.classifications2.MCRCategoryDAO;
033 import org.mycore.datamodel.classifications2.MCRCategoryDAOFactory;
034 import org.mycore.datamodel.classifications2.MCRCategoryID;
035 import org.mycore.datamodel.classifications2.MCRObjectReference;
036 import org.mycore.datamodel.classifications2.utils.MCRXMLTransformer;
037 import org.mycore.datamodel.common.MCRXMLTableManager;
038 import org.mycore.datamodel.metadata.MCRObjectID;
039
040 public class MCRClassificationMigrationHelper {
041 static final MCRCategoryDAO DAO = MCRCategoryDAOFactory.getInstance();
042
043 private static final MCRXMLTableManager XML_TABLE = MCRXMLTableManager.instance();
044
045 private static final MCRCategLinkService CATAG_LINK_SERVICE = MCRCategLinkServiceFactory.getInstance();
046
047 private static Logger LOGGER = Logger.getLogger(MCRClassificationMigrationHelper.class);
048
049 static void createCategories() throws URISyntaxException {
050 List<String> classIds = MCRXMLTableManager.instance().retrieveAllIDs("class");
051 LOGGER.info("Migrating classifications and categories...");
052 for (String classID : classIds) {
053 MCRObjectID objID = new MCRObjectID(classID);
054 Document cl = MCRXMLTableManager.instance().readDocument(objID);
055 MCRCategory cat = MCRXMLTransformer.getCategory(cl);
056 DAO.addCategory(null, cat);
057 MCRXMLTableManager.instance().delete(objID);
058 }
059 }
060
061 @SuppressWarnings("unchecked")
062 static void migrateCategoryLinks() throws JDOMException {
063 LOGGER.info("Migrating object links....");
064 XPath classSelector = XPath.newInstance("/mycoreobject/metadata/*[@class='MCRMetaClassification']/*");
065 LOGGER.debug("Retrieving all relevant objects IDs.");
066 List<String> objIDs = getAllObjectIDsForCategories();
067 int objectsTotal = objIDs.size();
068 LOGGER.debug(objectsTotal + "object IDs retrieved");
069
070 // pass through found objects
071 int pos = 0;
072 long startTime = System.currentTimeMillis();
073 Session session = MCRHIBConnection.instance().getSession();
074 for (String id : objIDs) {
075 pos++;
076 LOGGER.debug("Processing object " + id);
077 Collection<MCRCategoryID> categories = new HashSet<MCRCategoryID>();
078 if (XML_TABLE.exist(new MCRObjectID(id))) {
079 LOGGER.debug("Parsing XML of object " + id);
080 Document obj = XML_TABLE.readDocument(new MCRObjectID(id));
081 LOGGER.debug("executing XPATH " + classSelector.getXPath());
082 List<Element> classElements = classSelector.selectNodes(obj);
083 int categoryCount = classElements.size();
084 LOGGER.debug("found " + categoryCount + " category ids");
085 for (Element el : classElements) {
086 String clid = el.getAttributeValue("classid");
087 String catid = el.getAttributeValue("categid");
088 categories.add(new MCRCategoryID(clid, catid));
089 }
090 if (categories.size() > 0) {
091 LOGGER.debug("updating references");
092 String type = id.substring(id.indexOf("_") + 1, id.lastIndexOf("_") - 1);
093 MCRObjectReference objectReference = new MCRObjectReference(id, type);
094 try {
095 CATAG_LINK_SERVICE.setLinks(objectReference, categories);
096 } catch (Exception e) {
097 LOGGER.error("Error occured while creating category links for object " + id, e);
098 }
099 }
100 if (pos % 100 == 0 || pos == objectsTotal) {
101 long currentTime = System.currentTimeMillis();
102 long finishTime = currentTime + ((currentTime - startTime) * (objectsTotal - pos) / pos);
103 LOGGER.info((100d * (double) pos / (double) objectsTotal) + " % (" + pos + "/" + objectsTotal + "), estimated finish time is "
104 + new Date(finishTime));
105 //flush a batch of inserts and release memory:
106 session.flush();
107 session.clear();
108 }
109 } else
110 LOGGER.warn("Object " + id + " linked to category, but it is not in database.");
111 }
112 }
113
114 static void deleteOldCategoryLinks() {
115 LOGGER.info("Deleting old object links...");
116 final Session session = MCRHIBConnection.instance().getSession();
117 int deleted = session.createQuery("DELETE FROM MCRLINKHREF WHERE key.mcrtype='classid'").executeUpdate();
118 LOGGER.info(deleted + " object links deleted.");
119 }
120
121 @SuppressWarnings("unchecked")
122 private static List<String> getAllObjectIDsForCategories() {
123 Session session = MCRHIBConnection.instance().getSession();
124 Criteria c = session.createCriteria(MCRLINKHREF.class);
125 c.setProjection(Projections.distinct(Projections.property("key.mcrfrom")));
126 c.add(Restrictions.eq("key.mcrtype", "classid"));
127 return c.list();
128 }
129
130 }