Package org.fcrepo.server.journal.xmlhelpers

Source Code of org.fcrepo.server.journal.xmlhelpers.ContextXmlReader

/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package org.fcrepo.server.journal.xmlhelpers;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;

import org.fcrepo.server.MultiValueMap;
import org.fcrepo.server.journal.JournalException;
import org.fcrepo.server.journal.entry.JournalEntryContext;
import org.fcrepo.server.journal.helpers.JournalHelper;
import org.fcrepo.server.journal.helpers.PasswordCipher;


/**
* Reads a Context tag from the journal file, and assembles a
* JournalEntryContext from it.
*
* @author Jim Blake
*/
public class ContextXmlReader
        extends AbstractXmlReader {

    private String passwordType;

    /**
     * Read the context tax and populate a JournalEntryContext object.
     */
    public JournalEntryContext readContext(XMLEventReader reader)
            throws JournalException, XMLStreamException {
        JournalEntryContext context = new JournalEntryContext();

        XMLEvent event = reader.nextTag();
        if (!isStartTagEvent(event, QNAME_TAG_CONTEXT)) {
            throw getNotStartTagException(QNAME_TAG_CONTEXT, event);
        }

        context.setPassword(readContextPassword(reader));
        context.setNoOp(readContextNoOp(reader));
        context.setNow(readContextNow(reader));
        context
                .setEnvironmentAttributes(readMultiMap(reader,
                                                       CONTEXT_MAPNAME_ENVIRONMENT));
        context.setSubjectAttributes(readMultiMap(reader,
                                                  CONTEXT_MAPNAME_SUBJECT));
        context
                .setActionAttributes(readMultiMap(reader,
                                                  CONTEXT_MAPNAME_ACTION));
        context.setResourceAttributes(readMultiMap(reader,
                                                   CONTEXT_MAPNAME_RESOURCE));
        context.setRecoveryAttributes(readMultiMap(reader,
                                                   CONTEXT_MAPNAME_RECOVERY));

        event = reader.nextTag();
        if (!isEndTagEvent(event, QNAME_TAG_CONTEXT)) {
            throw getNotEndTagException(QNAME_TAG_CONTEXT, event);
        }

        decipherPassword(context);

        return context;
    }

    /**
     * Read the context password from XML. Note: While doing this, fetch the
     * password type, and store it to use when deciphering the password. Not the
     * cleanest structure, perhaps, but it will serve for now.
     */
    private String readContextPassword(XMLEventReader reader)
            throws JournalException, XMLStreamException {
        XMLEvent startTag = readStartTag(reader, QNAME_TAG_PASSWORD);
        passwordType =
                getOptionalAttributeValue(startTag.asStartElement(),
                                          QNAME_ATTR_PASSWORD_TYPE);
        return readCharactersUntilEndTag(reader, QNAME_TAG_PASSWORD);
    }

    /**
     * Read the context no-op flag from XML.
     */
    private boolean readContextNoOp(XMLEventReader reader)
            throws XMLStreamException, JournalException {
        readStartTag(reader, QNAME_TAG_NOOP);
        String value = readCharactersUntilEndTag(reader, QNAME_TAG_NOOP);
        return Boolean.valueOf(value).booleanValue();
    }

    /**
     * Read the context date from XML.
     */
    private Date readContextNow(XMLEventReader reader)
            throws XMLStreamException, JournalException {
        readStartTag(reader, QNAME_TAG_NOW);
        String value = readCharactersUntilEndTag(reader, QNAME_TAG_NOW);
        return JournalHelper.parseDate(value);
    }

    /**
     * Read a multi-map, with its nested tags.
     */
    private MultiValueMap readMultiMap(XMLEventReader reader, String mapName)
            throws JournalException, XMLStreamException {
        MultiValueMap map = new MultiValueMap();

        // must start with a multi-map tag
        XMLEvent event = reader.nextTag();
        if (!isStartTagEvent(event, QNAME_TAG_MULTI_VALUE_MAP)) {
            throw getNotStartTagException(QNAME_TAG_MULTI_VALUE_MAP, event);
        }

        // the map name must match the expected name
        String value =
                getRequiredAttributeValue(event.asStartElement(),
                                          QNAME_ATTR_NAME);
        if (!mapName.equals(value)) {
            throw new JournalException("Expecting a '" + mapName
                    + "' multi-map, but found a '" + value
                    + "' multi-map instead");
        }

        // populate the map
        readMultiMapKeys(reader, map);

        return map;
    }

    /**
     * Read through the keys of the multi-map, adding to the map as we go.
     */
    private void readMultiMapKeys(XMLEventReader reader, MultiValueMap map)
            throws XMLStreamException, JournalException {
        while (true) {
            XMLEvent event2 = reader.nextTag();
            if (isStartTagEvent(event2, QNAME_TAG_MULTI_VALUE_MAP_KEY)) {
                // if we find a key tag, get the name
                String key =
                        getRequiredAttributeValue(event2.asStartElement(),
                                                  QNAME_ATTR_NAME);
                // read as many values as we find.
                String[] values = readMultiMapValuesForKey(reader);
                // store in the map
                storeInMultiMap(map, key, values);
            } else if (isEndTagEvent(event2, QNAME_TAG_MULTI_VALUE_MAP)) {
                break;
            } else {
                throw getNotNextMemberOrEndOfGroupException(QNAME_TAG_MULTI_VALUE_MAP,
                                                            QNAME_TAG_MULTI_VALUE_MAP_KEY,
                                                            event2);
            }
        }
    }

    /**
     * Read the list of values for one key of the multi-map.
     */
    private String[] readMultiMapValuesForKey(XMLEventReader reader)
            throws XMLStreamException, JournalException {
        List<String> values = new ArrayList<String>();
        while (true) {
            XMLEvent event = reader.nextTag();
            if (isStartTagEvent(event, QNAME_TAG_MULTI_VALUE_MAP_VALUE)) {
                values
                        .add(readCharactersUntilEndTag(reader,
                                                       QNAME_TAG_MULTI_VALUE_MAP_VALUE));
            } else if (isEndTagEvent(event, QNAME_TAG_MULTI_VALUE_MAP_KEY)) {
                return values.toArray(new String[values.size()]);
            } else {
                throw getNotNextMemberOrEndOfGroupException(QNAME_TAG_MULTI_VALUE_MAP_KEY,
                                                            QNAME_TAG_MULTI_VALUE_MAP_VALUE,
                                                            event);
            }
        }
    }

    /**
     * This method is just to guard against the totally bogus Exception
     * declaration in MultiValueMap.set()
     */
    private void storeInMultiMap(MultiValueMap map, String key, String[] values)
            throws JournalException {
        try {
            map.set(key, values);
        } catch (Exception e) {
            // totally bogus Exception here.
            throw new JournalException(e);
        }
    }

    /**
     * The password as read was not correct. It needs to be deciphered.
     */
    private void decipherPassword(JournalEntryContext context) {
        String key = JournalHelper.formatDate(context.now());
        String passwordCipher = context.getPassword();
        String clearPassword =
                PasswordCipher.decipher(key, passwordCipher, passwordType);
        context.setPassword(clearPassword);
    }

}
TOP

Related Classes of org.fcrepo.server.journal.xmlhelpers.ContextXmlReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.