blob: 857fda13204e66fe77443b1f3ba4a7747932f228 [file] [log] [blame]
/*
* 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.vinci.transport.document;
import java.io.IOException;
import org.apache.vinci.transport.Attributes;
import org.apache.vinci.transport.Frame;
import org.apache.vinci.transport.FrameComponent;
import org.apache.vinci.transport.FrameLeaf;
import org.apache.vinci.transport.ServiceDownException;
import org.apache.vinci.transport.ServiceException;
import org.apache.vinci.transport.Transportable;
import org.apache.vinci.transport.TransportableFactory;
import org.apache.vinci.transport.VNSException;
import org.apache.vinci.transport.VinciClient;
import org.apache.vinci.transport.VinciFrame;
import org.apache.vinci.transport.util.TransportableConverter;
/**
* This class is a VinciFrame with extensions for support of XML attributes.
*
* This class provides a set of "aadd" decorator methods that are almost exactly the same as the
* "fadd" methods of the Frame class, except they return an empty set of attributes that can then be
* populated. See the "main()" method for an example of how to use this class to easily create
* documents with attributes.
*/
public class AFrame extends VinciFrame {
private Attributes a = null;
public void setAttributes(Attributes s) {
a = s;
}
public Attributes getAttributes() {
return a;
}
public Attributes createAttributes() {
if (a == null) {
a = new Attributes();
}
return a;
}
private static TransportableFactory aFrameFactory = new TransportableFactory() {
public Transportable makeTransportable() {
return new AFrame();
}
};
/**
* Get a TransportableFactory that creates new AFrames.
* @return -
*/
static public TransportableFactory getAFrameFactory() {
return aFrameFactory;
}
public AFrame() {
this(10);
}
/**
* @pre capacity ≥ 0
* @param capacity -
*/
public AFrame(int capacity) {
super(capacity);
}
/**
* Create an AFrame that is a (deep) copy of the given transportable.
*
* @pre t != null
* @param t -
* @return -
*/
public static AFrame toAFrame(Transportable t) {
return (AFrame) TransportableConverter.convert(t, getAFrameFactory());
}
/**
* Override the createSubFrame to create an AFrame of precise capacity.
*
* @pre tag_name != null
* @pre initialCapacity ≥ 0
*/
public Frame createSubFrame(String tag_name, int initialCapacity) {
return new AFrame(initialCapacity);
}
/**
* Override the createFrameLeaf to create an AFrameLeaf so that leaf values can have attributes.
*
* @pre array != null
*/
public FrameLeaf createFrameLeaf(byte[] array) {
return new AFrameLeaf(array, false);
}
/**
* Convenience method for fetching sub-frames when their type is known to be AFrame
*
* @param key
* The key identifying the value to retrieve.
* @exception ClassCastException
* if the value was not of type AFrame.
* @return The requested value, or null if the specified key does not exist.
*
* @pre key != null
*/
public AFrame fgetAFrame(String key) {
return (AFrame) fgetFirst(key);
}
/**
* Get the attributes associated with a particular key. If there is more than one matching key,
* then the attributes of only the first matching key are returned.
*
* @param key
* The key whose attributes to fetch.
* @return The (possibly empty) set of attributes associated with the key, or null (which
* indicates no such key).
*
* @pre key != null
*/
public Attributes aget(String key) {
FrameComponent comp = fgetFirst(key);
if (comp != null) {
Attributes not_null = comp.getAttributes();
if (not_null == null) {
return new Attributes();
} else {
return not_null;
}
}
return null;
}
/**
* Decorator method for adding float-valued tags.
*
* @param key
* The key to be associated with the value.
* @param val -
* @return The (empty) set of attributes associated with the added key.
*
* @pre key != null
*/
public Attributes aadd(String key, float val) {
AFrameLeaf l = new AFrameLeaf(val);
add(key, l);
return l.createAttributes();
}
/**
* Decorator method for adding float-array valued tags.
*
* @param key
* The key to be associated with the value.
* @param val -
* @return The (empty) set of attributes associated with the added key.
*
* @pre key != null
*/
public Attributes aadd(String key, float[] val) {
if (val != null) {
AFrameLeaf l = new AFrameLeaf(val);
add(key, l);
return l.createAttributes();
}
return null;
}
/**
* Decorator method for adding double valued tags.
*
* @param key
* The key to be associated with the value.
* @param val -
* @return The (empty) set of attributes associated with the added key.
*
* @pre key != null
*/
public Attributes aadd(String key, double val) {
AFrameLeaf l = new AFrameLeaf(val);
add(key, l);
return l.createAttributes();
}
/**
* Decorator method for adding double-array valued tags.
*
* @param key
* The key to be associated with the value.
* @param val
* The array to add. The array is immediately converted to string representation.
* @return The (empty) set of attributes associated with the added key.
*
* @pre key != null
*/
public Attributes aadd(String key, double[] val) {
if (val != null) {
AFrameLeaf l = new AFrameLeaf(val);
add(key, l);
return l.createAttributes();
}
return null;
}
/**
* Decorator method for adding int valued tags.
*
* @param key
* The key to be associated with the value.
* @param val
* The int to add.
* @return The (empty) set of attributes associated with the key.
*
* @pre key != null
*/
public Attributes aadd(String key, int val) {
AFrameLeaf l = new AFrameLeaf(val);
add(key, l);
return l.createAttributes();
}
/**
* Decorator method for adding int-array valued tags.
*
* @param key
* The key to be associated with the value.
* @param val
* The array to add. The array is immediately converted to string representation.
* @return The set of attributes associated with the key.
*
* @pre key != null
*/
public Attributes aadd(String key, int[] val) {
if (val != null) {
AFrameLeaf l = new AFrameLeaf(val);
add(key, l);
return l.createAttributes();
}
return null;
}
/**
* Decorator method for adding long valued tags.
*
* @param key
* The key to be associated with the value.
* @param val
* The long value to add.
* @return The (empty) set of attributes associated with the key.
*
* @pre key != null
*/
public Attributes aadd(String key, long val) {
AFrameLeaf l = new AFrameLeaf(val);
add(key, l);
return l.createAttributes();
}
/**
* Decorator method for adding long-array valued tags.
*
* @param key
* The key to be associated with the value.
* @param val
* The array to add. The array is immediately converted to string representation.
* @return The (empty) set of attributes associated with the key.
*
* @pre key != null
*/
public Attributes aadd(String key, long[] val) {
if (val != null) {
AFrameLeaf l = new AFrameLeaf(val);
add(key, l);
return l.createAttributes();
}
return null;
}
/**
* Decorator method for adding String valued tags.
*
* @param key
* The key to be associated with the value.
* @param val
* The string to add.
* @return The (empty) set of attributes associated with the added key.
*
* @pre key != null
*/
public Attributes aadd(String key, String val) {
if (val != null) {
AFrameLeaf l = new AFrameLeaf(val);
add(key, l);
return l.createAttributes();
}
return null;
}
/**
* Decorator method for adding binary valued tags. Encodes the data in Base64.
*
* @param key
* The key to be associated with the value.
* @param val
* The data to be encoded and added to this frame.
* @return The (empty) set of attributes associated with the added key.
*
* @pre key != null
*/
public Attributes aadd(String key, byte[] val) {
if (val != null) {
AFrameLeaf l = new AFrameLeaf(val, true);
add(key, l);
return l.createAttributes();
}
return null;
}
/**
* Decorator method for adding boolean valued tags.
*
* @param key
* The key to be associated with the value.
* @param val
* The boolean value to add.
* @return The (empty) set of attributes associated with the added key.
*
* @pre key != null
*/
public Attributes aadd(String key, boolean val) {
AFrameLeaf l = new AFrameLeaf(val);
add(key, l);
return l.createAttributes();
}
/**
* Decorator method for adding Frame-valued tags.
*
* @param key
* The key to be associated with the value.
* @param val
* The sub-frame to add. Note this frame is not copied.
* @return The (empty) set of attributes associated with the added key.
*
* @pre key != null
*/
public Attributes aadd(String key, AFrame val) {
if (val != null) {
add(key, val);
return val.createAttributes();
}
return null;
}
/**
* Decorator method for adding a valueless tag.
*
* @param key
* The key name.
* @return The (empty) set of attributes associated with the added key.
*
* @pre key != null
*/
public Attributes aadd(String key) {
AFrame sub = new AFrame(0);
add(key, sub);
return sub.createAttributes();
}
/**
* This is a hack method which allows you to add binary-valued tags to Frames in a manner such
* that there is no textual encoding overhead of that binary data. This is NOT necessarily
* XTalk-1.0 compatible which formally requires only UTF-8, but it still works. Binary data added
* using this method can be retrieved using QueryableFrame/VinciFrame getter method
* fgetTrueBinary(String).
*
* WARNING: if the default XTalk parser is replaced with another one, applications that depend on
* this method may break!
*
* NOTE: This method should only be used when performance hit of Base64 encoding binary data [as
* performed by aadd(String, byte[])] is unacceptable.
*
* @param key
* The key to be associated with the value.
* @param val
* The byte array to be added to the frame. Note the array is NOT copied or converted in
* any way.
* @return The (empty) set of attributes associated with the added key.
*
* @pre key != null
*/
public Attributes aaddTrueBinary(String key, byte[] val) {
if (val != null) {
AFrameLeaf l = new AFrameLeaf(val, false);
add(key, l);
return l.createAttributes();
}
return null;
}
/**
* @pre in != null
* @pre service_name != null
*
* @param in -
* @param service_name -
* @return -
* @throws IOException -
* @throws ServiceException -
* @throws ServiceDownException -
* @throws VNSException -
* @throws IllegalStateException
* if VNS_HOST is not specified.
*/
static public AFrame rpc(Transportable in, String service_name) throws IOException,
ServiceException, ServiceDownException, VNSException {
return (AFrame) VinciClient.sendAndReceive(in, service_name, getAFrameFactory());
}
/**
* @pre in != null
* @pre service_name != null
* @pre socket_timeout ≥ 0
*
* @param in -
* @param service_name -
* @param socket_timeout -
* @return -
* @throws IOException -
* @throws ServiceException -
* @throws ServiceDownException -
* @throws VNSException -
* @throws IllegalStateException
* if VNS_HOST is not specified.
*/
static public AFrame rpc(Transportable in, String service_name, int socket_timeout)
throws IOException, ServiceException, ServiceDownException, VNSException {
return (AFrame) VinciClient
.sendAndReceive(in, service_name, getAFrameFactory(), socket_timeout);
}
/**
* @pre in != null
* @pre service_name != null
* @pre socket_timeout ≥ 0
*
* WARNING: This method relies on JDK-1.4 specific functions. USE IT ONLY if you don't need to
* maintain JDK1.3 compatability.
*
* @param in -
* @param service_name -
* @param socket_timeout -
* @param connect_timeout -
* @return -
* @throws IOException -
* @throws ServiceException -
* @throws ServiceDownException -
* @throws VNSException -
* @throws IllegalStateException
* if VNS_HOST is not specified.
*/
static public AFrame rpc(Transportable in, String service_name, int socket_timeout,
int connect_timeout) throws IOException, ServiceException, ServiceDownException,
VNSException {
return (AFrame) VinciClient.sendAndReceive(in, service_name, getAFrameFactory(),
socket_timeout, connect_timeout);
}
/*
* public static void main(String[] args) { // EXAMPLE of creating a document with attributes.
* AFrame f = new AFrame(); f.setAttributes((Attributes)new Attributes().fadd("foo", "bar")); //
* Once we create the empty AFrame, we can call "aadd" to add a key/value pair and // retrieve an
* empty set of attributes that we can then populate with attributes that will // be associated
* with the just-added key. Note that the attribute list object is itself a // special type of
* VinciFrame, thus we can use the standard "fadd()" methods to create the // attribute list.
* f.aadd("KEY", "value1") // Add XML element and retrieve the attribute list object
* .fadd("attr1", "aval1") // Add an attribute for the tag. .fadd("attr2", "aval2") // Add another
* attribute for the tag. .fadd("attr3", "you get the point");
* // Note that with fadd() you can potentially create a duplicate attribute (an XML no-no), //
* so the "idiot proof" method is to instead use fset(): f.aadd("VALUELESS_KEY") // Add a
* valueless tag that has a couple of attributes .fset("foo", "bar") .fset("foo2", 2) .fset("foo",
* "replaced bar");
* // Here's how to create a nested AFrame: AFrame nested = new AFrame();
* nested.aadd("NESTED_KEY", 1234.567) .fadd("nested", "attribute"); f.aadd("NESTED_FRAME",
* nested) .fadd("attributename", new int[] {1,2,3});
* // We can use either fadd() or aadd() to add attributeless tags, though fadd is // preferrable
* since it avoids creating the attributes object. nested.fadd("ATTRIBUTELESS_KEY", "done with
* fadd()"); nested.aadd("ANOTHER_ATTRIBUTELESS_KEY", "done with aadd()");
*
* System.out.println(f.toXML()); System.out.println();
* // Querying key values: String foo_value = f.aget("VALUELESS_KEY").fgetString("foo");
* System.out.println("Attribute value of foo from VALUELESS_KEY: " + foo_value);
* System.out.println("TEST: " + toAFrame(f).toXML()); }
*/
}