bloritsch 01/02/23 13:36:38
Modified: src/org/apache/cocoon/acting Tag: xml-cocoon2
ImageUploadAction.java
src/org/apache/cocoon/reading Tag: xml-cocoon2
ResourceReader.java
Added: src/org/apache/cocoon/reading Tag: xml-cocoon2
DatabaseReader.java
Log:
Added "last-modified" timestamp reporting for ImageUploadAction, Added a
database resource reader, and changed formatting on the ResourceReader.
Revision Changes Path
No revision
No revision
1.1.2.3 +75 -6
xml-cocoon/src/org/apache/cocoon/acting/Attic/ImageUploadAction.java
Index: ImageUploadAction.java
===================================================================
RCS file:
/home/cvs/xml-cocoon/src/org/apache/cocoon/acting/Attic/ImageUploadAction.java,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- ImageUploadAction.java 2001/02/22 20:57:35 1.1.2.2
+++ ImageUploadAction.java 2001/02/23 21:36:37 1.1.2.3
@@ -10,8 +10,10 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.sql.Timestamp;
import java.sql.SQLException;
import java.util.Map;
+import java.util.Date;
import java.io.InputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -46,7 +48,7 @@
* at this time.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
- * @version CVS $Revision: 1.1.2.2 $ $Date: 2001/02/22 20:57:35 $
+ * @version CVS $Revision: 1.1.2.3 $ $Date: 2001/02/23 21:36:37 $
*/
public class ImageUploadAction extends ComposerAction implements
Contextualizable {
private final static int SIZE = 0;
@@ -66,6 +68,10 @@
private String database;
private File workDir;
+ /**
+ * Configure the <code>Action</code> so that we can use the same database
+ * for all instances.
+ */
public void configure(Configuration conf) throws ConfigurationException {
super.configure(conf);
@@ -81,10 +87,45 @@
}
}
+ /**
+ * Uses the passed <code>Context</code> to find the upload directory.
+ * NOTE: This might not be necessary any longer.
+ *
+ * <pre>
+ * <parameter name="table" value="database_table_name"/>
+ * <parameter name="image"
value="database_resource_column_name"/>
+ * <parameter name="file-param"
value="request_parameter_that_has_image"/>
+ * </pre>
+ *
+ * Please note that if any of those parameters are missing, this
+ * <code>Reader</code> cannot function. There are a number of other
+ * parameters that allow you to provide hints for the reader to
+ * optimize resource use:
+ *
+ * <pre>
+ * <parameter name="image-size"
value="database_image_size_column_name"/>
+ * <parameter name="image-width"
value="database_image_width_column_name"/>
+ * <parameter name="image-height"
value="database_image_height_column_name"/>
+ * <parameter name="key"
value="database_lookup_key_column_name"/>
+ * <parameter name="last-modified"
value="database_timestamp_column_name"/>
+ * </pre>
+ *
+ * Lastly, the <code>key</code> value is derived from the value of
+ * the <code>source</code> string.
+ *
+ * The image attributes are automatically derived from the image itself,
+ * but only included in the database if the attributes are set to
+ * column names in the table.
+ */
public void contextualize(Context context) {
this.workDir = new File((File)
context.get(Constants.CONTEXT_WORK_DIR), "image-dir" + File.separator);
}
+ /**
+ * Process the request and populate the database records with the
+ * uploaded image and it's associated attributes. Please note that
+ * there are several required parameters to use this action:
+ */
public Map act(EntityResolver resolver, Map objectModel, String source,
Parameters param) throws Exception {
DataSourceComponent datasource = (DataSourceComponent)
this.dbselector.select(this.database);
Connection conn = datasource.getConnection();
@@ -93,6 +134,7 @@
String table = param.getParameter("table", null);
String column = param.getParameter("image", null);
String keycol = param.getParameter("key", null);
+ String lastModified = param.getParameter("last-modified", null);
if (table == null || column == null) {
throw new ProcessingException("Cannot insert into a null
table/column");
@@ -114,9 +156,9 @@
String query;
if (keycol == null || source == null) {
- query = this.setupInsertQuery(table, column, paramColumns,
paramPositions);
+ query = this.setupInsertQuery(table, column, paramColumns,
paramPositions, lastModified);
} else {
- query = this.setupUpdateQuery(table, column, paramColumns,
paramPositions, keycol, source);
+ query = this.setupUpdateQuery(table, column, paramColumns,
paramPositions, lastModified, keycol, source);
}
File image = null;
@@ -141,8 +183,13 @@
}
}
+ if (lastModified != null) {
+ maxIndex++;
+ statement.setTimestamp(maxIndex, new Timestamp(new
Date().getTime()));
+ }
+
if (keycol != null && source != null) {
- statement.setString(maxIndex, source);
+ statement.setString(maxIndex + 1, source);
}
statement.execute();
@@ -163,7 +210,12 @@
return null;
}
- String setupInsertQuery(String table, String column, String[]
paramNames, int[] paramPositions) {
+ /**
+ * Sets up the query string to insert the data into a database.
+ * The query assumes all information is in one table, and that
+ * the indexes are derived automatically.
+ */
+ String setupInsertQuery(String table, String column, String[]
paramNames, int[] paramPositions, String lastModified) {
StringBuffer query = new StringBuffer("INSERT INTO ");
query.append(table).append(" (").append(column);
@@ -173,6 +225,10 @@
}
}
+ if (lastModified != null) {
+ query.append(", ").append(lastModified);
+ }
+
query.append(") VALUES (?");
int index = 2;
@@ -187,12 +243,21 @@
}
}
+ if (lastModified != null) {
+ query.append(", ?");
+ }
+
query.append(")");
return query.toString();
}
- String setupUpdateQuery(String table, String column, String[]
paramNames, int[] paramPositions, String keyColumn, String key) {
+ /**
+ * Sets up the query to update an existing image. The query assumes
+ * that all the information resides in the same table, and that the
+ * key is not a compound key.
+ */
+ String setupUpdateQuery(String table, String column, String[]
paramNames, int[] paramPositions, String lastModified, String keyColumn, String
key) {
StringBuffer query = new StringBuffer("UPDATE ");
query.append(table).append(" SET ").append(column).append(" = ?");
int index = 2;
@@ -205,6 +270,10 @@
} else {
paramPositions[i] = -1;
}
+ }
+
+ if (lastModified != null) {
+ query.append(", ").append(lastModified).append(" = ?");
}
query.append(" WHERE ").append(keyColumn).append(" = ?");
No revision
No revision
1.1.2.20 +29 -12
xml-cocoon/src/org/apache/cocoon/reading/Attic/ResourceReader.java
Index: ResourceReader.java
===================================================================
RCS file:
/home/cvs/xml-cocoon/src/org/apache/cocoon/reading/Attic/ResourceReader.java,v
retrieving revision 1.1.2.19
retrieving revision 1.1.2.20
diff -u -r1.1.2.19 -r1.1.2.20
--- ResourceReader.java 2001/02/23 14:01:27 1.1.2.19
+++ ResourceReader.java 2001/02/23 21:36:37 1.1.2.20
@@ -17,6 +17,7 @@
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.Date;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
@@ -37,7 +38,7 @@
/**
*
* @author <a href="mailto:[EMAIL PROTECTED]">Giacomo Pati</a>
- * @version CVS $Revision: 1.1.2.19 $ $Date: 2001/02/23 14:01:27 $
+ * @version CVS $Revision: 1.1.2.20 $ $Date: 2001/02/23 21:36:37 $
*
* The <code>ResourceReader</code> component is used to serve binary data
* in a sitemap pipeline. It makes use of HTTP Headers to determine if
@@ -77,36 +78,41 @@
}
if (res == null) {
- this.manager.release((Component) urlFactory);
throw new ProcessingException ("Missing a Response object in the
objectModel");
}
+
if (req == null) {
- this.manager.release((Component) urlFactory);
throw new ProcessingException ("Missing a Request object in the
objectModel");
}
+
String src = null;
File file = null;
URL url = null;
URLConnection conn = null;
InputStream is = null;
long len = 0;
+
try {
if(this.source.indexOf(":/") != -1) {
src = this.source;
url = urlFactory.getURL (src);
conn = url.openConnection();
+
if (!modified (conn.getLastModified(), req, res)) {
return;
}
+
len = conn.getContentLength();
is = conn.getInputStream();
} else {
src = this.resolver.resolveEntity
(null,this.source).getSystemId();
url = urlFactory.getURL (src);
file = new File (url.getFile());
+
if (!modified (file.lastModified(), req, res)) {
return;
}
+
len = file.length();
is = new FileInputStream (file);
}
@@ -121,16 +127,24 @@
} finally {
this.manager.release((Component) urlFactory);
}
- byte[] buffer = new byte[(int)len];
- is.read(buffer);
- is.close();
- res.setContentLength(buffer.length);
- long expires = parameters.getParameterAsInteger("expires", -1);
- if (expires > 0) {
- res.setDateHeader("Expires", System.currentTimeMillis()+expires);
+
+ try {
+ byte[] buffer = new byte[(int)len];
+ is.read(buffer);
+ is.close();
+ res.setContentType(this.getMimeType());
+ res.setContentLength(buffer.length);
+ long expires = parameters.getParameterAsInteger("expires", -1);
+
+ if (expires > 0) {
+ res.setDateHeader("Expires", new Date().getTime() + expires);
+ }
+
+ res.setHeader("Accept-Ranges", "bytes");
+ out.write ( buffer );
+ } catch (IOException ioe) {
+ getLogger().debug("Received an IOException, assuming client
severed connection on purpose");
}
- res.setHeader("Accept-Ranges", "bytes");
- out.write ( buffer );
}
/**
@@ -139,9 +153,11 @@
private boolean modified (long lastModified, HttpServletRequest req,
HttpServletResponse res) {
res.setDateHeader("Last-Modified", lastModified);
long if_modified_since = req.getDateHeader("if-modified-since");
+
if (if_modified_since >= lastModified) {
res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
+
getLogger().debug("ResourceReader: resource has " +
((if_modified_since < lastModified) ? "" : "not ") + "been modified");
return (if_modified_since < lastModified);
}
@@ -151,6 +167,7 @@
*/
public String getMimeType () {
ServletContext ctx = (ServletContext) objectModel.get("context");
+
if (ctx != null) {
return ctx.getMimeType(this.source);
} else {
No revision
No revision
1.1.2.1 +211 -0
xml-cocoon/src/org/apache/cocoon/reading/Attic/DatabaseReader.java