Repository: isis
Updated Branches:
  refs/heads/master 3c23f0992 -> d99641d06


ISIS-714, ISIS-788: further fixes for blobs and clobs in DataNucleus.

- for ISIS-714, the clob/blob stuff was still broken
   - improve the IsisClobPanel, new implemenation of Wicket's IResource 
(CharSequenceResource) so preserve name and media-type.
- for ISIS-788, removed the redundant Isis{Blob/Clob}Converter classes


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/d99641d0
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/d99641d0
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/d99641d0

Branch: refs/heads/master
Commit: d99641d068a226a28bf2c8b9e20f2d2446ce6d56
Parents: 3c23f09
Author: Dan Haywood <[email protected]>
Authored: Mon May 26 10:27:25 2014 +0100
Committer: Dan Haywood <[email protected]>
Committed: Mon May 26 10:27:25 2014 +0100

----------------------------------------------------------------------
 .../valuemappings/IsisBlobRDBMSMapping.java     |  48 +++++++
 .../valuetypes/IsisBlobConverter.java           |  46 -------
 .../datanucleus/valuetypes/IsisBlobMapping.java |  14 +-
 .../valuetypes/IsisClobConverter.java           |  46 -------
 .../datanucleus/valuetypes/IsisClobMapping.java |  15 ++-
 .../valuetypes/IsisDateConverter.java           |  19 ---
 .../src/main/resources/plugin.xml               |  26 ++--
 .../isisapplib/CharSequenceResource.java        | 120 +++++++++++++++++
 .../scalars/isisapplib/IsisBlobPanel.java       |   8 +-
 .../scalars/isisapplib/IsisClobPanel.java       |  15 +--
 .../scalars/isisapplib/IsisColorPanel.java      |   2 +-
 .../dom/src/main/java/dom/todo/ToDoItem.java    | 130 ++++++++-----------
 .../src/main/java/dom/todo/ToDoItem.layout.json |   5 +
 .../webapp/pom.xml                              |   2 +-
 14 files changed, 263 insertions(+), 233 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuemappings/IsisBlobRDBMSMapping.java
----------------------------------------------------------------------
diff --git 
a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuemappings/IsisBlobRDBMSMapping.java
 
