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
andAttributeData
. -
The Asset API uses generic
Condition
andQuery
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:
-
FirstSiteII (FSII) is required to run the examples in this tutorial. The
tools.jar
file (available in JDK 1.5 and above) must be in the classpath.Note:
The Asset API can be used from a standalone Java program. Doing so requires some configuration. See Optional: Setting Up to Use the Asset API from Standalone Java Programs.
-
Working through the examples in this chapter requires a knowledge of
jsp
elements and how they are created in the WebCenter Sites environment. See Creating Template, CSElement, and SiteEntry Assets.
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:
-
Get a session.
-
Get a handle to
AssetDataManager
. -
Build a query.
-
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>
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 callnewSession( null, null )
and get a Session that belongs toDefaultReader
, 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.- Using the session, get a handle to
AssetDataManager.getManager
. (TheAssetDataManager.class.getName()
method does this.) - A
Query
represents results that are based on the user's search criteria. In this example, we are using a simple version ofQuery
, where we specify the asset type (Content_C
) subtype (FSII Article
) and the list of attributes to be returned (justFSIIHeadline
in this case). We want all assets; therefore the third parameter (which takesCondition
instance) isnull
. For information about how to useConditions
, see Running a Complex Query. - The
read()
method ofAssetDataManager
returns anIterable
overAssetData
. Each piece of asset data contains an instance ofAttributeData
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 anAssetId
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 theid
number and type.AssetId.getId()
andAssetId.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 singleAssetId
:<%@ 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 aCondition
, a set of attributes to be returned, and aSortOrder
. The example above uses a condition that is built on theFSIISKU
attribute value beingEQUAL
toiAC-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 ofAssetData
. -
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 andAssetSet
family of tags. To illustrate this point, say we want to read all products whose price (FSIIPrice
) is greater than 179.FSIIPrice
is of typeMONEY
. Consulting Table 68-2 in Data Types and Valid Query Operations, we see that theGREATER_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
tofalse
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 allDocument_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, butname=name1 AND name=name2
is not). -
Only
OR
is allowed for two conditions involving the same field name. TheOR
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
, andRICHTEXT
.
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:
-
Make sure the following files are in the classpath of your Java program:
-
javaee.jar
andtools.jar
(both are available in JDK 1.5 and higher versions). -
ServletRequest.properties
. This file can be copied from theWEB-INF/classes
folder. -
SSOConfig.xml
, given that your WebCenter Sites installation has WEM installed and single sign-on (inwcs_properties.json
) is set totrue
. TheSSOConfig.xml
file can be copied from theWEB-INF/classes
folder. -
cs-cache.xml
,ss-cache.xml
,linked-cache.xml
, andcas-cache.xml
. -
SitesSecurityContext.xml
. This file can be copied from theWEB-INF/classes
folder. -
All of the WebCenter Sites binary files (
jar
files in theWEB-INF/lib
folder).
-
-
Continue with the steps in one of the following sections:
To set up a single database connection:
-
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>
-
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: