001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id$ */
019:
020: package org.apache.fop.util;
021:
022: import java.awt.color.ColorSpace;
023: import java.awt.color.ICC_ColorSpace;
024: import java.awt.color.ICC_Profile;
025: import java.util.Collections;
026: import java.util.Map;
027:
028: import javax.xml.transform.Source;
029: import javax.xml.transform.URIResolver;
030: import javax.xml.transform.stream.StreamSource;
031:
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034:
035: /**
036: * Map with cached ICC based ColorSpace objects.
037: */
038: public class ColorSpaceCache {
039: /** logger instance */
040: private static Log log = LogFactory.getLog(ColorSpaceCache.class);
041:
042: private URIResolver resolver;
043: private Map colorSpaceMap = Collections
044: .synchronizedMap(new java.util.HashMap());
045:
046: /**
047: * Default constructor
048: * @param resolver uri resolver
049: */
050: public ColorSpaceCache(URIResolver resolver) {
051: this .resolver = resolver;
052: }
053:
054: /**
055: * Create (if needed) and return an ICC ColorSpace instance.
056: *
057: * The ICC profile source is taken from the src attribute of the color-profile FO element.
058: * If the ICC ColorSpace is not yet in the cache a new one is created and stored in the cache.
059: *
060: * The FOP URI resolver is used to try and locate the ICC file.
061: * If that fails null is returned.
062: *
063: * @param base a base URI to resolve relative URIs
064: * @param iccProfileSrc ICC Profile source to return a ColorSpace for
065: * @return ICC ColorSpace object or null if ColorSpace could not be created
066: */
067: public ColorSpace get(String base, String iccProfileSrc) {
068: ColorSpace colorSpace = null;
069: if (!colorSpaceMap.containsKey(base + iccProfileSrc)) {
070: try {
071: ICC_Profile iccProfile = null;
072: // First attempt to use the FOP URI resolver to locate the ICC
073: // profile
074: Source src = resolver.resolve(iccProfileSrc, base);
075: if (src != null && src instanceof StreamSource) {
076: // FOP URI resolver found ICC profile - create ICC profile
077: // from the Source
078: iccProfile = ICC_Profile
079: .getInstance(((StreamSource) src)
080: .getInputStream());
081: } else {
082: // TODO - Would it make sense to fall back on VM ICC
083: // resolution
084: // Problem is the cache might be more difficult to maintain
085: //
086: // FOP URI resolver did not find ICC profile - perhaps the
087: // Java VM can find it?
088: // iccProfile = ICC_Profile.getInstance(iccProfileSrc);
089: }
090: if (iccProfile != null) {
091: colorSpace = new ICC_ColorSpace(iccProfile);
092: }
093: } catch (Exception e) {
094: // Ignore exception - will be logged a bit further down
095: // (colorSpace == null case)
096: }
097:
098: if (colorSpace != null) {
099: // Put in cache (not when VM resolved it as we can't control
100: colorSpaceMap.put(base + iccProfileSrc, colorSpace);
101: } else {
102: // TODO To avoid an excessive amount of warnings perhaps
103: // register a null ColorMap in the colorSpaceMap
104: log.warn("Color profile '" + iccProfileSrc
105: + "' not found.");
106: }
107: } else {
108: colorSpace = (ColorSpace) colorSpaceMap.get(base
109: + iccProfileSrc);
110: }
111: return colorSpace;
112: }
113: }
|