b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuemappings/IsisBlobRDBMSMapping.java
new file mode 100644
index 0000000..f729edb
--- /dev/null
+++ 
b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuemappings/IsisBlobRDBMSMapping.java
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.isis.objectstore.jdo.datanucleus.valuemappings;
+
+import org.datanucleus.store.rdbms.RDBMSStoreManager;
+import org.datanucleus.store.rdbms.mapping.datastore.BlobRDBMSMapping;
+import org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping;
+import org.datanucleus.store.rdbms.table.Column;
+
+public class IsisBlobRDBMSMapping extends BlobRDBMSMapping {
+
+    public IsisBlobRDBMSMapping(JavaTypeMapping mapping, RDBMSStoreManager 
storeMgr, Column col) {
+        super(mapping, storeMgr, col);
+    }
+
+    @Override
+    public JavaTypeMapping getJavaTypeMapping() {
+        final JavaTypeMapping javaTypeMapping = super.getJavaTypeMapping();
+        return javaTypeMapping;
+    }
+
+    protected Object getObjectForBytes(byte[] bytes, int param) {
+        if(param == 3) {
+            // JDBC is 1-based.
+            return bytes;
+        } else {
+            return super.getObjectForBytes(bytes, param);
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisBlobConverter.java
----------------------------------------------------------------------
diff --git 
a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisBlobConverter.java
 
b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisBlobConverter.java
deleted file mode 100644
index a5c1f4f..0000000
--- 
a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisBlobConverter.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you 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.apache.isis.objectstore.jdo.datanucleus.valuetypes;
-
-import org.datanucleus.store.types.converters.TypeConverter;
-
-import org.apache.isis.applib.adapters.EncoderDecoder;
-import org.apache.isis.applib.value.Blob;
-import 
org.apache.isis.core.progmodel.facets.value.blobs.BlobValueSemanticsProvider;
-
-public class IsisBlobConverter implements TypeConverter<Blob, String>{
-
-    private static final long serialVersionUID = 1L;
-    private EncoderDecoder<Blob> encoderDecoder;
-
-    public IsisBlobConverter() {
-        encoderDecoder = new BlobValueSemanticsProvider().getEncoderDecoder();
-    }
-    
-    @Override
-    public String toDatastoreType(Blob memberValue) {
-        return encoderDecoder.toEncodedString(memberValue);
-    }
-
-    @Override
-    public Blob toMemberType(String datastoreValue) {
-        return encoderDecoder.fromEncodedString(datastoreValue);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisBlobMapping.java
----------------------------------------------------------------------
diff --git 
a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisBlobMapping.java
 
b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisBlobMapping.java
index 8776d9e..bdbb61d 100644
--- 
a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisBlobMapping.java
+++ 
b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisBlobMapping.java
@@ -20,7 +20,6 @@ package 
org.apache.isis.objectstore.jdo.datanucleus.valuetypes;
 
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
-
 import org.datanucleus.ClassLoaderResolver;
 import org.datanucleus.ClassNameConstants;
 import org.datanucleus.ExecutionContext;
@@ -29,7 +28,6 @@ import org.datanucleus.metadata.AbstractMemberMetaData;
 import org.datanucleus.store.rdbms.RDBMSStoreManager;
 import org.datanucleus.store.rdbms.mapping.java.SingleFieldMultiMapping;
 import org.datanucleus.store.rdbms.table.Table;
-
 import org.apache.isis.applib.value.Blob;
 
 public class IsisBlobMapping extends SingleFieldMultiMapping {
@@ -58,7 +56,8 @@ public class IsisBlobMapping extends SingleFieldMultiMapping {
     {
         addColumns(ClassNameConstants.JAVA_LANG_STRING); // name
         addColumns(ClassNameConstants.JAVA_LANG_STRING); // mime type
-        addColumns(ClassNameConstants.JAVA_IO_SERIALIZABLE); // bytes
+        // this mapping type isn't supported out-of-the-box by DN, so instead 
we register IsisBlobRDBMSMapping
+        addColumns(ClassNameConstants.BYTE_ARRAY); // bytes
     }
 
     public Object getValueForDatastoreMapping(NucleusContext nucleusCtx, int 
index, Object value)
@@ -101,9 +100,12 @@ public class IsisBlobMapping extends 
SingleFieldMultiMapping {
             // Do nothing
         }
 
-        String name = getDatastoreMapping(0).getString(resultSet, 
exprIndex[0]); 
-        String mimeTypeBase = getDatastoreMapping(1).getString(resultSet, 
exprIndex[1]); 
-        byte[] bytes = (byte[]) 
getDatastoreMapping(2).getObject(resultSet,exprIndex[2]); 
+        final String name = getDatastoreMapping(0).getString(resultSet, 
exprIndex[0]);
+        final String mimeTypeBase = 
getDatastoreMapping(1).getString(resultSet, exprIndex[1]);
+        final byte[] bytes = (byte[]) 
getDatastoreMapping(2).getObject(resultSet, exprIndex[2]);
+        if(name == null || mimeTypeBase == null || bytes == null) {
+            return null;
+        }
         return new Blob(name, mimeTypeBase, bytes);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisClobConverter.java
----------------------------------------------------------------------
diff --git 
a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisClobConverter.java
 
b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisClobConverter.java
deleted file mode 100644
index 55544f8..0000000
--- 
a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisClobConverter.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you 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.apache.isis.objectstore.jdo.datanucleus.valuetypes;
-
-import org.datanucleus.store.types.converters.TypeConverter;
-
-import org.apache.isis.applib.adapters.EncoderDecoder;
-import org.apache.isis.applib.value.Clob;
-import 
org.apache.isis.core.progmodel.facets.value.clobs.ClobValueSemanticsProvider;
-
-public class IsisClobConverter implements TypeConverter<Clob, String>{
-
-    private static final long serialVersionUID = 1L;
-    private EncoderDecoder<Clob> encoderDecoder;
-
-    public IsisClobConverter() {
-        encoderDecoder = new ClobValueSemanticsProvider().getEncoderDecoder();
-    }
-    
-    @Override
-    public String toDatastoreType(Clob memberValue) {
-        return encoderDecoder.toEncodedString(memberValue);
-    }
-
-    @Override
-    public Clob toMemberType(String datastoreValue) {
-        return encoderDecoder.fromEncodedString(datastoreValue);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisClobMapping.java
----------------------------------------------------------------------
diff --git 
a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisClobMapping.java
 
b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisClobMapping.java
index 6d2a9b8..dc659da 100644
--- 
a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisClobMapping.java
+++ 
b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisClobMapping.java
@@ -58,7 +58,7 @@ public class IsisClobMapping extends SingleFieldMultiMapping {
     {
         addColumns(ClassNameConstants.JAVA_LANG_STRING); // name
         addColumns(ClassNameConstants.JAVA_LANG_STRING); // mime type
-        addColumns(ClassNameConstants.JAVA_LANG_CHARACTER_ARRAY); // chars
+        addColumns(ClassNameConstants.JAVA_LANG_STRING); // chars
     }
 
     public Object getValueForDatastoreMapping(NucleusContext nucleusCtx, int 
index, Object value)
@@ -82,7 +82,7 @@ public class IsisClobMapping extends SingleFieldMultiMapping {
         } else {
             getDatastoreMapping(0).setString(preparedStmt, exprIndex[0], 
clob.getName());
             getDatastoreMapping(1).setString(preparedStmt, exprIndex[1], 
clob.getMimeType().getBaseType());
-            getDatastoreMapping(2).setObject(preparedStmt, exprIndex[2], 
clob.getChars());
+            getDatastoreMapping(2).setObject(preparedStmt, exprIndex[2], 
clob.getChars().toString());
         }
     }
     
@@ -101,9 +101,12 @@ public class IsisClobMapping extends 
SingleFieldMultiMapping {
             // Do nothing
         }
 
-        String name = getDatastoreMapping(0).getString(resultSet, 
exprIndex[0]); 
-        String mimeTypeBase = getDatastoreMapping(1).getString(resultSet, 
exprIndex[1]); 
-        char[] chars = (char[]) 
getDatastoreMapping(2).getObject(resultSet,exprIndex[2]); 
-        return new Clob(name, mimeTypeBase, chars);
+        final String name = getDatastoreMapping(0).getString(resultSet, 
exprIndex[0]);
+        final String mimeTypeBase = 
getDatastoreMapping(1).getString(resultSet, exprIndex[1]);
+        final String str = getDatastoreMapping(2).getString(resultSet, 
exprIndex[2]);
+        if(name == null || mimeTypeBase == null || str == null) {
+            return null;
+        }
+        return new Clob(name, mimeTypeBase, str.toCharArray());
     }
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisDateConverter.java
----------------------------------------------------------------------
diff --git 
a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisDateConverter.java
 
b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisDateConverter.java
index f658fc9..4bcbf23 100644
--- 
a/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisDateConverter.java
+++ 
b/component/objectstore/jdo/jdo-datanucleus/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/valuetypes/IsisDateConverter.java
@@ -27,27 +27,8 @@ public class IsisDateConverter implements 
TypeConverter<Date, Long>{
     private static final long serialVersionUID = 1L;
 
     public IsisDateConverter() {
-        
     }
     
-//    @Override
-//    public Long toLong(Date object) {
-//        if(object == null) {
-//            return null;
-//        }
-//
-//        Date d = (Date)object;
-//        return d.getMillisSinceEpoch();
-//    }
-//
-//    @Override
-//    public Date toObject(Long value) {
-//        if(value == null) {
-//            return null;
-//        }
-//        return new Date(value);
-//    }
-
     @Override
     public Long toDatastoreType(Date memberValue) {
         if(memberValue == null) {

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/component/objectstore/jdo/jdo-datanucleus/src/main/resources/plugin.xml
----------------------------------------------------------------------
diff --git 
a/component/objectstore/jdo/jdo-datanucleus/src/main/resources/plugin.xml 
b/component/objectstore/jdo/jdo-datanucleus/src/main/resources/plugin.xml
index 120da65..863b71f 100644
--- a/component/objectstore/jdo/jdo-datanucleus/src/main/resources/plugin.xml
+++ b/component/objectstore/jdo/jdo-datanucleus/src/main/resources/plugin.xml
@@ -37,9 +37,20 @@
         <mapping 
             java-type="org.apache.isis.applib.value.Clob" 
             
mapping-class="org.apache.isis.objectstore.jdo.datanucleus.valuetypes.IsisClobMapping"/>
-
     </extension>
 
+
+    <extension point="org.datanucleus.store.rdbms.rdbms_mapping">
+        <mapping java-type="[B" jdbc-type="BLOB" sql-type="BLOB" default="true"
+                 
rdbms-mapping-class="org.apache.isis.objectstore.jdo.datanucleus.valuemappings.IsisBlobRDBMSMapping">
+        </mapping>
+        <mapping java-type="[Ljava.lang.Byte;" jdbc-type="BLOB" 
sql-type="BLOB" default="true"
+                 
rdbms-mapping-class="org.apache.isis.objectstore.jdo.datanucleus.valuemappings.IsisBlobRDBMSMapping">
+        </mapping>
+    </extension>
+    <!--
+    to support 
http://www.datanucleus.org/products/accessplatform/jdo/types.html#typeconverter
+    -->
     <extension point="org.datanucleus.java_type">
         <java-type 
                name="org.apache.isis.applib.value.Date" 
@@ -53,19 +64,6 @@
             dfg="true" 
             embedded="true"
             
long-converter="org.apache.isis.objectstore.jdo.datanucleus.valuetypes.IsisDateTimeConverter"/>
-
-        <java-type 
-            name="org.apache.isis.applib.value.Blob" 
-            persistent="true" 
-            dfg="false" 
-            embedded="true"
-            
string-converter="org.apache.isis.objectstore.jdo.datanucleus.valuetypes.IsisBlobConverter"/>
-        <java-type 
-            name="org.apache.isis.applib.value.Clob" 
-            persistent="true" 
-            dfg="false" 
-            embedded="true"
-            
string-converter="org.apache.isis.objectstore.jdo.datanucleus.valuetypes.IsisClobConverter"/>
     </extension>
 
 </plugin>

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/CharSequenceResource.java
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/CharSequenceResource.java
 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/CharSequenceResource.java
new file mode 100644
index 0000000..36cd077
--- /dev/null
+++ 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/CharSequenceResource.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.isis.viewer.wicket.ui.components.scalars.isisapplib;
+
+import java.net.URLConnection;
+import org.apache.wicket.request.resource.AbstractResource;
+import org.apache.wicket.request.resource.ContentDisposition;
+import org.apache.wicket.util.time.Time;
+
+/**
+ * Adapted from {@link org.apache.wicket.request.resource.ByteArrayResource}
+ */
+public class CharSequenceResource extends AbstractResource {
+    private static final long serialVersionUID = 1L;
+
+    /** the content type. */
+    private final String contentType;
+
+    private CharSequence chars;
+
+    /** the time that this resource was last modified; same as construction 
time. */
+    private final Time lastModified = Time.now();
+
+    private final String filename;
+
+    public CharSequenceResource(final String contentType, final CharSequence 
chars, final String filename)
+    {
+        this.contentType = contentType;
+        this.chars = chars;
+        this.filename = filename;
+    }
+
+    protected void configureResponse(final ResourceResponse response, final 
Attributes attributes)
+    {
+    }
+
+    /**
+     * @see 
org.apache.wicket.request.resource.AbstractResource#newResourceResponse(org.apache.wicket.request.resource.IResource.Attributes)
+     */
+    @Override
+    protected ResourceResponse newResourceResponse(final Attributes attributes)
+    {
+        final ResourceResponse response = new ResourceResponse();
+
+        String contentType = this.contentType;
+
+        if (contentType == null)
+        {
+            if (filename != null)
+            {
+                contentType = 
URLConnection.getFileNameMap().getContentTypeFor(filename);
+            }
+
+            if (contentType == null)
+            {
+                contentType = "application/octet-stream";
+            }
+        }
+
+
+        response.setContentType(contentType);
+        response.setLastModified(lastModified);
+
+        final CharSequence data = getData(attributes);
+        if (data == null)
+        {
+            response.setError(404 /* HttpServletResponse.SC_NOT_FOUND */);
+        }
+        else
+        {
+            response.setContentLength(data.length());
+
+            if (response.dataNeedsToBeWritten(attributes))
+            {
+                if (filename != null)
+                {
+                    response.setFileName(filename);
+                    
response.setContentDisposition(ContentDisposition.ATTACHMENT);
+                }
+                else
+                {
+                    response.setContentDisposition(ContentDisposition.INLINE);
+                }
+
+                response.setWriteCallback(new WriteCallback()
+                {
+                    @Override
+                    public void writeData(final Attributes attributes)
+                    {
+                        //attributes.getResponse().write(data);
+                        attributes.getResponse().write(data);
+                    }
+                });
+
+                configureResponse(response, attributes);
+            }
+        }
+
+        return response;
+    }
+
+    protected CharSequence getData(final Attributes attributes)
+    {
+        return chars;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobPanel.java
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobPanel.java
 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobPanel.java
index ee2420b..0578f35 100644
--- 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobPanel.java
+++ 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobPanel.java
@@ -21,16 +21,14 @@ package 
org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib;
 
 
 import java.util.List;
-
-import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.markup.html.form.upload.FileUpload;
 import org.apache.wicket.request.resource.ByteArrayResource;
-
+import org.apache.wicket.request.resource.IResource;
 import org.apache.isis.applib.value.Blob;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 
 /**
- * Panel for rendering scalars of type {@link Blob Isis' applib.Blob}.
+ * Panel for rendering scalars of type {@link 
org.apache.isis.applib.value.Blob Isis' applib.Blob}.
  */
 public class IsisBlobPanel extends IsisBlobOrClobPanelAbstract<Blob> {
 
@@ -50,7 +48,7 @@ public class IsisBlobPanel extends 
IsisBlobOrClobPanelAbstract<Blob> {
         return blob;
     }
 
-    protected ByteArrayResource newResource(final Blob blob) {
+    protected IResource newResource(final Blob blob) {
         return new ByteArrayResource(blob.getMimeType().getBaseType(), 
blob.getBytes(), blob.getName());
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisClobPanel.java
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisClobPanel.java
 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisClobPanel.java
index 9ec5b0a..546fda3 100644
--- 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisClobPanel.java
+++ 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisClobPanel.java
@@ -27,25 +27,21 @@ import com.google.common.base.Charsets;
 
 import org.apache.wicket.markup.html.form.upload.FileUpload;
 import org.apache.wicket.request.resource.IResource;
-import org.apache.wicket.request.resource.ResourceStreamResource;
-import org.apache.wicket.util.resource.StringResourceStream;
 
 import org.apache.isis.applib.value.Clob;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 
 /**
  * Panel for rendering scalars of type {@link Clob Isis' applib.Clob}.
+ *
+ * <p>
+ *    TODO: for now, this only handles CLOBs encoded as UTF-8.  One option 
might be to 'guess' the character encoding, eg akin to cpdetector?
+ * </p>
  */
 public class IsisClobPanel extends IsisBlobOrClobPanelAbstract<Clob> {
 
     private static final long serialVersionUID = 1L;
     
-    /**
-     * TODO: for now, this only handles CLOBs encoded as UTF-8.
-     * 
-     * <p>
-     * One option might be to 'guess' the character encoding, eg akin to 
cpdetector?
-     */
     private static final Charset CHARSET = Charsets.UTF_8;
 
     public IsisClobPanel(final String id, final ScalarModel model) {
@@ -62,8 +58,7 @@ public class IsisClobPanel extends 
IsisBlobOrClobPanelAbstract<Clob> {
     }
 
     protected IResource newResource(final Clob clob) {
-        return new ResourceStreamResource(new 
StringResourceStream(clob.getChars(), clob.getMimeType().getBaseType()));
+        return new CharSequenceResource(clob.getMimeType().getBaseType(), 
clob.getChars(), clob.getName());
     }
 
-
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisColorPanel.java
----------------------------------------------------------------------
diff --git 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisColorPanel.java
 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisColorPanel.java
index f9ae3a3..5e8870b 100644
--- 
a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisColorPanel.java
+++ 
b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisColorPanel.java
@@ -23,7 +23,7 @@ import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import 
org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelTextFieldParseableAbstract;
 
 /**
- * Panel for rendering scalars of type {@link Color Isis' applib.Color}.
+ * Panel for rendering scalars of type {@link 
org.apache.isis.applib.value.Color Isis' applib.Color}.
  */
 public class IsisColorPanel extends ScalarPanelTextFieldParseableAbstract {
 

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
----------------------------------------------------------------------
diff --git 
a/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
 
b/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
index ec03b65..9194e6e 100644
--- 
a/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
+++ 
b/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
@@ -49,6 +49,7 @@ import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.applib.util.ObjectContracts;
 import org.apache.isis.applib.util.TitleBuffer;
 import org.apache.isis.applib.value.Blob;
+import org.apache.isis.applib.value.Clob;
 
 @javax.jdo.annotations.PersistenceCapable(identityType=IdentityType.DATASTORE)
 @javax.jdo.annotations.DatastoreIdentity(
@@ -110,8 +111,7 @@ public class ToDoItem implements Comparable<ToDoItem> {
     //endregion
 
     // region > title, icon
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     public String title() {
         final TitleBuffer buf = new TitleBuffer();
         buf.append(getDescription());
@@ -131,8 +131,7 @@ public class ToDoItem implements Comparable<ToDoItem> {
     //endregion
 
     //region > description (property)
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     private String description;
 
     @javax.jdo.annotations.Column(allowsNull="false", length=100)
@@ -155,8 +154,7 @@ public class ToDoItem implements Comparable<ToDoItem> {
     //endregion
 
     //region > dueBy (property)
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     @javax.jdo.annotations.Persistent(defaultFetchGroup="true")
     private LocalDate dueBy;
 
@@ -181,8 +179,8 @@ public class ToDoItem implements Comparable<ToDoItem> {
     //endregion
 
     //region > category and subcategory (property)
-    // //////////////////////////////////////
 
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     public static enum Category {
         Professional {
             @Override
@@ -260,13 +258,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
     public void setSubcategory(final Subcategory subcategory) {
         this.subcategory = subcategory;
     }
-
-
     //endregion
 
     //region > ownedBy (property)
-    // //////////////////////////////////////
-    
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     private String ownedBy;
 
     @javax.jdo.annotations.Column(allowsNull="false")
@@ -277,13 +272,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
     public void setOwnedBy(final String ownedBy) {
         this.ownedBy = ownedBy;
     }
-
-
     //endregion
 
     //region > complete (property), completed (action), notYetCompleted 
(action)
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     private boolean complete;
 
     @Disabled
@@ -338,14 +330,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
     public String disableNotYetCompleted() {
         return !complete ? "Not yet completed" : null;
     }
-
     //endregion
 
     //region > completeSlowly (property)
-    // //////////////////////////////////////
-    // completeSlowly
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     @Hidden
     public void completeSlowly(int millis) {
         try {
@@ -354,13 +342,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
         }
         setComplete(true);
     }
-
-
     //endregion
 
     //region > cost (property), updateCost (action)
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     private BigDecimal cost;
 
     @javax.jdo.annotations.Column(allowsNull="true", scale=2)
@@ -401,14 +386,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
         if(proposedCost == null) { return null; }
         return proposedCost.compareTo(BigDecimal.ZERO) < 0? "Cost must be 
positive": null;
     }
-
     //endregion
 
     //region > notes (property)
-    // //////////////////////////////////////
-    // Notes (property)
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     private String notes;
 
     @javax.jdo.annotations.Column(allowsNull="true", length=400)
@@ -419,17 +400,15 @@ public class ToDoItem implements Comparable<ToDoItem> {
     public void setNotes(final String notes) {
         this.notes = notes;
     }
-
     //endregion
 
     //region > attachment (property)
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     private Blob attachment;
     @javax.jdo.annotations.Persistent(defaultFetchGroup="false", columns = {
             @javax.jdo.annotations.Column(name = "attachment_name"),
             @javax.jdo.annotations.Column(name = "attachment_mimetype"),
-            @javax.jdo.annotations.Column(name = "attachment_bytes", sqlType = 
"BLOB")
+            @javax.jdo.annotations.Column(name = "attachment_bytes", jdbcType 
= "BLOB", sqlType = "BLOB")
     })
     @Optional
     public Blob getAttachment() {
@@ -439,11 +418,28 @@ public class ToDoItem implements Comparable<ToDoItem> {
     public void setAttachment(final Blob attachment) {
         this.attachment = attachment;
     }
+    //endregion
 
-    // //////////////////////////////////////
-    // Version (derived property)
-    // //////////////////////////////////////
+    //region > doc (property)
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    private Clob doc;
+    @javax.jdo.annotations.Persistent(defaultFetchGroup="false", columns = {
+            @javax.jdo.annotations.Column(name = "doc_name"),
+            @javax.jdo.annotations.Column(name = "doc_mimetype"),
+            @javax.jdo.annotations.Column(name = "doc_chars", jdbcType = 
"CLOB", sqlType = "CLOB")
+    })
+    @Optional
+    public Clob getDoc() {
+        return doc;
+    }
 
+    public void setDoc(final Clob doc) {
+        this.doc = doc;
+    }
+    //endregion
+
+    //region > version (derived property)
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     public Long getVersionSequence() {
         if(!(this instanceof javax.jdo.spi.PersistenceCapable)) {
             return null;
@@ -456,11 +452,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
     public boolean hideVersionSequence() {
         return !(this instanceof javax.jdo.spi.PersistenceCapable);
     }
-
     //endregion
 
     //region > dependencies (property), add (action), remove (action)
-    // //////////////////////////////////////
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
     // overrides the natural ordering
     public static class DependenciesComparator implements Comparator<ToDoItem> 
{
@@ -477,8 +472,6 @@ public class ToDoItem implements Comparable<ToDoItem> {
         }
     }
 
-    
-
     @javax.jdo.annotations.Persistent(table="ToDoItemDependencies")
     @javax.jdo.annotations.Join(column="dependingId")
     @javax.jdo.annotations.Element(column="dependentId")
@@ -563,12 +556,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
     public Collection<ToDoItem> choices0Remove() {
         return getDependencies();
     }
-
-
     //endregion
 
     //region > clone (action)
-    // //////////////////////////////////////
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
     // the name of the action in the UI
     // nb: method is not called "clone()" is inherited by java.lang.Object and
@@ -604,12 +595,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
             final LocalDate dueBy, final BigDecimal cost) {
         return toDoItems.validateNewToDo(description, category, subcategory, 
dueBy, cost);
     }
-
     //endregion
 
     //region > delete (action)
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     @PostsActionInvokedEvent(DeletedEvent.class)
     @Bulk
     public List<ToDoItem> delete() {
@@ -621,13 +610,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
         // invalid to return 'this' (cannot render a deleted object)
         return toDoItems.notYetComplete(); 
     }
-
-
     //endregion
 
     //region > totalCost (property)
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     @ActionSemantics(Of.SAFE)
     @Bulk(AppliesTo.BULK_ONLY)
     public BigDecimal totalCost() {
@@ -638,14 +624,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
         }
         return total.setScale(2);
     }
-
-
-
     //endregion
 
     //region > scheduleExplicitly (action), scheduleImplicitly (background 
action)
-    // //////////////////////////////////////
-    
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     @ActionSemantics(Of.IDEMPOTENT)
     @Prototype
     public ToDoItem scheduleExplicitly() {
@@ -663,14 +645,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
         completeSlowly(3000);
         return this;
     }
-
-
-
     //endregion
 
     //region > openSourceCodeOnGithub (action)
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     @Prototype
     @ActionSemantics(Of.SAFE)
     public URL openSourceCodeOnGithub() throws MalformedURLException {
@@ -679,8 +657,8 @@ public class ToDoItem implements Comparable<ToDoItem> {
     //endregion
 
     //region > demoException (action)
-    // //////////////////////////////////////
-    
+
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     static enum DemoExceptionType {
         RecoverableException,
         RecoverableExceptionAutoEscalated,
@@ -707,12 +685,10 @@ public class ToDoItem implements Comparable<ToDoItem> {
             }
         }
     }
-
-
     //endregion
 
     //region > object-level validation
-    // //////////////////////////////////////
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
     /**
      * In a real app, if this were actually a rule, then we'd expect that
@@ -725,11 +701,11 @@ public class ToDoItem implements Comparable<ToDoItem> {
         }
         return null;
     }
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //endregion
 
     //region > programmatic helpers
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     private static final long ONE_WEEK_IN_MILLIS = 7 * 24 * 60 * 60 * 1000L;
 
     @Programmatic // excluded from the framework's metamodel
@@ -743,12 +719,11 @@ public class ToDoItem implements Comparable<ToDoItem> {
     private static boolean isMoreThanOneWeekInPast(final LocalDate dueBy) {
         return dueBy.toDateTimeAtStartOfDay().getMillis() < Clock.getTime() - 
ONE_WEEK_IN_MILLIS;
     }
-
     //endregion
 
     //region > events
-    // //////////////////////////////////////
 
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     public static abstract class AbstractActionInvokedEvent extends 
ActionInvokedEvent<ToDoItem> {
         private static final long serialVersionUID = 1L;
         private final String description;
@@ -794,11 +769,12 @@ public class ToDoItem implements Comparable<ToDoItem> {
             super("deleted", source, identifier, arguments);
         }
     }
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //endregion
 
     //region > predicates
-    // //////////////////////////////////////
 
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     public static class Predicates {
         
         public static Predicate<ToDoItem> thoseOwnedBy(final String 
currentUser) {
@@ -873,12 +849,11 @@ public class ToDoItem implements Comparable<ToDoItem> {
         }
 
     }
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //endregion
 
     //region > toString, compareTo
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     @Override
     public String toString() {
         return ObjectContracts.toString(this, 
"description,complete,dueBy,ownedBy");
@@ -891,12 +866,11 @@ public class ToDoItem implements Comparable<ToDoItem> {
     public int compareTo(final ToDoItem other) {
         return ObjectContracts.compare(this, other, 
"complete,dueBy,description");
     }
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //endregion
 
     //region > injected services
-    // //////////////////////////////////////
-
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     @javax.inject.Inject
     private DomainObjectContainer container;
 
@@ -929,9 +903,7 @@ public class ToDoItem implements Comparable<ToDoItem> {
 
     @javax.inject.Inject
     private WrapperFactory wrapperFactory;
-    
+    // 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //endregion
 
-    
-
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.layout.json
----------------------------------------------------------------------
diff --git 
a/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.layout.json
 
b/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.layout.json
index 4db6560..db9e7d2 100644
--- 
a/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.layout.json
+++ 
b/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.layout.json
@@ -122,6 +122,11 @@
                         hidden: {
                             where: STANDALONE_TABLES
                         }
+                    },
+                    doc: {
+                        hidden: {
+                            where: STANDALONE_TABLES
+                        }
                     }
                 }
             }

http://git-wip-us.apache.org/repos/asf/isis/blob/d99641d0/example/application/quickstart_wicket_restful_jdo/webapp/pom.xml
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/webapp/pom.xml 
b/example/application/quickstart_wicket_restful_jdo/webapp/pom.xml
index 9a3fc62..126973a 100644
--- a/example/application/quickstart_wicket_restful_jdo/webapp/pom.xml
+++ b/example/application/quickstart_wicket_restful_jdo/webapp/pom.xml
@@ -243,7 +243,7 @@
          <!-- 
         <dependency>
             <groupId>com.microsoft.sqlserver</groupId>
-            <artifactId>jdbc</artifactId>
+            <artifactId>sqljdbc4</artifactId>
             <version>4.0</version>
         </dependency>
           -->

Reply via email to