68 Using Asset API: Tutorial

Use this Asset API tutorial as a quick reference. Know that it’s not a substitute for the Java API Reference for Oracle WebCenter Sites. Code samples in this tutorial will help you use the Asset API.

Topics:

68.1 Understanding the Asset API

With the Asset API, you can access and manipulate WebCenter Sites assets. The main purpose of this API is to broaden the context in which you handle assets.

The Asset API is a Java API. Its major features are:

  • The Asset API supports WebCenter Sites in a non-servlet context.

    Before the Asset API, WebCenter Sites exposed primary interfaces for programming in the form of tags (both in XML and JSP), used as the means for creating web pages and applications. In this sense, WebCenter Sites was tightly built around the servlet model and was not usable in other contexts, such as standalone Java programs (EJB, for example). Therefore, there was a need to create an API that could be used anywhere, regardless of the servlet framework.

  • The Asset API unifies the retrieval, creation, and modification of the two asset families: basic and flex.

    • The Asset API represents both asset families with AssetData and AttributeData.

    • The Asset API uses generic Condition and Query objects for both flex and basic assets.

  • The Asset API supports the creation and editing of basic assets, flex assets, and flex parent assets in the form of Java objects.

    Note:

    The Asset API does not log any dependencies other than the asset that is being loaded.

68.2 Primary Interfaces

With the Asset API, you can access data and definitions for WebCenter Sites assets.

The Asset API provides:

  • Package com.fatwire.assetapi.data contains classes that are useful in reading data.

  • Classes under com.fatwire.assetapi.def are for asset definitions.

  • Package com.fatwire.assetapi.query contains constructs necessary for building a Query. See the Java API Reference for Oracle WebCenter Sites.

The Asset API defines the following primary interfaces:

  • Session: The primary entry point into WebCenter Sites from the API. One has to obtain a session to be able to do anything at all in the Asset API.

  • AssetDataManager: A manager for reading asset data. Developers can query for information here, and look up asset associations and other information.

  • AssetTypeDefManager: A manager for reading an asset type's definition. 'Definition' is a loaded term in WebCenter Sites where flex assets are concerned. Here it is used in the generic sense, as something that defines the structure of an asset type. As a result, basic asset types also have a definition.

  • AssetData: An asset's data; basically a collection of AttributeData instances and other information about the asset itself.

  • AssetId: The asset type-ID combination.

  • DimensionableAssetManager: A manager that supports multilingual assets by retrieving translations of any given asset.

68.3 Getting Started

The following are the prerequisites to follow this tutorial:

68.4 Asset API Read

Let's start writing some code based on FSII data.

Topics:

68.4.1 A Simple Example: Reading Field Values

Let's try to read all the values of the FSIIHeadline field in FSII Articles. These are the steps to follow:

  1. Get a session.

  2. Get a handle to AssetDataManager.

  3. Build a query.

  4. Perform 'read' and print the results.

Here is the code that implements these steps (in a jsp element):

