alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 * 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.commons.jxpath.ri.model.beans;

import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.JXPathException;
import org.apache.commons.jxpath.ri.QName;
import org.apache.commons.jxpath.ri.model.NodePointer;

/**
 * @author Dmitri Plotnikov
 * @version $Revision: 1.18 $ $Date: 2004/03/25 03:49:50 $
 */
public class NullPropertyPointer extends PropertyPointer {

    private String propertyName = "*";
    private boolean byNameAttribute = false;

    /**
     */
    public NullPropertyPointer(NodePointer parent) {
        super(parent);
    }

    public QName getName() {
        return new QName(propertyName);
    }

    public void setPropertyIndex(int index) {
    }

    public int getLength() {
        return 0;
    }

    public Object getBaseValue() {
        return null;
    }

    public Object getImmediateNode() {
        return null;
    }

    public boolean isLeaf() {
        return true;
    }    

    public NodePointer getValuePointer() {
        return new NullPointer(this,  new QName(getPropertyName()));
    }

    protected boolean isActualProperty() {
        return false;
    }

    public boolean isActual() {
        return false;
    }

    public boolean isContainer() {
        return true;
    }

    public void setValue(Object value) {
        if (parent == null || parent.isContainer()) {
            throw new JXPathException(
                "Cannot set property "
                    + asPath()
                    + ", the target object is null");
        }
        else if (parent instanceof PropertyOwnerPointer &&
                ((PropertyOwnerPointer) parent).
                    isDynamicPropertyDeclarationSupported()){
            // If the parent property owner can create
            // a property automatically - let it do so
            PropertyPointer propertyPointer =
                ((PropertyOwnerPointer) parent).getPropertyPointer();
            propertyPointer.setPropertyName(propertyName);
            propertyPointer.setValue(value);
        }
        else {
            throw new JXPathException(
                "Cannot set property "
                    + asPath()
                    + ", path does not match a changeable location");
        }
    }

    public NodePointer createPath(JXPathContext context) {
        NodePointer newParent = parent.createPath(context);
        if (isAttribute()) {
            return newParent.createAttribute(context, getName());
        }
        else {
            // Consider these two use cases:
            // 1. The parent pointer of NullPropertyPointer is 
            //    a PropertyOwnerPointer other than NullPointer. When we call 
            //    createPath on it, it most likely returns itself. We then
            //    take a PropertyPointer from it and get the PropertyPointer
            //    to expand the collection for the corresponsing property.
            //
            // 2. The parent pointer of NullPropertyPointer is a NullPointer.
            //    When we call createPath, it may return a PropertyOwnerPointer
            //    or it may return anything else, like a DOMNodePointer.
            //    In the former case we need to do exactly what we did in use 
            //    case 1.  In the latter case, we simply request that the 
            //    non-property pointer expand the collection by itself.
            if (newParent instanceof PropertyOwnerPointer) {
                PropertyOwnerPointer pop = (PropertyOwnerPointer) newParent;
                newParent = pop.getPropertyPointer();
            }
            return newParent.createChild(context, getName(), getIndex());
        }
    }

    public NodePointer createPath(JXPathContext context, Object value) {
        NodePointer newParent = parent.createPath(context);
        if (isAttribute()) {
            NodePointer pointer = newParent.createAttribute(context, getName());
            pointer.setValue(value);
            return pointer;
        }
        else {
            if (newParent instanceof PropertyOwnerPointer) {
                PropertyOwnerPointer pop = (PropertyOwnerPointer) newParent;
                newParent = pop.getPropertyPointer();
            }
            return newParent.createChild(context, getName(), index, value);
        }
    }
    
    public NodePointer createChild(
            JXPathContext context,
            QName name, 
            int index)
    {
        return createPath(context).createChild(context, name, index);
    }
        
    public NodePointer createChild(
            JXPathContext context,
            QName name, 
            int index,
            Object value) 
    {
        return createPath(context).createChild(context, name, index, value);
    }

    public String getPropertyName() {
        return propertyName;
    }

    public void setPropertyName(String propertyName) {
        this.propertyName = propertyName;
    }

    public void setNameAttributeValue(String attributeValue) {
        this.propertyName = attributeValue;
        byNameAttribute = true;
    }

    public boolean isCollection() {
        return getIndex() != WHOLE_COLLECTION;
    }

    public int getPropertyCount() {
        return 0;
    }

    public String[] getPropertyNames() {
        return new String[0];
    }

    public String asPath() {
        if (!byNameAttribute) {
            return super.asPath();
        }
        else {
            StringBuffer buffer = new StringBuffer();
            buffer.append(getImmediateParentPointer().asPath());
            buffer.append("[@name='");
            buffer.append(escape(getPropertyName()));
            buffer.append("']");
            if (index != WHOLE_COLLECTION) {
                buffer.append('[').append(index + 1).append(']');
            }
            return buffer.toString();
        }
    }

    private String escape(String string) {
        int index = string.indexOf('\'');
        while (index != -1) {
            string =
                string.substring(0, index)
                    + "'"
                    + string.substring(index + 1);
            index = string.indexOf('\'');
        }
        index = string.indexOf('\"');
        while (index != -1) {
            string =
                string.substring(0, index)
                    + """
                    + string.substring(index + 1);
            index = string.indexOf('\"');
        }
        return string;
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.