001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: DatabaseImageStore.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.cmf.dam.contentstores;
009:
010: import com.uwyn.rife.cmf.Content;
011: import com.uwyn.rife.cmf.ContentInfo;
012: import com.uwyn.rife.cmf.MimeType;
013: import com.uwyn.rife.cmf.dam.ContentDataUser;
014: import com.uwyn.rife.cmf.dam.contentstores.exceptions.StoreContentDataErrorException;
015: import com.uwyn.rife.cmf.dam.contentstores.exceptions.UseContentDataErrorException;
016: import com.uwyn.rife.cmf.dam.exceptions.ContentManagerException;
017: import com.uwyn.rife.cmf.format.Formatter;
018: import com.uwyn.rife.cmf.format.exceptions.FormatException;
019: import com.uwyn.rife.cmf.transform.ContentTransformer;
020: import com.uwyn.rife.database.Datasource;
021: import com.uwyn.rife.database.DbPreparedStatement;
022: import com.uwyn.rife.database.DbPreparedStatementHandler;
023: import com.uwyn.rife.database.DbResultSet;
024: import com.uwyn.rife.database.exceptions.DatabaseException;
025: import com.uwyn.rife.database.queries.Insert;
026: import com.uwyn.rife.database.queries.Select;
027: import com.uwyn.rife.engine.ElementSupport;
028: import com.uwyn.rife.tools.Convert;
029: import com.uwyn.rife.tools.StringUtils;
030: import java.io.BufferedInputStream;
031: import java.io.ByteArrayInputStream;
032: import java.io.IOException;
033: import java.io.InputStream;
034: import java.io.OutputStream;
035: import java.sql.ResultSet;
036: import java.sql.SQLException;
037: import java.sql.Types;
038: import java.util.Map;
039:
040: public abstract class DatabaseImageStore extends DatabaseContentStore {
041: public DatabaseImageStore(Datasource datasource) {
042: super (datasource);
043:
044: addMimeType(MimeType.IMAGE_GIF);
045: addMimeType(MimeType.IMAGE_JPEG);
046: addMimeType(MimeType.IMAGE_PNG);
047: }
048:
049: public String getContentType(ContentInfo contentInfo) {
050: MimeType mimeType = MimeType.getMimeType(contentInfo
051: .getMimeType());
052: if (!getSupportedMimeTypes().contains(mimeType)) {
053: return null;
054: }
055:
056: String content_type = mimeType.toString();
057:
058: Map<String, String> attributes = contentInfo.getAttributes();
059: if (attributes != null) {
060: if (attributes.containsKey("content-type")) {
061: content_type = attributes.get("content-type");
062: }
063: }
064:
065: return content_type;
066: }
067:
068: public Formatter getFormatter(MimeType mimeType, boolean fragment) {
069: if (!getSupportedMimeTypes().contains(mimeType)) {
070: return null;
071: }
072: return mimeType.getFormatter();
073: }
074:
075: public String getContentForHtml(int id, ContentInfo info,
076: ElementSupport element, String serveContentExitName)
077: throws ContentManagerException {
078: if (null == element)
079: throw new IllegalArgumentException("element can't be null.");
080: if (null == serveContentExitName)
081: throw new IllegalArgumentException(
082: "serveContentExitName can't be null.");
083:
084: StringBuilder result = new StringBuilder();
085: result.append("<img src=\"");
086: result.append(StringUtils.encodeHtml(element.getExitQueryUrl(
087: serveContentExitName, info.getPath()).toString()));
088: result.append("\"");
089: Map<String, String> properties = info.getProperties();
090: if (properties != null) {
091: String width = properties.get("cmf:width");
092: if (width != null) {
093: result.append(" width=\"");
094: result.append(width);
095: result.append("\"");
096: }
097: String height = properties.get("cmf:height");
098: if (height != null) {
099: result.append(" height=\"");
100: result.append(height);
101: result.append("\"");
102: }
103: }
104: result.append(" alt=\"\" />");
105:
106: return result.toString();
107: }
108:
109: protected boolean _storeContentData(final Insert storeContent,
110: final int id, Content content,
111: ContentTransformer transformer)
112: throws ContentManagerException {
113: if (id < 0)
114: throw new IllegalArgumentException("id must be positive");
115: if (content != null && content.getData() != null
116: && !(content.getData() instanceof byte[]))
117: throw new IllegalArgumentException(
118: "the content data must be of type byte[]");
119:
120: assert storeContent != null;
121:
122: final byte[] typed_data;
123:
124: if (null == content || null == content.getData()) {
125: typed_data = null;
126: } else {
127: Formatter formatter = null;
128: if (!Convert.toBoolean(content.getAttribute("unformatted"),
129: false)) {
130: formatter = getFormatter(content.getMimeType(), content
131: .isFragment());
132: }
133:
134: if (formatter != null) {
135: try {
136: typed_data = (byte[]) formatter.format(content,
137: transformer);
138: } catch (FormatException e) {
139: throw new StoreContentDataErrorException(id, e);
140: }
141: } else {
142: typed_data = (byte[]) content.getData();
143: }
144: }
145:
146: return storeTypedData(storeContent, id, typed_data);
147: }
148:
149: protected boolean storeTypedData(Insert storeContent, final int id,
150: final byte[] data) throws ContentManagerException {
151: try {
152: int result = executeUpdate(storeContent,
153: new DbPreparedStatementHandler() {
154: public void setParameters(
155: DbPreparedStatement statement) {
156: statement.setInt("contentId", id);
157: if (null == data) {
158: statement.setNull("content",
159: getNullSqlType()).setInt(
160: getContentSizeColumnName(), 0);
161: } else {
162: statement.setBinaryStream("content",
163: new ByteArrayInputStream(data),
164: data.length).setInt(
165: getContentSizeColumnName(),
166: data.length);
167: }
168: }
169: });
170:
171: return result != -1;
172: } catch (DatabaseException e) {
173: throw new StoreContentDataErrorException(id, e);
174: }
175: }
176:
177: protected int getNullSqlType() {
178: return Types.BLOB;
179: }
180:
181: protected <ResultType> ResultType _useContentData(
182: Select retrieveContent, final int id, ContentDataUser user)
183: throws ContentManagerException {
184: if (id < 0)
185: throw new IllegalArgumentException("id must be positive");
186: if (null == user)
187: throw new IllegalArgumentException("user can't be null");
188:
189: assert retrieveContent != null;
190:
191: try {
192: return (ResultType) user.useContentData(executeQuery(
193: retrieveContent, new DbPreparedStatementHandler() {
194: public void setParameters(
195: DbPreparedStatement statement) {
196: statement.setInt("contentId", id);
197: }
198:
199: public Object concludeResults(
200: DbResultSet resultset)
201: throws SQLException {
202: if (!resultset.next()) {
203: return null;
204: }
205:
206: return resultset.getBytes("content");
207: }
208: }));
209: } catch (DatabaseException e) {
210: throw new UseContentDataErrorException(id, e);
211: }
212: }
213:
214: protected void outputContentColumn(ResultSet resultSet,
215: OutputStream os) throws SQLException {
216: InputStream is = resultSet.getBinaryStream("content");
217: byte[] buffer = new byte[512];
218: BufferedInputStream buffered_raw_is = new BufferedInputStream(
219: is, 512);
220: int size = 0;
221: try {
222: while ((size = buffered_raw_is.read(buffer)) != -1) {
223: os.write(buffer, 0, size);
224: }
225:
226: os.flush();
227: } catch (IOException e) {
228: // don't do anything, the client has probably disconnected
229: }
230: }
231: }
|