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: package org.apache.lenya.cms.publication;
019:
020: import java.awt.image.BufferedImage;
021: import java.io.ByteArrayInputStream;
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.io.OutputStream;
025: import java.net.MalformedURLException;
026: import java.util.Iterator;
027:
028: import javax.imageio.ImageIO;
029:
030: import org.apache.avalon.framework.logger.AbstractLogEnabled;
031: import org.apache.avalon.framework.logger.Logger;
032: import org.apache.avalon.framework.service.ServiceException;
033: import org.apache.avalon.framework.service.ServiceManager;
034: import org.apache.cocoon.servlet.multipart.Part;
035: import org.apache.commons.io.IOUtils;
036: import org.apache.commons.io.output.ByteArrayOutputStream;
037: import org.apache.excalibur.source.SourceResolver;
038: import org.apache.excalibur.source.TraversableSource;
039: import org.apache.lenya.cms.metadata.MetaData;
040: import org.apache.lenya.cms.metadata.MetaDataException;
041: import org.apache.lenya.cms.repository.RepositoryException;
042:
043: /**
044: * Wrapper to handle resource documents.
045: */
046: public class ResourceWrapper extends AbstractLogEnabled {
047:
048: private ServiceManager manager;
049: private Document document;
050:
051: private static final String MIME_IMAGE_PJPEG = "image/pjpeg";
052: private static final String MIME_IMAGE_JPEG = "image/jpeg";
053:
054: /**
055: * @param document The document to wrap.
056: * @param manager The service manager.
057: * @param logger The logger.
058: */
059: public ResourceWrapper(Document document, ServiceManager manager,
060: Logger logger) {
061: this .document = document;
062: this .manager = manager;
063: enableLogging(logger);
064: }
065:
066: protected Document getDocument() {
067: return this .document;
068: }
069:
070: /**
071: * @param file The part to write.
072: * @throws IOException
073: * @throws MetaDataException
074: * @throws ServiceException
075: * @throws RepositoryException
076: * @throws DocumentException
077: */
078: public void write(Part file) throws IOException, MetaDataException,
079: ServiceException, RepositoryException, DocumentException {
080:
081: String mimeType = file.getMimeType();
082: String fileName = file.getFileName();
083: int fileSize = file.getSize();
084: InputStream inputStream = file.getInputStream();
085:
086: write(inputStream, mimeType, fileName, fileSize);
087: }
088:
089: /**
090: * Writes the content of the resource from a source.
091: * @param sourceUri The source URI.
092: * @throws ServiceException
093: * @throws MalformedURLException
094: * @throws IOException
095: * @throws RepositoryException
096: * @throws DocumentException
097: * @throws MetaDataException
098: */
099: public void write(String sourceUri) throws ServiceException,
100: MalformedURLException, IOException, RepositoryException,
101: DocumentException, MetaDataException {
102: SourceResolver resolver = null;
103: TraversableSource source = null;
104: try {
105: resolver = (SourceResolver) this .manager
106: .lookup(SourceResolver.ROLE);
107: source = (TraversableSource) resolver.resolveURI(sourceUri);
108: write(source.getInputStream(), source.getMimeType(), source
109: .getName(), source.getContentLength());
110: } finally {
111: if (resolver != null) {
112: if (source != null) {
113: resolver.release(source);
114: }
115: this .manager.release(resolver);
116: }
117: }
118: }
119:
120: /**
121: * Writes the content of the resource.
122: * @param inputStream The input stream providing the content.
123: * @param mimeType The mime type.
124: * @param fileName The file name.
125: * @param fileSize The file size.
126: * @throws IOException
127: * @throws MetaDataException
128: * @throws ServiceException
129: * @throws MalformedURLException
130: * @throws RepositoryException
131: * @throws DocumentException
132: */
133: public void write(InputStream inputStream, String mimeType,
134: String fileName, long fileSize) throws IOException,
135: MetaDataException, ServiceException, MalformedURLException,
136: RepositoryException, DocumentException {
137: final ByteArrayOutputStream sourceBos = new ByteArrayOutputStream();
138: IOUtils.copy(inputStream, sourceBos);
139:
140: InputStream input = new ByteArrayInputStream(sourceBos
141: .toByteArray());
142:
143: MetaData mediaMeta = null;
144:
145: OutputStream destOutputStream = null;
146: try {
147: mediaMeta = document
148: .getMetaData("http://apache.org/lenya/metadata/media/1.0");
149: addResourceMeta(fileName, mimeType, input, mediaMeta);
150:
151: destOutputStream = document.getOutputStream();
152: IOUtils.write(sourceBos.toByteArray(), destOutputStream);
153:
154: document.setMimeType(mimeType);
155:
156: } finally {
157: if (destOutputStream != null) {
158: destOutputStream.flush();
159: destOutputStream.close();
160: }
161: }
162:
163: if (getLogger().isDebugEnabled())
164: getLogger().debug("Resource::addResource() done.");
165: }
166:
167: protected void addResourceMeta(String fileName, String mimeType,
168: InputStream stream, MetaData customMeta)
169: throws MetaDataException, IOException {
170: if (customMeta != null) {
171: customMeta.setValue("filename", fileName);
172: }
173: if (canReadMimeType(mimeType)) {
174: BufferedImage input = ImageIO.read(stream);
175: String width = Integer.toString(input.getWidth());
176: String height = Integer.toString(input.getHeight());
177: customMeta.setValue("height", height);
178: customMeta.setValue("width", width);
179: }
180: }
181:
182: /**
183: * Checks if a mime type denotes an image.
184: * @param mimeType The mime type.
185: * @return A boolean value.
186: */
187: public static boolean canReadMimeType(String mimeType) {
188: Iterator iter = ImageIO
189: .getImageReadersByMIMEType(translateMimeType(mimeType));
190: return iter.hasNext();
191: }
192:
193: /**
194: * Translates the mime type if it can be read, but the tools don't think so.
195: * For example, all jpegs from IE are marked as image/pjpeg, which ImageIO
196: * doesn't return a ImageReader for, even though the one for image/jpeg
197: * works just fine, even for a real image/pjpeg.
198: * @param mimeType The mime type.
199: * @return The translated or original mime type if no translation was applied
200: */
201: private static String translateMimeType(String mimeType) {
202: if (mimeType.equals(MIME_IMAGE_PJPEG)) {
203: return MIME_IMAGE_JPEG;
204: }
205: return mimeType;
206: }
207: }
|