All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.xfa.service.href.HrefService Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
/**
 * Copyright 2005 Adobe Systems Incorporated.  All Rights Reserved
 *
 * NOTICE:  Adobe permits you to use, modify, and distribute this file in
 * accordance with the terms of the Adobe license agreement accompanying it.
 * If you have received this file from a source other than Adobe, then your
 * use, modification, or distribution of it requires the prior written
 * permission of Adobe.
 */

package com.adobe.xfa.service.href;

import com.adobe.xfa.AppModel;
import com.adobe.xfa.Attribute;
import com.adobe.xfa.HrefHandler;
import com.adobe.xfa.Model;
import com.adobe.xfa.Node;
import com.adobe.xfa.ProtoableNode;
import com.adobe.xfa.XFA;
import com.adobe.xfa.configuration.ConfigurationModel;
import com.adobe.xfa.protocol.ProtocolUtils;
import com.adobe.xfa.service.Service;
import com.adobe.xfa.service.href.HrefStore.HrefData;
import com.adobe.xfa.template.TemplateModel;
import com.adobe.xfa.ut.ExFull;
import com.adobe.xfa.ut.MsgFormatPos;
import com.adobe.xfa.ut.ResId;
import com.adobe.xfa.ut.StringUtils;


/**
 * A class to handle all href related actions in an XFA based form.
 */
public class HrefService extends Service implements HrefHandler {

	private final HrefStore	mHrefStore;
	private Node			mContextNode;
	private final String	msConfigSchemaName;

	/**
	 * The default cache size, in bytes.
	 */
	public static final int CACHE_SIZE = 50 * 1024;	// 50KB

	/**
	 * Instantiates a new HrefService using a specified
	 * contextNode as the context for resolving
	 * relative references.
	 * @param contextNode the context node for resolving relative references.
	 * @param nHrefCacheSize the maximum size of the cache of URL bytes. If negative,
	 * no caching is done. If zero, CACHE_SIZE is used. 
	 */
	public HrefService(Node contextNode, int nHrefCacheSize) {
		super();
		String sBasePath = getBaseUrl(contextNode);
		String sUriPath = getAlternativeUrl(contextNode);
		if (nHrefCacheSize == 0)
			nHrefCacheSize = CACHE_SIZE;
		mHrefStore = new HrefStore(this, sBasePath, sUriPath, nHrefCacheSize);
		mContextNode = contextNode;
		msConfigSchemaName = null;
	}

	/**
	 * Instantiates a new HrefService using the configuration
	 * to determine the node that will service as the context for resolving
	 * relative references.
	 * @param sConfigSchemaName the name of the configuration element containing
	 * the template.base and template.uri elements that
	 * describe how relative references are to be resolved.
	 * @param nHrefCacheSize the maximum size of the cache of URL bytes. If negative,
	 * no caching is done. If zero, CACHE_SIZE is used. 
	 */
	public HrefService(String sConfigSchemaName, int nHrefCacheSize) {
		super();
		if (nHrefCacheSize == 0)
			nHrefCacheSize = CACHE_SIZE;
		mHrefStore = new HrefStore(this, null, null, nHrefCacheSize);
		mContextNode = null;
		msConfigSchemaName = sConfigSchemaName;
	}

	/**
	 * Gets the context node associated with this service.
	 * @return the context node associated with this service.
	 * @exclude from published api.
	 */
	public final Node getContextNode() {
		return mContextNode;
	}

	/**
	 * Gets the configuration schema name associated with this service.
	 * @return the configuration schema name associated with this service.
	 * @exclude from published api.
	 */
	public final String getConfigSchemaName() {
		return msConfigSchemaName;
	}

	/**
	 * Sets the context node associated with this service.
	 * @param contextNode the context node.
	 * @exclude from published api. 
	 */
	public final void setContextNode(Node contextNode) {
		mContextNode = contextNode;
	}

	/**
	 * Get the trustiness of absolute URLs.
	 * @return the trustiness. When true, absolute hrefs are allowed.
	 * @exclude from published api.
	 */
	public final boolean isTrusted() {
		return mHrefStore.isTrusted();
	}

	/**
	 * Sets the trustiness of absolute urls. Trust implies that
	 * absolute hrefs are allowed.
	 * @param bTrusted allow absolute URLs when true.
 	 * @exclude from published api.
	 */
	public final void isTrusted(boolean bTrusted) {
		mHrefStore.isTrusted(bTrusted);
	}

	/**
	 * Gets the size of the cache in bytes.
	 * @return the size of the cache in bytes.
	 * @exclude from published api.
	 */
	public final int getCacheSize() {
		return mHrefStore.getCacheSize();
	}

	/**
	 * Sets the cache size in bytes. The service will use this value as an
	 * upper limit for loaded hrefs. 
	 * @param nSize the size of the cache in bytes.
	 * @exclude from published api.
	 */
	final void setCacheSize(int nSize) {
		mHrefStore.setCacheSize(nSize);
	}

	/**
	 * Clears the cache. Removes all hrefs from the cache.
	 * @exclude from published api.
	 */
	public final void clearCache() {
		mHrefStore.clearCache();
	}

	/**
	 * Gets the current size of the cache in bytes.
	 * @return the current size of the cache in bytes.
	 * @exclude from published api.
	 */
	public final int getCurrentCacheSize() {
		return mHrefStore.getCurrentCacheSize();
	}

