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    }