org.wso2.carbon.registry.extensions.handlers.utils.ConflictResolutionReader.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.registry.extensions.handlers.utils.ConflictResolutionReader.java

Source

/*
 * Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * 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.wso2.carbon.registry.extensions.handlers.utils;

import org.apache.axiom.om.OMContainer;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.util.AXIOMUtil;
import org.apache.axiom.om.xpath.AXIOMXPath;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jaxen.JaxenException;
import org.wso2.carbon.registry.core.LogEntry;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.exceptions.RegistryException;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import java.io.IOException;
import java.io.Reader;
import java.util.*;

public class ConflictResolutionReader extends Reader {
    private static final Log log = LogFactory.getLog(ConflictResolutionReader.class);

    private static final String XPATH_EXPRESSION = "//lastModified";

    private Reader reader;
    private StringBuffer buffer;
    private String path;
    private Registry registry;

    public ConflictResolutionReader(Reader reader, String path, Registry registry) {
        this.reader = reader;
        this.path = path;
        this.registry = registry;
        buffer = new StringBuffer();
    }

    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {
        int retValue;

        retValue = reader.read(cbuf, off, len);
        if (retValue != -1) {
            buffer.append(cbuf);
        } else {
            checkForConflicts();
        }

        return retValue;
    }

    @Override
    public int read() throws IOException {
        int ret;

        ret = reader.read();
        if (ret != -1) {
            buffer.append((char) ret);
        } else {
            checkForConflicts();
        }

        return ret;
    }

    private void checkForConflicts() throws IOException {
        try {
            OMElement restoreElement = AXIOMUtil.stringToOM(buffer.toString());
            restoreElement.build();
            AXIOMXPath xpathQuery = new AXIOMXPath(XPATH_EXPRESSION);
            List lastModifiedTimes = xpathQuery.selectNodes(restoreElement);

            Collections.sort(lastModifiedTimes, new Comparator<OMElement>() {
                public int compare(OMElement o1, OMElement o2) {
                    long o1Value = Long.parseLong(o1.getText());
                    long o2Value = Long.parseLong(o2.getText());

                    if (o1Value < o2Value) {
                        return 1;
                    } else if (o1Value > o2Value) {
                        return -1;
                    } else {
                        return 0;
                    }
                }
            });

            long maxTimeValue = getMaxTimeElement(lastModifiedTimes);

            LogEntry[] logs = registry.getLogs(null, LogEntry.ALL, null, new Date(maxTimeValue), null, true);

            Arrays.sort(logs, new Comparator<LogEntry>() {
                public int compare(LogEntry o1, LogEntry o2) {
                    return o2.getResourcePath().compareTo(o1.getResourcePath());
                }
            });

            for (LogEntry logEntry : logs) {
                if (logEntry.getResourcePath().startsWith(path)) {
                    final String msg = "Another user has modified the content of the resource " + path;
                    log.error(msg);
                    throw new IOException(msg);
                }
            }

        } catch (XMLStreamException e) {
            log.error("Error reading the restore file", e);
        } catch (JaxenException e) {
            log.error("Failed to initialize the Xpath", e);
        } catch (RegistryException e) {
            log.error("Unable to get logs from registry", e);
        }
    }

    /*
    Checking to see whether the version field is 0
    This is done to identify the newly added resources
    */
    private long getMaxTimeElement(List lastUpdateTimes) {
        for (Object lastUpdateTime : lastUpdateTimes) {
            OMElement maxTimeElement = (OMElement) lastUpdateTime;
            OMContainer parentElement = maxTimeElement.getParent();
            OMElement versionChild;
            if ((versionChild = parentElement.getFirstChildWithName(new QName("version"))) != null) {
                if (Integer.parseInt(versionChild.getText()) > 0) {
                    return Long.parseLong(maxTimeElement.getText());
                }
            }
        }
        return Long.MIN_VALUE;
    }

    @Override
    public void close() throws IOException {
        reader.close();
    }

    @Override
    public void reset() throws IOException {
        reader.reset();
    }
}