/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/store/org/apache/slide/store/tamino/tools/repairer/UniqueContentIdCheck.java,v 1.4 2004/12/15 10:38:27 pnever Exp $
 * $Revision: 1.4 $
 * $Date: 2004/12/15 10:38:27 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * 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.
 */


package org.apache.slide.store.tamino.tools.repairer;

import java.util.*;

import org.apache.slide.content.NodeProperty;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.store.tamino.common.IContent;
import org.apache.slide.store.tamino.common.XContent;
import org.apache.slide.store.tamino.common.XGlobals;
import org.apache.slide.store.tamino.jdomobjects.XDescriptors;
import org.apache.slide.store.tamino.tools.stores.XStore;
import org.apache.slide.store.tamino.tools.stores.XStoreGroup;
import org.apache.slide.util.XException;

/**
 ** Test the uniqueness of uri entries in the WebDAV meta data information.
 **
 ** @author    Hardy.Kiefer@softwareag.com
 ** @author    Peter.Nevermann@softwareag.com
 ** @version   $Revision: 1.4 $
 **/
public class UniqueContentIdCheck extends AbstractCheck implements RepairConstants {
    
    XStoreGroup group;
    
    /**
     ** Creates a test to find not unique uri's in meta data.
     **
     ** @pre        (taminoClient != null)
     **
     ** @param      taminoClient       the current database session
     **/
    protected UniqueContentIdCheck(XStoreGroup group, XTaminoClient taminoClient) throws XException {
        super(taminoClient, MSG_START_DUPLICATE_CONTENT_IDS, MSG_DESCR_DUPLICATE_CONTENT_IDS);
        this.group = group;
    }
    
    
    /**
     * This method finds all not uniqueness of uris and content ids.
     */
    public void check() throws XException {
        Map allContentIds;
        Map usageMap; //  contentId -> List of descriptorsId
        Iterator iter;
        Map.Entry e;
        String descId;
        String contentId;
        List users;
        
        List patchesToApply = new ArrayList();
        allContentIds = taminoClient.getDescriptorsAccessor().queryAllContentIds( taminoCollection ); // inoId -> contentId
        usageMap = new HashMap(); // contentId -> list(inoId's)
        iter = allContentIds.entrySet().iterator();
        while ( iter.hasNext() ) {
            e = (Map.Entry)iter.next();
            descId = (String)e.getKey();
            contentId = (String)e.getValue();
            if( !XGlobals.EMPTY_CONTENT_ID.equals(contentId) ) {
                users = (List) usageMap.get(contentId);
                if (users == null) {
                    users = new ArrayList();
                    usageMap.put(contentId, users);
                }
                users.add(descId);
                if (users.size() > 1) {
                    // try to read the content
                    // logAndApplyPatch(new CopyContent(group.getMainStore(), descId, contentId));
                    patchesToApply.add(new CopyContent(group.getMainStore(), descId, contentId));
                }
            }
        }
        // apply patches
        Iterator pit = patchesToApply.iterator();
        while (pit.hasNext()) {
            Patch p = (Patch)pit.next();
            logAndApplyPatch(p);
        }
    }
    
    public static class CopyContent extends Patch {
        XStore store;
        String descriptorsId;
        String contentId;
        
        
        public CopyContent(XStore store, String descriptorsId, String contentId) {
            this.store = store;
            this.descriptorsId = descriptorsId;
            this.contentId = contentId;
        }
        
        public void apply(XTaminoClient taminoClient) throws XException {
            NodeRevisionNumber nrn = new NodeRevisionNumber();
            XDescriptors desc = taminoClient.getDescriptorsAccessor().readDescriptorsByIno(descriptorsId);
            NodeRevisionDescriptor nrd = desc.getRevisionDescriptor(nrn);
            IContent contentToCopy = taminoClient.getContentAccessor().readContent(contentId);
            contentToCopy = new XContent(contentToCopy.getContent(), nrd);
            contentToCopy.setContentId(contentId);
            
            IContent result = taminoClient.writeContent(store, contentToCopy);
            String newContentId = result.getContentId();
            
            taminoClient.setContentId(newContentId, nrd);
            nrd.setContentLength (result.getLength());
            nrd.setLastModified (new Date());
            nrd.removeProperty (XGlobals.IS_XML, XGlobals.TAMINO_NAMESPACE_URI);
            NodeProperty isXmlProp =
                new NodeProperty (XGlobals.IS_XML,
                                  new Boolean (result.getIsXml()),
                                  XGlobals.TAMINO_NAMESPACE_URI);
            isXmlProp.setKind (NodeProperty.Kind.PROTECTED);
            nrd.setProperty (isXmlProp);
            
            desc.setReadOnly(false);
            desc.removeRevisionDescriptor(nrd);
            desc.setRevisionDescriptor(nrd);
            taminoClient.getDescriptorsAccessor().update(desc);
        }
        
        public void log(XRepairLogWriter logWriter) {
            String msg = MSG_FOUND_DUPLICATE_CONTENTID;
            msg += "; content will be cloned";
            logWriter.println(TC_CHECK_DETAILS, msg, new Object[] {contentId, descriptorsId} );
        }
    }
}




