[Cosmo-dev] bug: 7127 move ContentItem.content and content*
properties to table fields
Jared Rhine
jared at wordzoo.com
Thu Oct 19 12:16:43 PDT 2006
Please confirm: this patch is a schema change and thus running installations
of Cosmo 0.5-SNAPSHOT should wipe their databases. It goes without saying
that people running 0.5-SNAPSHOT are on their own and can only expect schema
stability/migration support in released versions.
I'm likely to upgrade osaf.us to an svn release prior to r2703, deferring
the r2703 data wipe to avoid stomping on the testing we've asked people to do.
-------- Original Message --------
Subject: [commits-cosmo] (rletness) [2703] bug: 7127 move
ContentItem.content and content* properties to table fields
Date: Wed, 18 Oct 2006 09:26:24 -0700 (PDT)
From: svncheckin at osafoundation.org
To: commits-cosmo at osafoundation.org
Revision
2703 <http://cvs.osafoundation.org/viewcvs.cgi?rev=2703&view=rev>
Author
rletness
Date
2006-10-18 09:26:23 -0700 (Wed, 18 Oct 2006)
Log Message
bug: 7127 move ContentItem.content and content* properties to table fields
ContentItem.contentLength, contentLanguage, contentEncoding, contentType are
now fields in the Item table, instead of stored as Attributes in the
Attribute table.
ContentItem.content is now stored in a separate content_data table, and
only loaded
when needed. Before the data was loaded as part of a propfind. This
should make
propfinds faster and home dir listings faster.
Modified Paths
* cosmo/trunk/src/main/java/org/osaf/cosmo/dao/hibernate/ItemDaoImpl.java
<#cosmotrunksrcmainjavaorgosafcosmodaohibernateItemDaoImpljava>
* cosmo/trunk/src/main/java/org/osaf/cosmo/dav/impl/DavFile.java
<#cosmotrunksrcmainjavaorgosafcosmodavimplDavFilejava>
* cosmo/trunk/src/main/java/org/osaf/cosmo/model/ContentItem.java
<#cosmotrunksrcmainjavaorgosafcosmomodelContentItemjava>
* cosmo/trunk/src/main/resources/applicationContext.xml
<#cosmotrunksrcmainresourcesapplicationContextxml>
* cosmo/trunk/src/main/resources/org/osaf/cosmo/model/ContentItem.hbm.xml
<#cosmotrunksrcmainresourcesorgosafcosmomodelContentItemhbmxml>
* cosmo/trunk/src/test/unit/java/org/osaf/cosmo/test/ContentDaoTest.java
<#cosmotrunksrctestunitjavaorgosafcosmotestContentDaoTestjava>
* cosmo/trunk/src/test/unit/resources/applicationContext-test.xml
<#cosmotrunksrctestunitresourcesapplicationContexttestxml>
Added Paths
* cosmo/trunk/src/main/java/org/osaf/cosmo/model/ContentData.java
<#cosmotrunksrcmainjavaorgosafcosmomodelContentDatajava>
* cosmo/trunk/src/main/resources/org/osaf/cosmo/model/ContentData.hbm.xml
<#cosmotrunksrcmainresourcesorgosafcosmomodelContentDatahbmxml>
Diff
Modified:
cosmo/trunk/src/main/java/org/osaf/cosmo/dao/hibernate/ItemDaoImpl.java
(2702 => 2703)
--- cosmo/trunk/src/main/java/org/osaf/cosmo/dao/hibernate/ItemDaoImpl.java
2006-10-17 22:07:12 UTC (rev 2702)
+++ cosmo/trunk/src/main/java/org/osaf/cosmo/dao/hibernate/ItemDaoImpl.java
2006-10-18 16:26:23 UTC (rev 2703)
@@ -15,6 +15,8 @@
*/
package org.osaf.cosmo.dao.hibernate;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
@@ -36,6 +38,8 @@
import org.osaf.cosmo.model.CalendarPropertyIndex;
import org.osaf.cosmo.model.CalendarTimeRangeIndex;
import org.osaf.cosmo.model.CollectionItem;
+import org.osaf.cosmo.model.ContentData;
+import org.osaf.cosmo.model.ContentItem;
import org.osaf.cosmo.model.DuplicateItemNameException;
import org.osaf.cosmo.model.HomeCollectionItem;
import org.osaf.cosmo.model.Item;
@@ -537,6 +541,20 @@
item2.addAttribute(entry.getValue().copy());
+ // copy content
+ if(item instanceof ContentItem) {
+ ContentItem contentItem = (ContentItem) item;
+ ContentItem newContentItem = (ContentItem) item2;
+ try {
+ InputStream contentStream =
contentItem.getContentInputStream();
+ newContentItem.setContent(contentStream);
+ contentStream.close();
+ } catch (IOException e) {
+ throw new RuntimeException("Error copying content");
+ }
+ }
+
+
// copy calendar indexes
if(item instanceof CalendarItem) {
CalendarItem calendarItem = (CalendarItem) item;
Modified:
cosmo/trunk/src/main/java/org/osaf/cosmo/dav/impl/DavFile.java
(2702 => 2703)
--- cosmo/trunk/src/main/java/org/osaf/cosmo/dav/impl/DavFile.java
2006-10-17 22:07:12 UTC (rev 2702)
+++ cosmo/trunk/src/main/java/org/osaf/cosmo/dav/impl/DavFile.java
2006-10-18 16:26:23 UTC (rev 2703)
@@ -88,11 +88,11 @@
RESOURCE_TYPES = new int[] { ResourceType.DEFAULT_RESOURCE };
- DEAD_PROPERTY_FILTER.add(ContentItem.ATTR_CONTENT_MIMETYPE);
- DEAD_PROPERTY_FILTER.add(ContentItem.ATTR_CONTENT_ENCODING);
- DEAD_PROPERTY_FILTER.add(ContentItem.ATTR_CONTENT_CONTENTLANGUAGE);
- DEAD_PROPERTY_FILTER.add(ContentItem.ATTR_CONTENT_DATA);
- DEAD_PROPERTY_FILTER.add(ContentItem.ATTR_CONTENT_LENGTH);
+ //DEAD_PROPERTY_FILTER.add(ContentItem.ATTR_CONTENT_MIMETYPE);
+ //DEAD_PROPERTY_FILTER.add(ContentItem.ATTR_CONTENT_ENCODING);
+ //DEAD_PROPERTY_FILTER.add(ContentItem.ATTR_CONTENT_CONTENTLANGUAGE);
+ //DEAD_PROPERTY_FILTER.add(ContentItem.ATTR_CONTENT_DATA);
+ //DEAD_PROPERTY_FILTER.add(ContentItem.ATTR_CONTENT_LENGTH);
}
/** */
Added:
cosmo/trunk/src/main/java/org/osaf/cosmo/model/ContentData.java
(2702 => 2703)
--- cosmo/trunk/src/main/java/org/osaf/cosmo/model/ContentData.java
2006-10-17 22:07:12 UTC (rev 2702)
+++ cosmo/trunk/src/main/java/org/osaf/cosmo/model/ContentData.java
2006-10-18 16:26:23 UTC (rev 2703)
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2006 Open Source Applications Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osaf.cosmo.model;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
+
+
+/**
+ * Represents the data of a piece of Content. For now the
+ * data is stored in memory as a byte[]. For the next
+ * release, this will be changed to store the data on
+ * the disk, to prevent OutOfMemoryExceptions.
+ */
+public class ContentData {
+
+ private Long id = new Long(-1);
+ private byte[] content = null;
+
+ /**
+ */
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this,
+ ToStringStyle.MULTI_LINE_STYLE);
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ /**
+ * Get an InputStream to the content data. Repeated
+ * calls to this method will return new instances
+ * of InputStream.
+ * @return
+ */
+ public InputStream getContentInputStream() {
+ if(content==null)
+ return null;
+
+ // For now, return byte[] inputstream, later
+ // this will be a FileInputStream most likely
+ return new ByteArrayInputStream(content);
+ }
+
+ /**
+ * Set the content using an InputSteam. Does not close the
+ * InputStream.
+ * @param is content data
+ * @throws IOException
+ */
+ public void setContentInputStream(InputStream is) throws IOException {
+ // For now use byte[], for .6 use temp File
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ IOUtils.copy(is, bos);
+ content = bos.toByteArray();
+ }
+
+ /**
+ * @return the size of the data read, or -1 for no data present
+ */
+ public long getSize() {
+ if(content != null)
+ return content.length;
+ else
+ return -1;
+ }
+
+ // Hide for Hibernate's use
+ private void setId(Long id) {
+ this.id = id;
+ }
+
+ private byte[] getContent() {
+ return content;
+ }
+
+ private void setContent(byte[] content) {
+ this.content = content;
+ }
+
+}
Modified:
cosmo/trunk/src/main/java/org/osaf/cosmo/model/ContentItem.java
(2702 => 2703)
--- cosmo/trunk/src/main/java/org/osaf/cosmo/model/ContentItem.java
2006-10-17 22:07:12 UTC (rev 2702)
+++ cosmo/trunk/src/main/java/org/osaf/cosmo/model/ContentItem.java
2006-10-18 16:26:23 UTC (rev 2703)
@@ -33,85 +33,125 @@
*/
private static final long serialVersionUID = 4904755977871771389L;
- // ContentItem specific attributes
- public static final String ATTR_CONTENT_MIMETYPE = "content:mimeType";
- public static final String ATTR_CONTENT_ENCODING = "content:encoding";
- public static final String ATTR_CONTENT_CONTENTLANGUAGE =
"content:contentLanguage";
- public static final String ATTR_CONTENT_DATA = "content:data";
- public static final String ATTR_CONTENT_LENGTH = "content:length";
-
// max content size is smaller than binary attribute value max
// size
public static final long MAX_CONTENT_SIZE = 10 * 1024 * 1024;
+ private String contentType = null;
+ private String contentLanguage = null;
+ private String contentEncoding = null;
+ private Long contentLength = null;
+ private ContentData contentData = null;
+
public ContentItem() {
}
+
+ /**
+ * @deprecated use setContent(InputStream)
+ */
public byte[] getContent() {
- return (byte[]) getAttributeValue(ATTR_CONTENT_DATA);
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ InputStream contentStream = contentData.getContentInputStream();
+ IOUtils.copy(contentStream, bos);
+ contentStream.close();
+ return bos.toByteArray();
+ } catch (IOException e) {
+ throw new RuntimeException("Error getting content");
+ }
}
/**
* Sets the ATTR_CONTENT_DATA with the given content, and
ATTR_CONTENT_LENGTH
* with the length of the content
* @param content
+ * @deprecated use getContentInputStream()
*/
public void setContent(byte[] content) {
if (content.length > MAX_CONTENT_SIZE)
throw new DataSizeException("Item content too large");
- setAttribute(ATTR_CONTENT_DATA, content);
- setContentLength((long)content.length);
+
+ if(contentData==null) {
+ contentData = new ContentData();
+ }
+
+ try {
+ setContent(new ByteArrayInputStream(content));
+ } catch (IOException e) {
+ throw new RuntimeException("Error setting content");
+ }
}
+ /**
+ * Set ContentItem's data using InputStream. The provided InputStream
+ * is not closed.
+ * @param is data
+ * @throws IOException
+ */
public void setContent(InputStream is) throws IOException {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- IOUtils.copy(is, bos);
- setContent(bos.toByteArray());
+ if(contentData==null) {
+ contentData = new ContentData();
+ }
+
+ contentData.setContentInputStream(is);
+
+ // Verify size is not greater than MAX.
+ // TODO: do this checking in ContentData.setContentInputStream()
+ if (contentData.getSize() > MAX_CONTENT_SIZE)
+ throw new DataSizeException("Item content too large");
+
+ setContentLength(contentData.getSize());
}
public InputStream getContentInputStream() {
- return new ByteArrayInputStream(getContent());
+ if(contentData==null)
+ return null;
+ else
+ return contentData.getContentInputStream();
}
public String getContentEncoding() {
- return (String) getAttributeValue(ATTR_CONTENT_ENCODING);
+ return contentEncoding;
}
public void setContentEncoding(String contentEncoding) {
- // allow for nulls
- addStringAttribute(ATTR_CONTENT_ENCODING, contentEncoding);
+ this.contentEncoding = contentEncoding;
}
public String getContentLanguage() {
- return (String) getAttributeValue(ATTR_CONTENT_CONTENTLANGUAGE);
+ return contentLanguage;
}
public void setContentLanguage(String contentLanguage) {
- // allow for nulls
- addStringAttribute(ATTR_CONTENT_CONTENTLANGUAGE, contentLanguage);
+ this.contentLanguage = contentLanguage;
}
+ public Long getContentLength() {
+ return contentLength;
+ }
+
+
+ public void setContentLength(Long contentLength) {
+ this.contentLength = contentLength;
+ }
+
+
public String getContentType() {
- return (String) getAttributeValue(ATTR_CONTENT_MIMETYPE);
+ return contentType;
}
+
public void setContentType(String contentType) {
- setAttribute(ATTR_CONTENT_MIMETYPE, contentType);
+ this.contentType = contentType;
}
- public Long getContentLength() {
- return (Long) getAttributeValue(ATTR_CONTENT_LENGTH);
- }
public void validate() {
super.validate();
validateContent();
}
-
- protected void setContentLength(Long contentLength) {
- setAttribute(ATTR_CONTENT_LENGTH, contentLength);
- }
-
+
protected void validateContent() {
if (getContentLength() == null)
throw new ModelValidationException("Content Length must be
present");
@@ -119,10 +159,10 @@
if (getContentLength().longValue() < 0)
throw new ModelValidationException("Content Length must be >= 0");
- if (getContent() == null)
+ if (getContentData() == null)
throw new ModelValidationException("Content must be present");
- if (getContent().length != getContentLength().longValue())
+ if (getContentData().getSize() != getContentLength().longValue())
throw new ModelValidationException(
"Content Length doesn't match Content");
}
@@ -136,6 +176,15 @@
getContentEncoding()).append("contentLanguage",
getContentLanguage()).toString();
}
+
+ // For hibernate use only
+ private ContentData getContentData() {
+ return contentData;
+ }
+ // For hibernate use only
+ private void setContentData(ContentData contentFile) {
+ this.contentData = contentFile;
+ }
}
Modified: cosmo/trunk/src/main/resources/applicationContext.xml
(2702 => 2703)
--- cosmo/trunk/src/main/resources/applicationContext.xml 2006-10-17
22:07:12 UTC (rev 2702)
+++ cosmo/trunk/src/main/resources/applicationContext.xml 2006-10-18
16:26:23 UTC (rev 2703)
@@ -83,6 +83,7 @@
<value>org/osaf/cosmo/model/CollectionItem.hbm.xml</value>
<value>org/osaf/cosmo/model/HomeCollectionItem.hbm.xml</value>
<value>org/osaf/cosmo/model/ContentItem.hbm.xml</value>
+ <value>org/osaf/cosmo/model/ContentData.hbm.xml</value>
<value>org/osaf/cosmo/model/CalendarCollectionItem.hbm.xml</value>
<value>org/osaf/cosmo/model/CalendarItem.hbm.xml</value>
<value>org/osaf/cosmo/model/CalendarEventItem.hbm.xml</value>
Added:
cosmo/trunk/src/main/resources/org/osaf/cosmo/model/ContentData.hbm.xml
(2702 => 2703)
--- cosmo/trunk/src/main/resources/org/osaf/cosmo/model/ContentData.hbm.xml
2006-10-17 22:07:12 UTC (rev 2702)
+++ cosmo/trunk/src/main/resources/org/osaf/cosmo/model/ContentData.hbm.xml
2006-10-18 16:26:23 UTC (rev 2703)
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+ Copyright 2005,2006 Open Source Applications Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Generated Jul 17, 2006 11:59:26 AM by Hibernate Tools 3.1.0.beta5 -->
+<hibernate-mapping package="org.osaf.cosmo.model">
+
+ <class name="ContentData" table="content_data">
+
+ <id name="id" column="id" unsaved-value="-1">
+ <generator class="native" />
+ </id>
+
+ <property name="content" column="content"
type="org.osaf.cosmo.hibernate.BinaryBlobType" length="102400000"/>
+
+ </class>
+
+
+</hibernate-mapping>
Modified:
cosmo/trunk/src/main/resources/org/osaf/cosmo/model/ContentItem.hbm.xml
(2702 => 2703)
--- cosmo/trunk/src/main/resources/org/osaf/cosmo/model/ContentItem.hbm.xml
2006-10-17 22:07:12 UTC (rev 2702)
+++ cosmo/trunk/src/main/resources/org/osaf/cosmo/model/ContentItem.hbm.xml
2006-10-18 16:26:23 UTC (rev 2703)
@@ -21,6 +21,23 @@
<hibernate-mapping package="org.osaf.cosmo.model">
<subclass name="ContentItem" extends="Item"
discriminator-value="content" lazy="false">
-
+
+ <property name="contentEncoding" type="string">
+ <column name="contentEncoding" length="32"/>
+ </property>
+ <property name="contentLanguage" type="string">
+ <column name="contentLanguage" length="32"/>
+ </property>
+ <property name="contentType" type="string">
+ <column name="contentType" length="64"/>
+ </property>
+ <property name="contentLength" type="long">
+ <column name="contentLength"/>
+ </property>
+
+ <many-to-one name="contentData" class="ContentData"
+ column="contentdataid"
+ cascade="all" />
+
</subclass>
</hibernate-mapping>
Modified:
cosmo/trunk/src/test/unit/java/org/osaf/cosmo/test/ContentDaoTest.java
(2702 => 2703)
--- cosmo/trunk/src/test/unit/java/org/osaf/cosmo/test/ContentDaoTest.java
2006-10-17 22:07:12 UTC (rev 2702)
+++ cosmo/trunk/src/test/unit/java/org/osaf/cosmo/test/ContentDaoTest.java
2006-10-18 16:26:23 UTC (rev 2703)
@@ -98,21 +98,21 @@
item.setContentLanguage("en");
item.setContentEncoding("UTF8");
item.setContentType("text/text");
- item.removeAttribute(ContentItem.ATTR_CONTENT_LENGTH);
+ item.setContentLength(null);
try {
contentDao.createContent(root, item);
Assert.fail("able to create invalid content.");
} catch (ModelValidationException e) {}
- item.setAttribute(ContentItem.ATTR_CONTENT_LENGTH,(new Long(-1)));
+ item.setContentLength(new Long(-1));
try {
contentDao.createContent(root, item);
Assert.fail("able to create invalid content.");
} catch (ModelValidationException e) {}
- item.setAttribute(ContentItem.ATTR_CONTENT_LENGTH,(new Long(1)));
+ item.setContentLength(new Long(1));
try {
contentDao.createContent(root, item);
Modified:
cosmo/trunk/src/test/unit/resources/applicationContext-test.xml
(2702 => 2703)
--- cosmo/trunk/src/test/unit/resources/applicationContext-test.xml
2006-10-17 22:07:12 UTC (rev 2702)
+++ cosmo/trunk/src/test/unit/resources/applicationContext-test.xml
2006-10-18 16:26:23 UTC (rev 2703)
@@ -53,6 +53,7 @@
<value>org/osaf/cosmo/model/CollectionItem.hbm.xml</value>
<value>org/osaf/cosmo/model/HomeCollectionItem.hbm.xml</value>
<value>org/osaf/cosmo/model/ContentItem.hbm.xml</value>
+ <value>org/osaf/cosmo/model/ContentData.hbm.xml</value>
<value>org/osaf/cosmo/model/CalendarCollectionItem.hbm.xml</value>
<value>org/osaf/cosmo/model/CalendarItem.hbm.xml</value>
<value>org/osaf/cosmo/model/CalendarEventItem.hbm.xml</value>
More information about the cosmo-dev
mailing list