View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.cms.tabular;
17  
18  import java.io.ByteArrayInputStream;
19  import java.io.ByteArrayOutputStream;
20  import java.io.InputStream;
21  import java.util.List;
22  
23  import javax.jcr.Binary;
24  import javax.jcr.Node;
25  import javax.jcr.Property;
26  import javax.jcr.PropertyType;
27  import javax.jcr.RepositoryException;
28  
29  import org.apache.commons.io.IOUtils;
30  import org.argeo.api.tabular.TabularColumn;
31  import org.argeo.api.tabular.TabularWriter;
32  import org.argeo.cms.ArgeoTypes;
33  import org.argeo.jcr.ArgeoJcrException;
34  import org.argeo.jcr.JcrUtils;
35  import org.argeo.util.CsvWriter;
36  
37  /** Write / reference tabular content in a JCR repository. */
38  public class JcrTabularWriter implements TabularWriter {
39  	private Node contentNode;
40  	private ByteArrayOutputStream out;
41  	private CsvWriter csvWriter;
42  	
43  	@SuppressWarnings("unused")
44  	private final List<TabularColumn> columns;
45  
46  	/** Creates a table node */
47  	public JcrTabularWriter(Node tableNode, List<TabularColumn> columns,
48  			String contentNodeType) {
49  		try {
50  			this.columns = columns;
51  			for (TabularColumn column : columns) {
52  				String normalized = JcrUtils.replaceInvalidChars(column
53  						.getName());
54  				Node columnNode = tableNode.addNode(normalized,
55  						ArgeoTypes.ARGEO_COLUMN);
56  				columnNode.setProperty(Property.JCR_TITLE, column.getName());
57  				if (column.getType() != null)
58  					columnNode.setProperty(Property.JCR_REQUIRED_TYPE,
59  							PropertyType.nameFromValue(column.getType()));
60  				else
61  					columnNode.setProperty(Property.JCR_REQUIRED_TYPE,
62  							PropertyType.TYPENAME_STRING);
63  			}
64  			contentNode = tableNode.addNode(Property.JCR_CONTENT,
65  					contentNodeType);
66  			if (contentNodeType.equals(ArgeoTypes.ARGEO_CSV)) {
67  				contentNode.setProperty(Property.JCR_MIMETYPE, "text/csv");
68  				contentNode.setProperty(Property.JCR_ENCODING, "UTF-8");
69  				out = new ByteArrayOutputStream();
70  				csvWriter = new CsvWriter(out);
71  			}
72  		} catch (RepositoryException e) {
73  			throw new ArgeoJcrException("Cannot create table node " + tableNode, e);
74  		}
75  	}
76  
77  	public void appendRow(Object[] row) {
78  		csvWriter.writeLine(row);
79  	}
80  
81  	public void close() {
82  		Binary binary = null;
83  		InputStream in = null;
84  		try {
85  			// TODO parallelize with pipes and writing from another thread
86  			in = new ByteArrayInputStream(out.toByteArray());
87  			binary = contentNode.getSession().getValueFactory()
88  					.createBinary(in);
89  			contentNode.setProperty(Property.JCR_DATA, binary);
90  		} catch (RepositoryException e) {
91  			throw new ArgeoJcrException("Cannot store data in " + contentNode, e);
92  		} finally {
93  			IOUtils.closeQuietly(in);
94  			JcrUtils.closeQuietly(binary);
95  		}
96  	}
97  }