	/**
	 * Gets the HrefStore.
	 * @return the pointer to href Store.
	 * @exclude from published api.
	 */
	private final HrefStore getHrefStore() {
		return mHrefStore;
	}

    /**
     * Resolves the usehref attribute in the given ProtoableNode and
     * loads the referenced document into a new AppModel.
	 * Any fragment identifier in the URL is ignored.
     * @param protoableNode a ProtoableNode with a usehref attribute.
     * @return the newly created AppModel containing the document loaded
     * from the referenced location, or null upon error.
     */
	public AppModel loadFragment(ProtoableNode protoableNode) {

		// node must have a non-empty usehref attribute.
		Attribute usehref = protoableNode.peekAttribute(XFA.USEHREFTAG);
		if (usehref == null)
			throw new IllegalArgumentException();
		
		return loadFragmentInternal(protoableNode.getAppModel(), usehref.toString(), protoableNode.getName());
	}
	
	/**
     * Resolves a URL and loads the reference XFA document into a new AppModel.
	 * Any fragment identifier in the URL is ignored.
     * @param appModel the AppModel containing the URL
     * @param sUrl the URL that references the external XFA document
     * @return the newly created AppModel containing the document loaded
     * from the referenced location.
     */
	public AppModel loadFragment(AppModel appModel, String sUrl) {
		return loadFragmentInternal(appModel, sUrl, null);
	}
	
	private AppModel loadFragmentInternal(AppModel appModel, String sUrl, String sNodeName) {
		
		// Ensure node as a non-empty usehref attribute.
		if (StringUtils.isEmpty(sUrl))
			throw new IllegalArgumentException();
	
		// If we need to finish initializing this service, then do so.
		// This occurs because in xfa/agent, we don't really know
		// when config has been loaded, so we can't fully initialize.
		// this service until herein.
		//
		Node context = getContextNode();
		if (context == null && getConfigSchemaName() != null) {
			
			// Emulate XFAAgent::getContextNode()
			ConfigurationModel configModel = ConfigurationModel.getConfigurationModel(appModel, false);
			
			if (configModel != null) {
			
				context = configModel.getCommonNode(getConfigSchemaName());
				
				if (context != null) {
				
					String sBasePath = getBaseUrl(context);
					if (!StringUtils.isEmpty(sBasePath))
						setBaseUrl(sBasePath);
					
					String sUriPath = getAlternativeUrl(context);
					if (!StringUtils.isEmpty(sUriPath))
						setAlternativeUrl(sUriPath);
					
					setContextNode(context);
				}
			}
		}
		
		// Remove any fragment ids from the usehref to get at the url.
		int nSharp = sUrl.indexOf('#');
		if (nSharp >= 0)
			sUrl = sUrl.substring(0, nSharp);

		// Try to fetch url and load it in an  app model.
		try {
			getHrefStore().add(sUrl);
			HrefData oHrefData = getHrefStore().getHrefData(sUrl);
			return oHrefData.getAppModel();
		}
		catch (ExFull e) {
			MsgFormatPos oMsg = null;
			if (!StringUtils.isEmpty(sNodeName)) {
				//
				// "HrefService: Href cannot be resolved for node: %1."
				//
				oMsg = new MsgFormatPos(ResId.XFAHrefServiceException);
				oMsg.format(sNodeName);
				ExFull oErr = new ExFull(oMsg);
				oErr.insert(e, false);
    			throw oErr;
			}
			throw e;
		}
	}
	
    /**
     * Gets the TemplateModel associated with the
	 * given AppModel.
     * @param appModel an AppModel
     * @return the TemplateModel from appModel 
     * or null if there is no TemplateModel.
     */
	public Model getDocument(AppModel appModel) {
		return TemplateModel.getTemplateModel(appModel, false);
	}

	/**
	 * Gets the base URL that relative hrefs will be resolved against.
	 * @return a URL to resolve relative hrefs against.
	 */
	public final String getBaseUrl() {
		return mHrefStore.getBaseUrl();
	}

	/**
	 * Sets the base URL that relative hrefs will be resolved against.
	 * @param sBaseUrl a URL to resolve relative hrefs against.
	 */
	public final void setBaseUrl(String sBaseUrl) {
		mHrefStore.setBaseUrl(sBaseUrl);
	}

	/**
	 * Gets the alternate URL that relative hrefs will be resolved against.
	 * @return a URL to resolve relative hrefs against.
	 * @exclude from published api.
	 */
	public final String getAlternativeUrl() {
		return mHrefStore.getAlternativeUrl();
	}

	/**
	 * Sets the alternate URL that relative hrefs will be resolved against.
	 * @param sAltUrl a URL to resolve relative hrefs against.
	 * @exclude from published api.
	 */
	public final void setAlternativeUrl(String sAltUrl) {
		mHrefStore.setAlternativeUrl(sAltUrl);
	}

	private static final String getBaseUrl(Node contextNode) {
		return ProtocolUtils.getTemplateBasePathFromConfig(contextNode);
	}

	private static final String getAlternativeUrl(Node contextNode) {
		return ProtocolUtils.getTemplateUriPathFromConfig(contextNode);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy