Package org.apache.jackrabbit.spi2davex

Source Code of org.apache.jackrabbit.spi2davex.ItemInfoJsonHandler

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.jackrabbit.spi2davex;

import org.apache.jackrabbit.commons.json.JsonHandler;
import org.apache.jackrabbit.spi.ChildInfo;
import org.apache.jackrabbit.spi.IdFactory;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.NodeId;
import org.apache.jackrabbit.spi.NodeInfo;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.spi.PathFactory;
import org.apache.jackrabbit.spi.PropertyId;
import org.apache.jackrabbit.spi.QValue;
import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
import org.apache.jackrabbit.util.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

/**
* <code>ItemInfoJSONHandler</code>...
*/
class ItemInfoJsonHandler implements JsonHandler {

    private static Logger log = LoggerFactory.getLogger(ItemInfoJsonHandler.class);

    private static final int SPECIAL_JSON_PAIR = Integer.MAX_VALUE;

    private final List itemInfos;
    private final NamePathResolver resolver;
    private final String rootURI;

    private final QValueFactoryImpl vFactory;
    private final PathFactory pFactory;
    private final IdFactory idFactory;

    private Name name;
    private int propertyType;
    private int index = Path.INDEX_DEFAULT;

    private Stack nodeInfos = new Stack();
    private PropertyInfoImpl mvPropInfo;

    ItemInfoJsonHandler(NamePathResolver resolver, NodeInfo nInfo,
                        String rootURI,
                        QValueFactoryImpl vFactory,
                        PathFactory pFactory,
                        IdFactory idFactory) {
        this.resolver = resolver;
        this.rootURI = rootURI;

        this.vFactory = vFactory;
        this.pFactory = pFactory;
        this.idFactory = idFactory;

        itemInfos = new ArrayList();
        itemInfos.add(nInfo);
        nodeInfos.push(nInfo);
    }

    public void object() throws IOException {
        if (name != null) {
            try {
                NodeInfo current = getCurrentNodeInfo();
                Path relPath = pFactory.create(name, index);
                NodeId id = idFactory.createNodeId(current.getId(), relPath);
                Path currentPath = current.getPath();
                Path p = pFactory.create(currentPath, relPath, true);
                NodeInfo nInfo = new NodeInfoImpl(id, p);
                nodeInfos.push(nInfo);
                itemInfos.add(nInfo);
            } catch (RepositoryException e) {
                throw new IOException(e.getMessage());
            }
        }
    }

    public void endObject() throws IOException {
        try {
            NodeInfoImpl nInfo = (NodeInfoImpl) nodeInfos.pop();
            NodeInfo parent = getCurrentNodeInfo();
            if (parent != null) {
                if (nInfo.getPath().getAncestor(1).equals(parent.getPath())) {
                    ChildInfo ci = new ChildInfoImpl(nInfo.getName(), nInfo.getUniqueID(), nInfo.getIndex());
                    ((NodeInfoImpl) parent).addChildInfo(ci);
                } else {
                    log.debug("NodeInfo '"+ nInfo.getPath() + "' out of hierarchy. Parent path = " + parent.getPath());
                }
            }
            if (!nInfo.isCompleted()) {
                log.debug("Incomplete NodeInfo '"+ nInfo.getPath() + "' -> Only present as ChildInfo with its parent.");
                itemInfos.remove(nInfo);
            }
        } catch (RepositoryException e) {
            throw new IOException(e.getMessage());
        }
    }

    public void array() throws IOException {
        try {
            mvPropInfo = createPropertyInfo(null, true);
        } catch (RepositoryException e) {
            throw new IOException(e.getMessage());
        }
    }

    public void endArray() throws IOException {
        try {
            // make sure that type is set for mv-properties with empty value array.
            if (propertyType == PropertyType.UNDEFINED &&
                    mvPropInfo.numberOfValues() == 0) {
                int type = vFactory.retrieveType(getValueURI());
                mvPropInfo.setType(type);
            }
            mvPropInfo.checkCompleted();
            getCurrentNodeInfo().addPropertyInfo(mvPropInfo, idFactory);
            mvPropInfo = null;
        } catch (RepositoryException e) {
            throw new IOException(e.getMessage());
        }
    }

    public void key(String key) throws IOException {
        try {
            if (key.equals("::NodeIteratorSize")) {
                propertyType = SPECIAL_JSON_PAIR;
                // TODO: if additional JSON pairs are created -> set name
            } else if (key.startsWith(":")) {
                // binary property
                name = resolver.getQName(key.substring(1));
                propertyType = PropertyType.BINARY;
                index = Path.INDEX_DEFAULT;
            } else if (key.endsWith("]")) {
                // sns-node name
                int pos = key.lastIndexOf('[');
                name = resolver.getQName(key.substring(0, pos));
                propertyType = PropertyType.UNDEFINED;
                index = Integer.parseInt(key.substring(pos + 1, key.length() - 1));
            } else {
                // either node or property
                Name previousName = name;
                name = resolver.getQName(key);
                propertyType = guessPropertyType(name, previousName);
                // property type is defined through json value OR special property
                // :propertyName = type.
                index = Path.INDEX_DEFAULT;
            }
        } catch (RepositoryException e) {
            throw new IOException(e.getMessage());
        }
    }

