Exporting by Reference As mentioned previously, the default behavior for Encrypting Personalization Data Example To encrypt personalization data in your

7-60 Oracle Fusion Middleware Developers Guide for Oracle Portal throw new ProviderExceptionioe; } } Transforms the input data to its original form, in a single operation, using the DES cryptographic algorithm along with a statically defined secret key. param toDecode the input data. return a decoded form of the input data. throws ProviderException if an error occurs during transform. public final byte[] decodebyte[] toDecode throws ProviderException { try { Cipher c = Cipher.getInstanceDES; c.initCipher.DECRYPT_MODE, getSecretKey; return c.doFinaltoDecode; } catch GeneralSecurityException gse { throw new ProviderExceptiongse; } catch IOException ioe { throw new ProviderExceptionioe; } } Returns a codejavax.crypto.SecretKeycode deserialized from the obuscated form in sEncodedKey. Note, this is highly insecure private SecretKey getSecretKey throws GeneralSecurityException, IOException { if mKey == null { DESKeySpec ks = new DESKeySpecnew BASE64Decoder.decodeBuffer sEncodedKey; SecretKeyFactory skf = SecretKeyFactory.getInstanceDES; mKey = skf.generateSecretks; } return mKey; } } 2. Modify your provider.xml to reference the cipher manager: ?xml version = 1.0 encoding = UTF-8? ?providerDefinition version=3.1? provider class=oracle.portal.provider.v2.DefaultProviderDefinition providerInstanceClassnet.mzyg.tx.TxProviderInstanceproviderInstanceClass sessionfalsesession passAllUrlParamsfalsepassAllUrlParams preferenceStore class=oracle.portal.provider.v2. preference.DBPreferenceStore nameprefStore1name connectionjava:compenvjdbcPortletPrefsconnection preferenceStore cipherManager class=oracle.portal.sample.v2.devguide.tx. InsecureCipherManager Enhancing Java Portlets 7-61

7.2.8.3.7 Exporting by Reference Example To export by reference rather than exporting

the actual personalization, do the following: 1. Override the DefaultPortletInstance with the following ExportByRefDefaultPortletInstance: package oracle.portal.sample.v2.devguide.tx; import oracle.portal.provider.v2.DefaultPortletInstance; import oracle.portal.provider.v2.preference.PreferenceStore; import oracle.portal.provider.v2.transport.PrefStoreTransporter; public class ExportByRefDefaultPortletInstance extends DefaultPortletInstance { Returns a {link oracle.portal.provider.v2.transport.PrefStoreTransporter} capable of carrying out transport operations such as exportimport on data applicable to {link oracle.portal.provider.v2.PortletInstance} persisted in {link oracle.portal.provider.v2.preference.PreferenceStore}. This implementation returns an {link ExportByRefPrefStoreTransporter}. param ps the {link oracle.portal.provider.v2.preference.PreferenceStore} containing the data to be transported. return a {link oracle.portal.provider.v2.transport.PrefStoreTransporter} protected PrefStoreTransporter getPrefStoreTransporterPreferenceStore ps { return new ExportByRefPrefStoreTransporterps; } } 2. Create the ExportByRefPrefStoreTransporter class referenced in ExportByRefDefaultPortletInstance. This class implements an alternative preference store transporter that does not send preference data during the export operation. Instead, it writes the context path of the source preference to the stream. During the export, it reads the context path and uses that path to look up the preference data and copy it to the new instance. This method of exporting by reference assumes that the source and target providers have access to the same preference store. In fact, the best case for this example would be the situation where the source and target providers are the same. package oracle.portal.sample.v2.devguide.tx; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import oracle.portal.provider.v2.transport.PrefStoreTransporter; import oracle.portal.provider.v2.transport.TransportLogger; import oracle.portal.provider.v2.preference.Preference; import oracle.portal.provider.v2.preference.PreferenceStore; import oracle.portal.provider.v2.preference.PreferenceStoreException; public class ExportByRefPrefStoreTransporter extends PrefStoreTransporter { public ExportByRefPrefStoreTransporterPreferenceStore prefStore { superprefStore; } Exports the context path of the supplied {link oracle.portal.provider.v2.preference.Preference} from the {link oracle.portal.provider.v2.preference.PreferenceStore}. param pref the source {link 7-62 Oracle Fusion Middleware Developers Guide for Oracle Portal oracle.portal.provider.v2.preference.Preference} param out the codejava.io.OutputStreamout to which data will be written. param logger protected void exportPreferencePreference pref, OutputStream out, TransportLogger logger throws PreferenceStoreException, IOException { Get the context path of the preference we are exporting. String contextPath = pref.getContextPath; DataOutputStream dos = new DataOutputStreamout; Write the context path in the export data. The import process will use this context path to lookup this preference in the preference store and copy it to the new context dos.writeUTFcontextPath; } Reads a context path from the stream and copies preference data from that location into the {link oracle.portal.provider.v2.preference.PreferenceStore}. param pref the target {link oracle.portal.provider.v2.preference.Preference} param in the codejava.io.InputStreamcode from which to read data. param logger protected void importPreferencePreference pref, InputStream in, TransportLogger logger throws PreferenceStoreException, IOException { Read the context path to copy the value for this preference from. DataInputStream dis = new DataInputStreamin; String contextPath = dis.readUTF; Create preference object to copy from identical to the target preference but with a different context path Preference sourcePref = new PreferencecontextPath, pref.getName, pref.getType, Stringnull; Copy across the preference getPrefStore.copysourcePref, pref, true; } } 3. Update provider.xml to include the following element for your portlet: portlet class=oracle.portal.provider.v2.DefaultPortletDefinition ... portletInstanceClassoracle.portal.sample.v2.devguide.tx. ExportByRefDefaultPortletInstanceportletInstanceClass portlet For more information on the syntax of provider.xml, refer to the provider Javadoc on OTN: http:www.oracle.comtechnologyproductsiasportalhtmljavadocx ml_tag_reference_v2.html Enhancing Java Portlets 7-63

7.2.9 Enhancing Portlet Performance with Caching

In the previous sections of this chapter, you learned how to write fully-functional Java portlets using the PDK Framework. Once you complete the basic functionality of your portlet, you may want to turn your attention to portlet performance. Caching is a common technique for enhancing the performance of Web sites that include a great deal of dynamic content. The overhead involved in retrieving data and generating the output for dynamic content can be significantly reduced by proxying requests through a local agent backed by a large, low-latency data store known as a cache. The cache agent responds to a request in one of two ways, as follows: ■ If a valid version of the requested content exists in the cache, the agent simply returns the existing cached copy, thus skipping the costly process of content retrieval and generation. This condition is called a cache hit. ■ If a valid version of the requested content does not exist in the cache, the agent forwards the request to its destination and awaits the return of the content. The agent returns the content to the requestor and stores a local copy in its cache for reuse if a subsequent request for the same content arises. This condition is called a cache miss. Web providers generate dynamic content that is, portlets and they often reside remotely from the Oracle Portal instance on which they are deployed. As such, caching might improve their performance. The architecture of Oracle Portal lends itself well to caching, since all rendering requests originate from a single page assembling agent, known as the Parallel Page Engine PPE, which resides on the middle tier. You can make the PPE cache the portlets rendered by your Web provider and reuse the cached copies to handle subsequent requests, minimizing the overhead your Web provider imposes on page assembly. The Web provider can use any one of three different caching methods, depending upon which one is best suited to the application. The methods differ chiefly in how they determine whether content is still valid. Following are the three caching methods:

1. Expiry-based Caching

: When a provider receives a render request, it stamps its response with an expiry time. The rendered response remains in the cache and fills all subsequent requests for the same content until its expiry time passes. This caching scheme is perhaps the simplest and most performant because the test for cache validity requires very little overhead and does not involve any network round trips. Expiry-based caching suits applications where the content has a well-defined life span. For content with a less certain life span, however, expiry-based caching is less effective. Refer to Section 7.2.9.2, Activating Caching and Section 7.2.9.3, Adding Expiry-Based Caching for more information.

2. Invalidation-based Caching:

Invalidation-based caching works essentially the same way as expiry-based caching, except that the contents of the cache can expire or become invalid at any time. Invalidation of cache content is usually triggered by an event. For example, if you have a calendar portlet that shows your appointments for the day, the content for the portlet could be generated once, the first time you show the calendar for that day. The content remains cached until something happens to change your schedule for that day, such as the addition of an appointment, the deletion of an existing appointment, or a change of time for an appointment. Each of these change events can trigger an action in the calendar application. When such an event takes place, your calendar application can generate an invalidation request for any cached portlet content affected by the change. The next time you view a page containing your calendar portlet, the cache will not contain an entry.