123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- /* $Id$ */
-
- package org.apache.fop.afp;
-
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.URI;
- import java.net.URISyntaxException;
- import java.util.Map;
-
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
-
- import org.apache.fop.afp.modca.AbstractNamedAFPObject;
- import org.apache.fop.afp.modca.AbstractPageObject;
- import org.apache.fop.afp.modca.IncludeObject;
- import org.apache.fop.afp.modca.IncludedResourceObject;
- import org.apache.fop.afp.modca.PageSegment;
- import org.apache.fop.afp.modca.Registry;
- import org.apache.fop.afp.modca.ResourceGroup;
- import org.apache.fop.afp.modca.ResourceObject;
- import org.apache.fop.afp.util.ResourceAccessor;
- import org.apache.fop.afp.util.SimpleResourceAccessor;
-
- /**
- * Manages the creation and storage of document resources
- */
- public class AFPResourceManager {
-
- /** logging instance */
- private static Log log = LogFactory.getLog(AFPResourceManager.class);
-
- /** The AFP datastream (document tree) */
- private DataStream dataStream;
-
- /** Resource creation factory */
- private final Factory factory;
-
- private final AFPStreamer streamer;
-
- private final AFPDataObjectFactory dataObjectFactory;
-
- /** Maintain a reference count of instream objects for referencing purposes */
- private int instreamObjectCount = 0;
-
- /** a mapping of resourceInfo --> include name */
- private final Map/*<AFPResourceInfo,String>*/ includeNameMap
- = new java.util.HashMap()/*<AFPResourceInfo,String>*/;
-
- private Map pageSegmentMap = new java.util.HashMap();
-
- private AFPResourceLevelDefaults resourceLevelDefaults = new AFPResourceLevelDefaults();
-
- /**
- * Main constructor
- */
- public AFPResourceManager() {
- this.factory = new Factory();
- this.streamer = new AFPStreamer(factory);
- this.dataObjectFactory = new AFPDataObjectFactory(factory);
- }
-
- /**
- * Sets the outputstream
- *
- * @param paintingState the AFP painting state
- * @param outputStream the outputstream
- * @return a new AFP DataStream
- * @throws IOException thrown if an I/O exception of some sort has occurred
- */
- public DataStream createDataStream(AFPPaintingState paintingState, OutputStream outputStream)
- throws IOException {
- this.dataStream = streamer.createDataStream(paintingState);
- streamer.setOutputStream(outputStream);
- return this.dataStream;
- }
-
- /**
- * Returns the AFP DataStream
- *
- * @return the AFP DataStream
- */
- public DataStream getDataStream() {
- return this.dataStream;
- }
-
- /**
- * Tells the streamer to write
- *
- * @throws IOException thrown if an I/O exception of some sort has occurred.
- */
- public void writeToStream() throws IOException {
- streamer.close();
- }
-
- /**
- * Sets the default resource group file path
- *
- * @param filePath the default resource group file path
- */
-
- public void setDefaultResourceGroupFilePath(String filePath) {
- streamer.setDefaultResourceGroupFilePath(filePath);
- }
-
- /**
- * Creates a new data object in the AFP datastream
- *
- * @param dataObjectInfo the data object info
- *
- * @throws IOException thrown if an I/O exception of some sort has occurred.
- */
- public void createObject(AFPDataObjectInfo dataObjectInfo) throws IOException {
- AbstractNamedAFPObject namedObj = null;
-
- AFPResourceInfo resourceInfo = dataObjectInfo.getResourceInfo();
- updateResourceInfoUri(resourceInfo);
-
- String objectName = (String)includeNameMap.get(resourceInfo);
- if (objectName != null) {
- // an existing data resource so reference it by adding an include to the current page
- includeObject(dataObjectInfo, objectName);
- return;
- }
-
- objectName = (String)pageSegmentMap.get(resourceInfo);
- if (objectName != null) {
- // an existing data resource so reference it by adding an include to the current page
- includePageSegment(dataObjectInfo, objectName);
- return;
- }
-
- boolean useInclude = true;
- Registry.ObjectType objectType = null;
-
- // new resource so create
- if (dataObjectInfo instanceof AFPImageObjectInfo) {
- AFPImageObjectInfo imageObjectInfo = (AFPImageObjectInfo)dataObjectInfo;
- namedObj = dataObjectFactory.createImage(imageObjectInfo);
- } else if (dataObjectInfo instanceof AFPGraphicsObjectInfo) {
- AFPGraphicsObjectInfo graphicsObjectInfo = (AFPGraphicsObjectInfo)dataObjectInfo;
- namedObj = dataObjectFactory.createGraphic(graphicsObjectInfo);
- } else {
- // natively embedded data object
- namedObj = dataObjectFactory.createObjectContainer(dataObjectInfo);
- objectType = dataObjectInfo.getObjectType();
- useInclude = objectType != null && objectType.isIncludable();
- }
-
- AFPResourceLevel resourceLevel = resourceInfo.getLevel();
- ResourceGroup resourceGroup = streamer.getResourceGroup(resourceLevel);
- useInclude &= resourceGroup != null;
- if (useInclude) {
-
- boolean usePageSegment = dataObjectInfo.isCreatePageSegment();
-
- // if it is to reside within a resource group at print-file or external level
- if (resourceLevel.isPrintFile() || resourceLevel.isExternal()) {
- if (usePageSegment) {
- String pageSegmentName = "S10" + namedObj.getName().substring(3);
- namedObj.setName(pageSegmentName);
- PageSegment seg = new PageSegment(pageSegmentName);
- seg.addObject(namedObj);
- namedObj = seg;
- }
-
- // wrap newly created data object in a resource object
- namedObj = dataObjectFactory.createResource(namedObj, resourceInfo, objectType);
- }
-
- // add data object into its resource group destination
- resourceGroup.addObject(namedObj);
-
- // create the include object
- objectName = namedObj.getName();
- if (usePageSegment) {
- includePageSegment(dataObjectInfo, objectName);
- pageSegmentMap.put(resourceInfo, objectName);
- } else {
- includeObject(dataObjectInfo, objectName);
- // record mapping of resource info to data object resource name
- includeNameMap.put(resourceInfo, objectName);
- }
-
- } else {
- // not to be included so inline data object directly into the current page
- dataStream.getCurrentPage().addObject(namedObj);
- }
- }
-
- private void updateResourceInfoUri(AFPResourceInfo resourceInfo) {
- String uri = resourceInfo.getUri();
- if (uri == null) {
- uri = "/";
- }
- // if this is an instream data object adjust the uri to ensure that its unique
- if (uri.endsWith("/")) {
- uri += "#" + (++instreamObjectCount);
- resourceInfo.setUri(uri);
- }
- }
-
- private void includeObject(AFPDataObjectInfo dataObjectInfo,
- String objectName) {
- IncludeObject includeObject
- = dataObjectFactory.createInclude(objectName, dataObjectInfo);
- dataStream.getCurrentPage().addObject(includeObject);
- }
-
- private void includePageSegment(AFPDataObjectInfo dataObjectInfo,
- String pageSegmentName) {
- int x = dataObjectInfo.getObjectAreaInfo().getX();
- int y = dataObjectInfo.getObjectAreaInfo().getY();
- AbstractPageObject currentPage = dataStream.getCurrentPage();
- boolean createHardPageSegments = true;
- currentPage.createIncludePageSegment(pageSegmentName, x, y, createHardPageSegments);
- }
-
- /**
- * Creates an included resource object by loading the contained object from a file.
- * @param resourceName the name of the resource
- * @param basePath the base path in which to look for the resource files
- * @param resourceObjectType the resource object type ({@link ResourceObject}.*)
- * @throws IOException if an I/O error occurs while loading the resource
- */
- public void createIncludedResource(String resourceName, String basePath,
- byte resourceObjectType) throws IOException {
- AFPResourceLevel resourceLevel = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE);
- URI uri;
- try {
- uri = new URI(resourceName.trim());
- } catch (URISyntaxException e) {
- throw new IOException("Could not create URI from resource name: " + resourceName
- + " (" + e.getMessage() + ")");
- }
-
- AFPResourceInfo resourceInfo = new AFPResourceInfo();
- resourceInfo.setLevel(resourceLevel);
- resourceInfo.setName(resourceName);
- resourceInfo.setUri(uri.toASCIIString());
-
- String objectName = (String)includeNameMap.get(resourceInfo);
- if (objectName == null) {
- if (log.isDebugEnabled()) {
- log.debug("Adding included resource: " + resourceName);
- }
- //TODO This works with local filenames only. In the long term, this
- //should work through FOP's URI resolver.
- ResourceAccessor accessor = new SimpleResourceAccessor(basePath);
- IncludedResourceObject resourceContent = new IncludedResourceObject(
- resourceName, accessor, uri);
-
- ResourceObject resourceObject = factory.createResource(resourceName);
- resourceObject.setDataObject(resourceContent);
- resourceObject.setType(resourceObjectType);
-
- ResourceGroup resourceGroup = streamer.getResourceGroup(resourceLevel);
- resourceGroup.addObject(resourceObject);
- // record mapping of resource info to data object resource name
- includeNameMap.put(resourceInfo, resourceName);
- } else {
- //skip, already created
- }
- }
-
- /**
- * Sets resource level defaults. The existing defaults over merged with the ones passed in
- * as parameter.
- * @param defaults the new defaults
- */
- public void setResourceLevelDefaults(AFPResourceLevelDefaults defaults) {
- this.resourceLevelDefaults.mergeFrom(defaults);
- }
-
- /**
- * Returns the resource level defaults in use with this resource manager.
- * @return the resource level defaults
- */
- public AFPResourceLevelDefaults getResourceLevelDefaults() {
- return this.resourceLevelDefaults;
- }
-
- }
|