    public void value(String value) throws IOException {
        try {
            QValue v;
            switch (propertyType) {
                case SPECIAL_JSON_PAIR:
                    // currently no special boolean value pair -> ignore
                    return;
                case PropertyType.BINARY:
                    // key started with ':' but value is String instead of
                    // long. value therefore reflects the property type.
                    // -> reset the property type.
                    // -> omit creation of value AND call to value(QValue)
                    propertyType = PropertyType.valueFromName(value);
                    return;
                case PropertyType.UNDEFINED:
                    v = vFactory.create(value, PropertyType.STRING);
                    break;
                case PropertyType.NAME:
                    v = vFactory.create(resolver.getQName(value));
                    break;
                case PropertyType.PATH:
                    v = vFactory.create(resolver.getQPath(value));
                    break;
                default:
                    v = vFactory.create(value, propertyType);
            }
            value(v);
        } catch (RepositoryException e) {
            throw new IOException(e.getMessage());
        }
    }

    public void value(boolean value) throws IOException {
        if (propertyType == SPECIAL_JSON_PAIR) {
            // currently no special boolean value pair -> ignore
            return;
        }
        try {
            value(vFactory.create(value));
        } catch (RepositoryException e) {
            throw new IOException(e.getMessage());
        }
    }

    public void value(long value) throws IOException {
        if (propertyType == SPECIAL_JSON_PAIR) {
            NodeInfoImpl parent = getCurrentNodeInfo();
            if (parent != null) {
                parent.setNumberOfChildNodes(value);
            }
            return;
        }
        try {
            QValue v;
            if (propertyType == PropertyType.BINARY) {
                int indx = (mvPropInfo == null) ? -1 : mvPropInfo.numberOfValues();
                v = vFactory.create(value, getValueURI(), indx);
            } else {
                v = vFactory.create(value);
            }
            value(v);
        } catch (RepositoryException e) {
            throw new IOException(e.getMessage());
        }
    }

    public void value(double value) throws IOException {
        if (propertyType == SPECIAL_JSON_PAIR) {
            // currently no special double value pair -> ignore
            return;
        }
        try {
            value(vFactory.create(value));
        } catch (RepositoryException e) {
            throw new IOException(e.getMessage());
        }
    }

    //--------------------------------------------------------------------------
    /**
     *
     * @param value
     * @throws RepositoryException
     */
    private void value(QValue value) throws RepositoryException {
        if (mvPropInfo == null) {
            createPropertyInfo(value, false);
        } else {
            mvPropInfo.addValue(value);
        }
    }

    Iterator getItemInfos() {
        return Collections.unmodifiableList(itemInfos).iterator();
    }

    private NodeInfoImpl getCurrentNodeInfo() {
        return  (nodeInfos.isEmpty()) ? (NodeInfoImpl) null : (NodeInfoImpl) nodeInfos.peek();
    }

    private PropertyInfoImpl createPropertyInfo(QValue value, boolean isMultiValued) throws RepositoryException {
        NodeInfoImpl parent = getCurrentNodeInfo();
        Path p = pFactory.create(parent.getPath(), name, true);
        PropertyId id = idFactory.createPropertyId(parent.getId(), name);

        PropertyInfoImpl pInfo;
        if (isMultiValued) {
            pInfo = new PropertyInfoImpl(id, p, propertyType);
            // not added to parent but upon having read all values.
        } else {
            pInfo = new PropertyInfoImpl(id, p, propertyType, value);
            parent.addPropertyInfo(pInfo, idFactory);
        }
        itemInfos.add(pInfo);
        return pInfo;
    }

    private String getValueURI() throws RepositoryException {
        Path propertyPath;
        if (mvPropInfo == null) {
            propertyPath = pFactory.create(getCurrentNodeInfo().getPath(), name, true);
        } else {
            propertyPath = mvPropInfo.getPath();
        }
        StringBuffer sb = new StringBuffer(rootURI);
        sb.append(Text.escapePath(resolver.getJCRPath(propertyPath)));
        return sb.toString();
    }

    private int guessPropertyType(Name name, Name previousName) {
        if (name.equals(previousName)) {
            // property has been previously retrieved from :name : "typeName"
            // entry in the JSON string. if by coincidence the previous key
            // is equal but belongs to an JSON object (-> node) the prop type
            // has been reset to UNDEFINED anyway.
            return propertyType;
        } else {
            // default: determine type upon Property.getType() only.
            return PropertyType.UNDEFINED;
        }
    }
}
TOP

Related Classes of org.apache.jackrabbit.spi2davex.ItemInfoJsonHandler

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.