<%@ page import="com.fatwire.system.*"%>
<%@ page import="com.fatwire.assetapi.data.*"%>
<%@ page import="com.fatwire.assetapi.query.*"%>
<%@ page import="java.util.*"%>
<cs:ftcs>
<%
Session ses = SessionFactory.getSession();
AssetDataManager mgr =(AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
Query q = new SimpleQuery("Content_C", "FSII Article", null, Collections.singletonList("FSIIHeadline") );
for( AssetData data : mgr.read( q ) )
{
out.println( data.getAttributeData("FSIIHeadline").getData() );
out.println( "<br/>" );
}
%>
</cs:ftcs>
  1. SessionFactory.newSession() builds a session for a given user. From that point on, all data that is read using this session instance is based on the user's ACL permissions. You could also simply call newSession( null, null ) and get a Session that belongs to DefaultReader, an assumed user. WebCenter Sites-powered web applications generally run as this user at runtime. However, error occurs if the incorrect user name and password are specified.
  2. Using the session, get a handle to AssetDataManager.getManager. (The AssetDataManager.class.getName() method does this.)
  3. A Query represents results that are based on the user's search criteria. In this example, we are using a simple version of Query, where we specify the asset type (Content_C) subtype (FSII Article) and the list of attributes to be returned (just FSIIHeadline in this case). We want all assets; therefore the third parameter (which takes Condition instance) is null. For information about how to use Conditions, see Running a Complex Query.
  4. The read() method of AssetDataManager returns an Iterable over AssetData. Each piece of asset data contains an instance of AttributeData against an attribute name. AttributeData.getData() returns the real data of the attribute itself.

68.4.2 Reading AssetId

  • To know the IDs of all these assets, use AssetData.getAssetId() which returns an AssetId instance.

  • To print AssetId, modify the code in A Simple Example: Reading Field Values, as shown below:

    for( AssetData data : mgr.read( q ) )
    {
    AssetId id = data.getAssetId();
    out.println( data.getAttributeData("FSIIHeadline").getData() + " id=" + id );
    out.println( "<br/>" );
    }
    

    The code above prints the following lines (note that AssetId is a composite that contains the id number and type. AssetId.getId() and AssetId.getType() return ID and type separately:

    AudioCo. America Announces H300 series id=Content_C:1114083739888 
    AudioCo. New Portable Media Player Offers Full Video Experience id=Content_C:1114083739926
    AudioCo.'s First Under Water MP3 Player id=Content_C:1114083739951
    ...

68.4.3 Reading Attributes Given the Asset ID

You can also read the attributes of an asset ID (either passed into a template or acquired programmatically).

  • Let's consider an AssetId (Content_C:1114083739888, for example, as shown in the code used in Reading AssetId) and attempt to print the name, description, and FSIIBody using the following code:

    <%@ page import="com.fatwire.system.*"%>
    <%@ page import="com.fatwire.assetapi.data.*"%>
    <%@ page import="com.fatwire.assetapi.query.*"%>
    <%@ page import="java.util.*"%>
    <%@ page import="com.openmarket.xcelerate.asset.*"%>
    <cs:ftcs>
    <%
    Session ses = SessionFactory.getSession();
    AssetDataManager mgr =(AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
    AssetId id = new AssetIdImpl( "Content_C", 1114083739888L );
    List attrNames = new ArrayList();
    attrNames.add( "name" );
    attrNames.add( "description" );
    attrNames.add( "FSIIBody" );
    
    AssetData data = mgr.readAttributes( id, attrNames );
    AttributeData attrDataName = data.getAttributeData( "name" );
    AttributeData attrDataDescr = data.getAttributeData( "description" );
    AttributeData attrDataBody = data.getAttributeData("FSIIBody");
    
    out.println( "name:" + attrDataName.getData() );
    out.println( "<br/>" );
    out.println( "description:" + attrDataDescr.getData() );
    out.println( "<br/>" );
    out.println( "FSII Body:" + attrDataBody.getData() );
    out.println( "<br/>" );
    %>
    </cs:ftcs>
    

    Here, we are indicating which attributes to read for a given ID. As you can see, you can specify basic fields (such as name, description) and flex attributes; both are treated as attributes.

  • Alternatively, you can load all attributes for a given ID by using AssetDataManager.read( List<AssetId> ids). The following code demonstrates how this is done for a single AssetId:

    <%@ page import="com.fatwire.system.*"%>
    <%@ page import="com.fatwire.assetapi.data.*"%>
    <%@ page import="com.fatwire.assetapi.query.*"%>
    <%@ page import="java.util.*"%>
    <%@ page import="com.openmarket.xcelerate.asset.*"%>
    <cs:ftcs>
    <%
    Session ses = SessionFactory.getSession();
    AssetDataManager mgr =(AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
    AssetId id = new AssetIdImpl( "Content_C", 1114083739888L );
    
    Iterable<AssetData> dataItr = mgr.read( Collections.singletonList( id ) );
    
    for( AssetData data : dataItr )
    {
    for(AttributeData atrData : data.getAttributeData() )
    {
    out.println( "<br/>" );
    out.println( "attribute name:" + atrData.getAttributeName() );
    out.println( "data: " + atrData.getData() );
    }
    }
    %>
    </cs:ftcs>
    

68.4.4 Running a Query

A Query specifies the criteria based on which data is looked up.

  • To look up a product whose SKU is iAC-008 use the code below which also prints the name and ID.

    <%@ page import="com.fatwire.system.*"%>
    <%@ page import="com.fatwire.assetapi.data.*"%>
    <%@ page import="com.fatwire.assetapi.query.*"%>
    <%@ page import="java.util.*"%>
    <cs:ftcs>
    <%
    Session ses = SessionFactory.getSession();
    AssetDataManager mgr = (AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
    Condition c = ConditionFactory.createCondition( "FSIISKU", OpTypeEnum.EQUALS, "iAC-008" );
    Query query = new SimpleQuery( "Product_C", "FSII Product", c, Collections.singletonList( "name" ) );
    
    for( AssetData data : mgr.read( query ) )
    {
    AttributeData attrData = data.getAttributeData( "name" );
    out.println( "name:" + attrData.getData() );
    out.println( "<br/>" );
    out.println( "id:" + data.getAssetId() );
    }
    %>
    </cs:ftcs>
    

    Query consists of a Condition, a set of attributes to be returned, and a SortOrder. The example above uses a condition that is built on the FSIISKU attribute value being EQUAL to iAC-008. Just as we did in the previous example, we pass in the list of attribute names we want to be returned in the resulting collection of AssetData.

  • There are some considerations as to what types of attributes can be queried and how. For a complete discussion of different query algorithms, see Query Types.

    In short, some types of queries are possible with one algorithm, but not with the other. Note that this is exactly the behavior we have in the Asset family of tags and AssetSet family of tags. To illustrate this point, say we want to read all products whose price (FSIIPrice) is greater than 179.

    FSIIPrice is of type MONEY. Consulting Table 68-2 in Data Types and Valid Query Operations, we see that the GREATER_THAN operation is allowed for this data type only in the basic/generic algorithm. The following code uses that algorithm to get all products whose price is greater than 179. The choice of query algorithm is made by the highlighted line in the code below:

    <%@ page import="com.fatwire.system.*"%>
    <%@ page import="com.fatwire.assetapi.data.*"%>
    <%@ page import="com.fatwire.assetapi.query.*"%>
    <%@ page import="java.util.*"%>
    
    <cs:ftcs>
    <%
    Session ses = SessionFactory.getSession();
            AssetDataManager mgr = (AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
    Condition c = ConditionFactory.createCondition( "FSIIPrice", OpTypeEnum.GREATER_THAN, 179.0f );
    Query query = new SimpleQuery( "Product_C", "FSII Product", c, Arrays.asList( "name", "FSIIPrice" ) );
    query.getProperties().setIsBasicSearch( true );
    
    for( AssetData data : mgr.read( query ) )
    {
    AttributeData name = data.getAttributeData( "name" );
    AttributeData price = data.getAttributeData( "FSIIPrice" );
    
    out.println( "name:" + name.getData() );
    out.println( "id:" + data.getAssetId() );
    out.println( "price:" + price.getData() );
    
    out.println( "<br/>" );
    }
    %>
    </cs:ftcs>
    

68.4.5 Running a Complex Query

A complex query can be achieved through nested Conditions. According to the choice of query algorithm, the query is subject to the constraints listed in Query Types.

Use the following code to retrieve all the Product_C assets whose FSIIPrice attribute is greater than 179.0 or whose names are like "FSII" or both:

<%@ page import="com.fatwire.system.*"%>
<%@ page import="com.fatwire.assetapi.data.*"%>
<%@ page import="com.fatwire.assetapi.query.*"%>
<%@ page import="java.util.*"%>
<cs:ftcs>
<%
Session ses = SessionFactory.getSession();
AssetDataManager mgr = (AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
Condition c1 = ConditionFactory.createCondition( "FSIIPrice", OpTypeEnum.GREATER_THAN, 179.0f );
Condition c2 = ConditionFactory.createCondition( "name", OpTypeEnum.LIKE, "FSII" );
Condition c = c1.and( c2 ); //c1.or( c2 );


Query query = new SimpleQuery( "Product_C", "FSII Product", c, Arrays.asList( "name", "FSIIPrice" ) );
query.getProperties().setIsBasicSearch( true );

for( AssetData data : mgr.read( query ) )
{
AttributeData name = data.getAttributeData( "name" );
AttributeData price = data.getAttributeData( "FSIIPrice" );

out.println( "name:" + name.getData() );
out.println( "id:" + data.getAssetId() );
out.println( "price:" + price.getData() );

out.println( "<br/>" );
}
%>
</cs:ftcs>

Note:

Make sure that the complex query shows the execution order and is readable.

The example of a correct query where the execution order is clear:

condition finalc = conditionA.and((conditionB).or(conditionC));

The example of an incorrect query where the execution order is not clear:

condition finalc = conditionA.and(conditionB).or(conditionC);

68.4.6 Retrieving the Results by Sorting

You can retrieve the results by sorting on a field, and you can reverse the sort order, as follows:

  • To retrieve the results sorted by price use the following code (specifying a SortOrder, ascending in this example):

    <%@ page import="com.fatwire.system.*"%>
    <%@ page import="com.fatwire.assetapi.data.*"%>
    <%@ page import="com.fatwire.assetapi.query.*"%>
    <%@ page import="java.util.*"%>
    <cs:ftcs>
    <%
    Session ses = SessionFactory.getSession();
            AssetDataManager mgr = (AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
    
    SortOrder so = new SortOrder( "FSIIPrice", true );
    Query query = new SimpleQuery( "Product_C", "FSII Product", 
    null, Collections.singletonList( "FSIIPrice" ), Collections.singletonList( so ) );
    
    for( AssetData data : mgr.read( query ) )
    {
    AttributeData price = data.getAttributeData( "FSIIPrice" );
    
    out.println( "id:" + data.getAssetId() );
    out.println( "price:" + price.getData() );
    
    out.println( "<br/>" );
    }
    %>
    </cs:ftcs>
    
    The above code sorts and prints asset ids and price in the ascending order of FSIIPrice,
    
    id:Product_C:1114083739851 price:89.99
    id:Product_C:1114083739757 price:99.95
    id:Product_C:1114083739696 price:129.99
    id:Product_C:1114083739301 price:129.99
    id:Product_C:1114083739471 price:179.95
    id:Product_C:1114083739350 price:189.95
    id:Product_C:1114083739225 price:399.99
    id:Product_C:1114083739596 price:899.95
    id:Product_C:1114083739804 price:1399.99
    id:Product_C:1114083739549 price:3799.95
    id:Product_C:1114083739663 price:6999.99
    
  • To reverse the sort order, change true to false in the highlighted line of the code above.

68.4.7 Reading BlobObject

The Asset API defines a special class to represent file type of data, data that is stored as a binary file. For example, the FSIIDocumentFile attribute in FirstSiteII is of type blob.

  • Use the following code to read FSIIDocumentFile from all Document_C instances and print the asset ID, file name, and file size:

    <%@ page import="com.fatwire.system.*"%>
    <%@ page import="com.fatwire.assetapi.data.*"%>
    <%@ page import="com.fatwire.assetapi.query.*"%>
    <%@ page import="java.util.*"%>
    <cs:ftcs>
    <%
    Session ses = SessionFactory.getSession();
    AssetDataManager mgr = (AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
    
    Query query = new SimpleQuery( "Document_C", "FSII Document", null, Collections.singletonList( "FSIIDocumentFile" ) );
    
    for( AssetData data : mgr.read( query ) )
    {
    AttributeData docAttr = data.getAttributeData("FSIIDocumentFile");
    BlobObject fileObj = (BlobObject)docAttr.getData();
    byte [] d = new byte[fileObj.getBinaryStream().available()];
    fileObj.getBinaryStream().read(d);
    
    out.println( "id:" + data.getAssetId() );
    out.println( "file name:" + fileObj.getFilename() );
    out.println( "file size:" + d.length );
    
    out.println( "<br/>" );
    }
    %>
    </cs:ftcs>
    

68.4.8 Retrieving Multi-Valued Attributes

The Asset API supports multi-valued attributes in the same way it supports single-valued attributes. AttributeData contains a companion method, getDataAsList() to retrieve multiple values.

Use the following code to print data contained in FSIIKeyword, a multi-valued attribute:

Note:

Because sample data that ships with FirstSiteII does not have data for the FSIIKeyword attribute, this sample code does not print any keywords. Before running this code, edit some FSIIDocument instances to add data for this attribute.

<%@ page import="com.fatwire.system.*"%> 
<%@ page import="com.fatwire.assetapi.data.*"%>
<%@ page import="com.fatwire.assetapi.query.*"%>
<%@ page import="java.util.*"%>
<cs:ftcs>
<%
Session ses = SessionFactory.getSession();
AssetDataManager mgr = (AssetDataManager) ses.getManager( AssetDataManager.class.getName() );

Query query = new SimpleQuery( "Document_C", "FSII Document", 
null, Collections.singletonList( "FSIIKeyword" ) );

for( AssetData data : mgr.read( query ) )
{
AttributeData attrData = data.getAttributeData( "FSIIKeyword" );
List retData = attrData.getDataAsList();
out.println( "id:" + data.getAssetId() );

for( Object o : retData )
{
out.println( "data:" + o );
}

out.println( "<br/>" );
}
%>
</cs:ftcs>

68.4.9 Multilingual Assets: Retrieving Translations

The Asset API also provides interfaces and methods to deal with multilingual assets. Basically, you have methods in DimensionableAssetManager to handle multilingual assets. They deal with getting all the locales for a given asset and specific translation of an asset.

Use the following example to first retrieve the translations for asset Page: 1118867611403 by using the getRelatives method in DimensionableAssetManager with group set to Locale, and then use the getRelative method to get the fr_FR translation of the asset:

<%@ page import="com.fatwire.system.*"%> 
<%@ page import="com.fatwire.assetapi.data.*"%>
<%@ page import="com.fatwire.mda.DimensionableAssetManager"%>
<%@ page import="com.openmarket.xcelerate.asset.*"%>
<%@ page import="java.util.*"%>

<cs:ftcs>
<%
Session ses = SessionFactory.getSession();
DimensionableAssetManager mgr = (DimensionableAssetManager)ses.getManager(DimensionableAssetManager.class.getName());

AssetId page_asset = new AssetIdImpl("Page", 1118867611403L);

for( AssetId id : mgr.getRelatives( page_asset, null, "Locale" ))
{
out.println( id );
}
out.println( "<br/>" );

AssetId fr_translation = mgr.getRelative( page_asset, "fr_FR" );
out.println( fr_translation );

%>
</cs:ftcs>

68.4.10 Reading Asset and Attribute Definitions

In addition to asset data, APIs also provide access to their definitions. Information such as the attributes that make up an asset definition or the type of each attribute can be obtained through a manager called AssetTypeDefManager.

Use the following example to read all definition information from Document_C and print it to the browser:

<%@ page import="com.fatwire.system.*"%>
<%@ page import="com.fatwire.assetapi.def.*"%>
<%@ page import="java.util.*"%>
<%@ page import="com.fatwire.assetapi.query.*"%>
<cs:ftcs>
<%
Session ses = SessionFactory.getSession();
        AssetTypeDefManager mgr = (AssetTypeDefManager) ses.getManager( AssetTypeDefManager.class.getName() );

AssetTypeDef defMgr = mgr.findByName( "Document_C", "FSII Document" );

out.println( "Asset type description: " + defMgr.getDescription() );
out.println( "<br/>" );

for( AttributeDef attrDef : defMgr.getAttributeDefs() )
{
out.println( "Attribute name: " + attrDef.getName() );
out.println( "Attribute description: " + attrDef.getDescription() );
out.println( "is required: " + attrDef.isDataMandatory() );
out.println( "Attribute type: " + attrDef.getType() );
out.println( "<br/>" );
}

%>
</cs:ftcs>

68.4.11 Reading Key-Value Mappings

The Asset API provides access to a given CSElement or template's key-value mapping pairs.

Use the following example to read all mapping pairs from a CSElement:

<%@ page import="com.fatwire.system.*"%>
<%@ page import="com.fatwire.assetapi.data.*"%>
<%@ page import="com.fatwire.assetapi.query.*"%>
<%@ page import="java.util.*"%>
<cs:ftcs>
<%
Session ses = SessionFactory.getSession();
AssetDataManager mgr = (AssetDataManager)(ses.getManager(AssetDataManager.class.getName()));
Condition c = ConditionFactory.createCondition("name", OpTypeEnum.LIKE, "FSIICommon/Nav/LocaleForm");
Query query = new SimpleQuery("CSElement", null, c, null);
query.getProperties().setReadAll(true);
for (AssetData data : mgr.read(query))
{
   List<AttributeData>  mappingArray = (List<AttributeData>)data.getAttributeData("Mapping"). getData();
   for (int i=0; i<mappingArray.size(); i++)
   {
      HashMap mappingMap = (HashMap)mappingArray.get(i).getData();
      String key = (String)((AttributeData)mappingMap.get("key")).getData();
      String type =(String)((AttributeData)mappingMap.get("type")).getData();                   
      String value = (String)((AttributeData)mappingMap.get("value")).getData();
      String siteid = (String)((AttributeData)mappingMap.get("siteid")).getData();     

      out.println("Mapping Entry #"+String.valueOf(i+1));
      out.println("<br/>");
      out.println("Key: "+key);
      out.println("Type: "+type);

out.println("Value: "+value);

      out.println("Siteid: "+siteid);
      out.println("<br/>");
   }
}
%>
</cs:ftcs>

68.5 Asset API Write

With the Asset API, you can perform write operations on basic assets and selected types of flex assets. The write operations are asset creation, modification, and deletion. The status field of an asset gets updated according to the action you perform.

The supported assets are basic assets, flex assets, and flex parents. These asset types are not supported at present: Flex Parent Definition, Flex Asset Definition, Flex Filter, and Flex Attribute. An UnsupportedOperationException is thrown if any write operation (insert or update) is attempted on those asset types.

Topics:

68.5.1 Creating New Assets

Asset API uses the AssetDataManager.insert( List<AssetData> data ) method to create a new asset in WebCenter Sites. The method takes in a list of AssetData and uses these AssetData to create assets in WebCenter Sites. If successful, the method populates the passed in AssetData with the IDs of the newly created assets.

Asset API is able to create a new flex asset by combining the AssetDataManager.newAssetData method and insert method. The newAssetData method returns an empty AssetData with all the AttributeData objects populated with null or empty List/Collection. The flextemplateid (for flex assets) or flexgroupid (for flex parents) is automatically populated if the correct subtype is specified.

  • To create a new flex asset, use the following code:

    <%@ page import="com.fatwire.system.*"%>
    <%@ page import="com.fatwire.assetapi.data.*"%>
    <%@ page import="com.fatwire.assetapi.query.*"%>
    <%@ page import="com.openmarket.xcelerate.asset.AssetIdImpl"%>
    <%@ page import="java.util.*"%>
    <cs:ftcs>
    <%
    Session ses = SessionFactory.getSession();
    AssetDataManager adm = (AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
            MutableAssetData d = adm.newAssetData( "Content_C", "FSII Article" );
            d.getAttributeData( "name" ).setData( New Content" );
            d.getAttributeData( "FSIIHeadline" ).setData( "headline" );
            d.getAttributeData( "FSIIAbstract" ).setData( "abstract" );
            d.getAttributeData( "FSIIBody" ).setData( "body" );
            d.getAttributeData( "Publist" ).setData( Arrays.asList( "FirstSiteII" ) );
            d.setParents( Arrays.<AssetId>asList( new AssetIdImpl( "Content_P", 1112192431478L)) );
            adm.insert( Arrays.<AssetData>asList( d ));
            out.println( d.getAssetId() );        
    %>
    </cs:ftcs>
    
  • Asset API is also capable of creating new basic assets. To create a new basic asset, use the following code:

    <%@ page import="com.fatwire.system.*"%>
    <%@ page import="com.fatwire.assetapi.data.*"%>
    <%@ page import="com.fatwire.assetapi.query.*"%>
    <%@ page import="java.util.*"%>
    <cs:ftcs>
    <%
    Session ses = SessionFactory.getSession();
    AssetDataManager adm = (AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
            MutableAssetData d = adm.newAssetData( "HelloArticle", "" );
            d.getAttributeData( "name" ).setData( New Hello Article" );
            d.getAttributeData( "headline" ).setData( "headline" );
            d.getAttributeData( "byline" ).setData( "abstract" );
            d.getAttributeData( "category" ).setData( "g" );
            BlobObject b = new BlobObjectImpl( "filename.txt", null, "body".getBytes() );
            d.getAttributeData( "urlbody" ).setData( b );
            d.getAttributeData( "Publist" ).setData( Arrays.asList( "HelloAssetWorld" ) );
            adm.insert( Arrays.<AssetData>asList( d ));
            out.println( d.getAssetId() );
    %>
    </cs:ftcs>
    
  • You can create a new Content_C asset of subtype FSIIArticle and set myAPItestvanity.html as its vanity URL with the FSII webroot and an HTTP response code of 200, as shown in this example:
    <%@ page import="com.fatwire.system.*"%> 
    <%@ page import="com.fatwire.assetapi.data.*"%> 
    <%@ page import="com.fatwire.assetapi.query.*"%> 
    <%@ page import="com.openmarket.xcelerate.asset.AssetIdImpl"%> 
    <%@ page import="java.util.*"%> 
    <cs:ftcs> 
    <% 
    Session ses = SessionFactory.getSession(); 
    AssetDataManager adm = (AssetDataManager) ses.getManager( 
    AssetDataManager.class.getName() ); 
            MutableAssetData d = adm.newAssetData( "Content_C", "FSII Article" ); 
            d.getAttributeData( "name" ).setData( "New Content" ); 
            d.getAttributeData( "FSIIHeadline" ).setData( "headline" ); 
            d.getAttributeData( "FSIIAbstract" ).setData( "abstract" ); 
            d.getAttributeData( "FSIIBody" ).setData( "body" ); 
            d.getAttributeData( "Publist" ).setData( Arrays.asList( "FirstSiteII" 
     ) ); 
            d.setParents( Arrays.<AssetId>asList( new AssetIdImpl( "Content_P", 
     1112192431478L)) ); 
    . 
            //Retrieve a AttributeData reference to the asset's Webreference 
     attribute containing a list of vanity urls for the asset 
           AttributeData webReferenceAttrData = 
     d.getAttributeData("Webreference"); 
           
           //Create new Vanity URL for this asset.   
           // Specify the follwing: 
       //String webroot: the name of the webroot to use 
       //String url: the vanity url 
       //Integer httpstatus: the http response code 
       //Long patternid: id of WebReferencesPatterns entry. 0 for urls not created 
     from pattern. 
       //boolean flag: indicates whether this the default vanity url for this 
     asset 
       //String template: SiteCatalog path for Template 
       //String wrapper: SiteCatalog path for Wrapper 
           WebReference vanityURL = new WebReferenceImpl("FSII", 
     "myAPItestvanity.html", new Integer("200"), 0L, 
     true,"FirstSiteII/FSIILayout","FSIIWrapper"); 
     . 
           //Set tthe asset's WebReference data attribute with the updated list: 
           
     webReferenceAttrData.setDataAsList(Arrays.<WebReference>asList(vanityURL)); 
           
           //Save the asset 
            adm.insert( Arrays.<AssetData>asList( d )); 
            out.println( d.getAssetId()+"<br/>");         
     . 
     %> 
    </cs:ftcs> 

68.5.2 Updating Existing Assets

Another operation that Asset API supports, in addition to insert, is update. Similar to insert, update saves the data from AssetData into WebCenter Sites, but to an existing asset. If the asset does not exist, then the update operation throws an exception.

To update existing assets, use the following code:

<%@ page import="com.openmarket.xcelerate.asset.AssetIdImpl"%>
<%@ page import="com.fatwire.system.*"%>
<%@ page import="com.fatwire.assetapi.data.*"%>
<%@ page import="com.fatwire.assetapi.query.*"%>
<%@ page import="java.util.*"%>
<cs:ftcs>
<%
Session ses = SessionFactory.getSession();
AssetDataManager adm = (AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
Iterable<AssetData> assets = adm.read( Arrays.<AssetId>asList( new AssetIdImpl( "HelloArticle", 1238171255471L), new AssetIdImpl( "Content_C", 1238171254486L)) );
        List<AssetData> sAssets = new ArrayList<AssetData>();
        for ( AssetData a : assets )
        {
            sAssets.add( a );
            a.getAttributeData( "name" ).setData( "Changed Name" );
        }
        adm.update( sAssets ); 
%>
</cs:ftcs>

68.5.3 Deleting Existing Assets

AssetAPI also supports deletion of assets from WebCenter Sites.

Use the following code to delete assets from WebCenter Sites.

After removing all the references to the two assets, adm.delete can delete both assets from WebCenter Sites. An exception is thrown if an asset is referenced by other assets, or if the asset is invalid. The delete process stops when an exception is thrown.

<%@ page import="com.openmarket.xcelerate.asset.AssetIdImpl"%>
<%@ page import="com.fatwire.system.*"%>
<%@ page import="com.fatwire.assetapi.data.*"%>
<%@ page import="com.fatwire.assetapi.query.*"%>
<%@ page import="java.util.*"%>
<cs:ftcs>
<%
 Session ses = SessionFactory.getSession();
 AssetDataManager adm = (AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
 adm.delete( Arrays.<AssetId>asList( new AssetIdImpl( "HelloArticle", 1238171255471L), new AssetIdImpl( "Content_C", 1238171254486L)) );
%>
</cs:ftcs>

68.5.4 Multilingual Assets

Asset API supports the creation of multilingual assets. Creation of the assets requires a two-step process. First, the asset is created and saved. Next, locale information is added.

Use the following example to create a new Content_C asset and set the locale to en_US.

<%@ page import="com.fatwire.system.*"%>
<%@ page import="com.fatwire.assetapi.data.*"%>
<%@ page import="com.fatwire.mda.*"%>
<%@ page import="com.fatwire.mda.DimensionableAssetInstance.
                 DimensionParentRelationship"%>
<%@ page import="java.util.*"%>
<%@ page import="com.openmarket.xcelerate.asset.*"%>
<%@ page import="com.openmarket.xcelerate.common.*"%>
<cs:ftcs>

<%
Session ses = SessionFactory.getSession();

AssetDataManager adm = (AssetDataManager) ses.getManager( AssetDataManager.class.getName() );
MutableAssetData d = adm.newAssetData( "Content_C", "FSII Article" );
d.getAttributeData( "name" ).setData( New Content" );
d.getAttributeData( "FSIIHeadline" ).setData( "headline" );
d.getAttributeData( "FSIIAbstract" ).setData( "abstract" );
d.getAttributeData( "FSIIBody" ).setData( "body" );
d.getAttributeData( "Publist" ).setData( Arrays.asList( "FirstSiteII" ) );
d.setParents( Arrays.<AssetId>asList( new AssetIdImpl( "Content_P", 1112192431478L)) );
adm.insert( Arrays.<AssetData>asList( d ));
DimensionManager dam = (DimensionManager)ses.getManager(DimensionManager.class.getName());
Dimension dim = dam.loadDimension("en_US");
d.getAttributeData("Dimension") .setData(Arrays.asList(new Dimension[]{dim}));
DimensionParentRelationship dpr = new DimParentRelationshipImpl("Locale", d.getAssetId());
d.getAttributeData("Dimension-parent").setData(Arrays.asList(new DimensionParentRelationship[]{dpr}));
adm.update( Arrays.<AssetData>asList( d ));
%>
</cs:ftcs>

68.6 Development Strategies

In this topic you will learn about data types and attribute data (maps WebCenter Sites data types to Java types) and query types (compares types of queries, their usage, and supported operations). AttributeData includes information about the WebCenter Sites-specific data type and the actual data. Using the Asset API, you can perform generic/basic and flex queries. The query that you run may have restrictions on what type of operation you can perform for a given data type.

Topics:

68.6.1 Data Types and Attribute Data

AttributeData contains information about the data type (WebCenter Sites specific type) and the actual data. The types are defined by AttributeTypeEnum. AttributeData.getData() and AttributeData.getDataAsList() return data objects of a specific Java type.

This table maps WebCenter Sites types to their corresponding Java types.

Table 68-1 WebCenter Sites Data Types and Java Types

WebCenter Sites Data Type Java Type

INT

Integer

FLOAT

Double

STRING

String

DATE

Date

MONEY

Double

LONG

Long

LARGE_TEXT

String

ASSET

AssetId

BLOB

BlobObject

68.6.2 Query Types

Using the Asset API, you can perform two kinds of queries: generic/basic and flex.

There are two different algorithms, one using the generic asset infrastructure (generic/basic query), and the other using AssetSets and Search States (flex query). Note that it is possible to use the generic/basic query for flex assets and basic assets; flex query, however, works only for flex assets.

Each of these algorithms has its advantages and disadvantages. The Asset API seeks to unify the querying mechanism and eventually let the API user not be concerned about the choice of algorithm. However, at the present time as there is no equivalence between these algorithms, the user needs to specify if she wants to use a specific feature, offered by one of the two.

QueryProperties.setIsBasicSearch( true ) sets the query algorithm to generic/basic search for this query. It is set to false by default. For basic assets, the setting does not matter.

Which type of query to choose? Very simply put, to look for basic attributes of a flex asset, use the basic. Otherwise use the default. This works for most queries one generally encounters. Things are a bit more subtle than that. Given below are other considerations for each type of query.

Basic/Generic Query

  • Cannot search on flex attributes if you do not specify subtype.

  • Cannot search on a flex attribute that is not in the flex definition.

  • Cannot sort on a flex attribute.

  • Case sensitivity is not guaranteed (depends on the database).

  • Only the AND operation is allowed between different fields (name=name1 AND description=descr1 is allowed, but name=name1 AND name=name2 is not).

  • Only OR is allowed for two conditions involving the same field name. The OR condition does not work on flex attributes.

Flex Query

  • Cannot have basic attributes in the condition (id, name, description, and so on).

  • Cannot sort by basic attributes.

  • Flex query works without a subtype being specified. The search applies to data of all subtypes.

  • Can use only the following operands in the condition: LIKE, EQUALS, BETWEEN, and RICHTEXT.

68.6.3 Data Types and Valid Query Operations

Depending on the type of query being performed, there are further restrictions on what type of operation is allowed for a given data type.

In general, a flex type query (which is the default for flex assets) allows only the following OpTypeEnums; LIKE, EQUALS, BETWEEN, and RICHTEXT. Note that these are the same operations available from AssetSet/SearchState tags.

To use other OpTypeEnums, you have to use basic/generic query (by setting QueryProperties.setIsBasicSearch( true )). Such a query, of course, has to adhere to the basic query rules above.

This table shows the allowed set of operations per data type (single-valued or multi-valued) for a basic/generic query.

Table 68-2 Allowed Set of Operations

Data Type EQUALS NOT_EQUALS LIKE GREATER LESSTHAN BETWEEN RICHTEXT

INT

Y

Y

N

Y

Y

N

FLOAT

Y

Y

N

Y

Y

N

STRING

Y

Y

Y

Y

Y

N

DATE

Y

Y

N

Y

Y

N

MONEY

Y

Y

N

Y

Y

N

LONG

Y

Y

N

Y

Y

N

LARGE_TEXT

N

N

Y

N

N

N

ASSET

Y

Y

N

N

N

N

BLOB

N

N

N

N

N

N

The following table shows the allowed set of operations per data type (single-valued or multi-valued) for the flex type query.

Table 68-3 Allowed Set of Operations per Data Type

Data Type EQUALS NOT_EQUALS LIKE GREATER LESS THAN BETWEEN RICHTEXT

INT

Y

N

Y

N

FLOAT

Y

N

Y

N

STRING

Y

Y

Y

N

DATE

Y

N

Y

N

MONEY

Y

N

Y

N

LONG

Y

N

Y

N

LARGE_TEXT

N

Y

N

Y

ASSET

Y

N

Y

N

BLOB

N

N

N

Y

68.7 Optional: Setting Up to Use the Asset API from Standalone Java Programs

You can use the Asset API from JSP templates and also from a standalone Java program. When you want to use this API from a Java program, set up a single database connection or a connection pool outside WebCenter Sites.

Note:

In the following steps, we assume that all components are local to your WebCenter Sites installation.

Before setting up a single database connection or pool:

  1. Make sure the following files are in the classpath of your Java program:

    • javaee.jar and tools.jar (both are available in JDK 1.5 and higher versions).

    • ServletRequest.properties. This file can be copied from the WEB-INF/classes folder.

    • SSOConfig.xml, given that your WebCenter Sites installation has WEM installed and single sign-on (in wcs_properties.json) is set to true. The SSOConfig.xml file can be copied from the WEB-INF/classes folder.

    • cs-cache.xml, ss-cache.xml, linked-cache.xml, and cas-cache.xml.

    • SitesSecurityContext.xml. This file can be copied from the WEB-INF/classes folder.

    • All of the WebCenter Sites binary files (jar files in the WEB-INF/lib folder).

  2. Continue with the steps in one of the following sections:

To set up a single database connection:

  1. Set the following system properties for your Java program:

    cs.dburl=<JDBC_URL_to_connect_to_DB>
    cs.dbdriver=<driverClass>
    cs.dbuid=<dbUserName>
    cs.dbpwd=<dbPassword>
    
  2. Locate the WebCenter Sites installation folder and pass its name as a JVM argument:

    -Dcs.installDir=<install_dir>
    

To set up a database connection pool:

  1. Add the following jar files to the classpath: commons-dbcp.jar (which ships with WebCenter Sites) and commons-pool.jar (available from the Apache website).
  2. Create the property file with the same name as your data source:

    Note the following:

    • The name of the data source is the value of the cs.dsn property (in wcs_properties.json).

    • The value of cs.dbconnpicture (also in wcs_properties.json) must refer to cs.dsn (the combination of cs.dbconnpicture and cs.dsn must yield a valid resource).

      For example, the combination of

      cs.dsn= csDataSource and

      cs.dbconnpicture= java\:comp/env/$dsn

      yields a valid resource:

      java:/csDataSource

      Therefore, you would name the property file csDataSource.properties (the value of cs.dsn).

    • When creating the property file, make sure to place it in the classpath of your Java program.

  3. When the property file is created, add the following keys to the file:
    driver=<driverClass>
    url=<JDBC_URL_to_connect_to_DB>
    maxconnections=<number_of_connections_to_pool>
    user=<dbUserName>
    password=<dbPassword>
    
  4. Locate the WebCenter Sites installation folder and pass its name as a JVM argument:
    -Dcs.installDir=<install_dir>