001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.components.legacy;
019:
020: import java.io.File;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.OutputStream;
024: import java.util.Collection;
025:
026: import de.finix.contelligent.CallData;
027: import de.finix.contelligent.Component;
028: import de.finix.contelligent.ComponentContext;
029: import de.finix.contelligent.ComponentManager;
030: import de.finix.contelligent.category.CategoryCombinationNotSupportedException;
031: import de.finix.contelligent.content.BinaryContent;
032: import de.finix.contelligent.content.Content;
033: import de.finix.contelligent.content.ContentProvider;
034: import de.finix.contelligent.exception.ComponentPersistenceException;
035: import de.finix.contelligent.exception.ContelligentException;
036: import de.finix.contelligent.logging.LoggingService;
037: import de.finix.contelligent.persistence.FileAdapter;
038: import de.finix.contelligent.persistence.LocalFileAdapter;
039: import de.finix.contelligent.render.BinaryRenderer;
040: import de.finix.contelligent.render.Renderable;
041: import de.finix.contelligent.render.Renderer;
042: import de.finix.contelligent.search.Metainfo;
043: import de.finix.contelligent.util.FileUtils;
044:
045: /**
046: * This is a component acting as a {@link ContentProvider} for
047: * {@link BinaryContent} where the contents is streamed from a file which is
048: * searched in the current {@link FileAdapter} using the path of this component
049: * as resource path.
050: */
051: public class FileFacade implements Component, Renderable,
052: ContentProvider, BinaryContent {
053: final static org.apache.log4j.Logger log = LoggingService
054: .getLogger(FileFacade.class);
055:
056: final static public String TYPENAME = "contelligent.core.File";
057:
058: private String contentType;
059:
060: private String extension;
061:
062: final private BinaryRenderer renderer;
063:
064: protected ComponentContext ctx;
065:
066: public FileFacade() {
067: renderer = new BinaryRenderer(this );
068: }
069:
070: public void setComponentContext(ComponentContext ctx) {
071: this .ctx = ctx;
072: }
073:
074: public ComponentContext getComponentContext() {
075: return ctx;
076: }
077:
078: /** Returns false always */
079: public boolean isDynamic() {
080: return false;
081: }
082:
083: public void postCreate() {
084: }
085:
086: /**
087: * returns the path of this component as string. (without a trailing
088: * separator!)
089: */
090: final public String toString() {
091: if (ctx != null) {
092: return ctx.getPath().toString();
093: } else {
094: return "Component (name unknown)";
095: }
096: }
097:
098: /**
099: * This is the implementation of {@link Component#getSearchMetainfo}.
100: * Overwrite that method for extension.
101: *
102: * @returns
103: */
104: public void putSearchMetainfo(Metainfo metainfo, CallData callData) {
105: }
106:
107: /**
108: * Answer true if the content of this component may be changed
109: *
110: * @return
111: */
112: public boolean mayChangeContent() {
113: return true;
114: }
115:
116: public void setContentType(String contentType) {
117: this .contentType = contentType;
118: }
119:
120: public String getContentType() {
121: return contentType;
122: }
123:
124: public String getExtension() {
125: return extension;
126: }
127:
128: public void setExtension(String extension) {
129: this .extension = extension;
130: }
131:
132: // from interface Renderable:
133:
134: public Renderer getRenderer() {
135: return renderer;
136: }
137:
138: // from interface ContentProvider:
139:
140: public Content getContent() {
141: return this ;
142: }
143:
144: // from interface BinaryContent:
145:
146: /**
147: * Implementation of {@link BinaryContent#streamBinary}. Uses the path of
148: * this component to get a file with the same path +
149: * {@link #setExtension extension} from the
150: * {@link FileAdapter#getResourceAsStream file-adapter}.
151: *
152: * @param out
153: * an <code>OutputStream</code> value
154: * @param callData
155: * a <code>CallData</code> value
156: */
157: public void streamBinary(OutputStream out, CallData callData)
158: throws IOException {
159: final String resName = getResourceName();
160: final boolean debugEnabled = log.isDebugEnabled();
161:
162: // XXX: use actual or persistent-manager here? If we use the actual one
163: // we allow to
164: // shadow a file in root with another one in edit without duplicating
165: // the component!
166: // (2002/10/23, rs)
167: ComponentManager manager = ctx.getPersistenceManager();
168: if (debugEnabled) {
169: log.debug("'" + this
170: + "':streamBinary() - should stream this file '"
171: + resName + "' from persistenceManager '" + manager
172: + "' ...");
173: }
174:
175: final FileAdapter fileAdapter = manager.getFileAdapter();
176: InputStream in = fileAdapter.getResourceAsStream(resName);
177: if (debugEnabled) {
178: log
179: .debug("'"
180: + this
181: + "':streamBinary() - resource '"
182: + resName
183: + "' found, streaming it to given output-stream ...");
184: }
185: try {
186: FileUtils.copy(in, out);
187: } finally {
188: if (in != null) {
189: try {
190: in.close();
191: } catch (Exception e) {
192: }
193: }
194: }
195: }
196:
197: public Object getContentValue(CallData callData)
198: throws IOException, ContelligentException {
199: return null;
200: }
201:
202: public int length(CallData callData)
203: throws CategoryCombinationNotSupportedException,
204: ComponentPersistenceException {
205: String resName = getResourceName();
206: ComponentManager manager = ctx.getPersistenceManager();
207: LocalFileAdapter fileAdapter = manager.getFileAdapter();
208: File file = fileAdapter.getResourceAsFile(resName);
209: return (int) file.length();
210: }
211:
212: public String getContentType(CallData callData) {
213: return getContentType();
214: }
215:
216: public String getExtension(CallData callData) {
217: return getExtension();
218: }
219:
220: // from interface Content (super-interface of BinaryContent):
221:
222: public Collection getSensitiveCategories() {
223: return null;
224: }
225:
226: public long lastModified(CallData callData) throws IOException {
227: final String resName = getResourceName();
228: return ctx.getPersistenceManager().getFileAdapter()
229: .lastModified(resName);
230: }
231:
232: public String getResourceName() {
233: String ext = getExtension();
234: if (ext == null || ext.length() == 0) {
235: return ctx.getPath().toString();
236: } else {
237: StringBuffer sb = new StringBuffer(32);
238: sb.append(ctx.getPath().toString()).append('.').append(ext);
239: return sb.toString();
240: }
241: }
242:
243: }
|