From: <jbo...@li...> - 2005-10-28 16:33:00
|
Author: adamw Date: 2005-10-28 12:32:35 -0400 (Fri, 28 Oct 2005) New Revision: 1466 Added: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/NodeContent.java trunk/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/test/ContentSettingTest.java Modified: trunk/forge/portal-extensions/forge-feeds/src/java/org/jboss/forge/feeds/RomeBasedFeed.java trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHeadNode.java trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHistoricNode.java trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewNode.java Log: http://jira.jboss.com/jira/browse/JBSHOTOKU-19 : implementation + test Modified: trunk/forge/portal-extensions/forge-feeds/src/java/org/jboss/forge/feeds/RomeBasedFeed.java =================================================================== --- trunk/forge/portal-extensions/forge-feeds/src/java/org/jboss/forge/feeds/RomeBasedFeed.java 2005-10-28 15:56:29 UTC (rev 1465) +++ trunk/forge/portal-extensions/forge-feeds/src/java/org/jboss/forge/feeds/RomeBasedFeed.java 2005-10-28 16:32:35 UTC (rev 1466) @@ -24,10 +24,10 @@ setFeedType(syndFeed); - syndFeed.setTitle("Aggregated Feed"); - syndFeed.setDescription("Anonymous Aggregated Feed"); - syndFeed.setAuthor("anonymous"); - syndFeed.setLink("http://www.anonymous.com"); + syndFeed.setTitle("Labs feed"); + syndFeed.setDescription("Labs aggregated feed"); + syndFeed.setAuthor("Labs team"); + syndFeed.setLink("http://labs.jboss.com"); List entries = new ArrayList(); syndFeed.setEntries(entries); Modified: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java =================================================================== --- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java 2005-10-28 15:56:29 UTC (rev 1465) +++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/ContentManager.java 2005-10-28 16:32:35 UTC (rev 1466) @@ -132,7 +132,6 @@ * * @return A ""-prefixed, default content manager, or null, if a default * content manager is not registered. - * @deprecated */ public static ContentManager getContentManager() { return getContentManager(""); Modified: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java =================================================================== --- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java 2005-10-28 15:56:29 UTC (rev 1465) +++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/Node.java 2005-10-28 16:32:35 UTC (rev 1466) @@ -1,6 +1,7 @@ package org.jboss.shotoku; import java.io.InputStream; +import java.io.OutputStream; import org.jboss.shotoku.exceptions.RepositoryException; @@ -29,6 +30,31 @@ public void setContent(String content); /** + * Sets this node's content, reading from the given input stream. + * + * @param is + * Input stream to read from. + */ + public void setContent(InputStream is); + + /** + * Sets this node's content, given as an array of bytes. + * + * @param bytes + * Byte array of new content. + */ + public void setContent(byte[] bytes); + + /** + * Gets an output stream for writing data to the node. The stream will be + * automatically closed upon invocation of any getContent...() methods, or + * the save() method. + * + * @return An output stream for writing data to the node. + */ + public OutputStream getOutputStream(); + + /** * Gets a history of this node. * * @return A history of this node. @@ -62,6 +88,14 @@ public InputStream getContentInputStream() throws RepositoryException; /** + * Gets the content of this node as a byte array. + * + * @return Content of this node as a byte array. + * @throws RepositoryException + */ + public byte[] getContentByteArray() throws RepositoryException; + + /** * Gets the length of this node's content. * * @return Length of this node's content. @@ -76,7 +110,7 @@ * @throws RepositoryException */ public long getLastModfication() throws RepositoryException; - + /** * Gets the mime type of this node. * Modified: trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java =================================================================== --- trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java 2005-10-28 15:56:29 UTC (rev 1465) +++ trunk/forge/portal-extensions/shotoku/shotoku-base/src/java/org/jboss/shotoku/NodeList.java 2005-10-28 16:32:35 UTC (rev 1466) @@ -39,7 +39,7 @@ return nodeList; } - /* - * public InputStream getFeed(Template velocityTemplate); - */ + /*public InputStream getFeed(String velocityTemplate) { + throw new RuntimeException("Operation not yet implemented"); + }*/ } Added: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/NodeContent.java =================================================================== --- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/NodeContent.java 2005-10-28 15:56:29 UTC (rev 1465) +++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/NodeContent.java 2005-10-28 16:32:35 UTC (rev 1466) @@ -0,0 +1,129 @@ +package org.jboss.shotoku.svn; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class NodeContent { + private final static int BUF_SIZE = 32768; + + private String stringContent; + private byte[] byteContent; + + private ByteArrayOutputStream currentBaos; + + private boolean changed; + + public NodeContent() { + changed = false; + } + + /* HELPER METHODS */ + + private void emptyContent() { + stringContent = null; + byteContent = null; + currentBaos = null; + } + + private void transfer(InputStream is, OutputStream os) throws IOException { + byte[] buffer = new byte[BUF_SIZE]; + int read; + while ((read = is.read(buffer)) != -1) + os.write(buffer, 0, read); + } + + /* CONVERSION METHODS */ + + public String asString() { + if (currentBaos != null) { + try { currentBaos.flush(); } catch (IOException e) { } + stringContent = currentBaos.toString(); + currentBaos = null; + } else if (stringContent == null) { + if (byteContent == null) + stringContent = ""; + else + stringContent = new String(byteContent); + } + + return stringContent; + } + + public byte[] asByteArray() { + if (currentBaos != null) { + try { currentBaos.flush(); } catch (IOException e) { } + byteContent = currentBaos.toByteArray(); + currentBaos = null; + } else if (byteContent == null) { + if (stringContent == null) + byteContent = new byte[0]; + else + byteContent = stringContent.getBytes(); + } + + return byteContent; + } + + public InputStream asInputStream() { + return new ByteArrayInputStream(asByteArray()); + } + + /* SETTING METHODS */ + + public void setContent(InputStream is) throws IOException { + emptyContent(); + ByteArrayOutputStream boas = new ByteArrayOutputStream(); + transfer(is, boas); + + byteContent = boas.toByteArray(); + + changed = true; + } + + public void setContent(String content) { + emptyContent(); + stringContent = content; + + changed = true; + } + + public void setContent(byte[] bytes) { + emptyContent(); + byteContent = bytes; + + changed = true; + } + + public void copyToFile(File file) throws FileNotFoundException, IOException { + transfer(asInputStream(), new FileOutputStream(file)); + } + + public OutputStream getOutputStream() { + currentBaos = new ByteArrayOutputStream(); + changed = true; + + return currentBaos; + } + + /* VARIOUS METHODS */ + + public boolean getChanged() { + return changed; + } + + public long getLength() { + if (stringContent != null) + return stringContent.length(); + + if (byteContent != null) + return byteContent.length; + + return 0; + } +} Modified: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHeadNode.java =================================================================== --- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHeadNode.java 2005-10-28 15:56:29 UTC (rev 1465) +++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHeadNode.java 2005-10-28 16:32:35 UTC (rev 1466) @@ -6,7 +6,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.PrintWriter; +import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.charset.Charset; @@ -14,48 +14,92 @@ import org.jboss.shotoku.exceptions.RepositoryException; public class SvnHeadNode extends SvnNode { - private String newContent; + private NodeContent content; + private NodeContent getNodeContent() { + if (content == null) + content = new NodeContent(); + + return content; + } + public SvnHeadNode(String id, String fullPath, File file, String name, SvnContentManager svnCm) { super(id, fullPath, file, name, svnCm); - newContent = null; + content = null; } + private ByteBuffer getFileBytes() throws IOException { + FileChannel fc = new FileInputStream(file).getChannel(); + ByteBuffer buff = ByteBuffer.allocate((int) file.length()); + fc.read(buff); + buff.flip(); + + return buff; + } + public String getContent() { - if (newContent != null) return newContent; - + if (content == null) { + try { + return Charset.forName( + System.getProperty("file.encoding")).decode( + getFileBytes()).toString(); + } catch (IOException e) { + throw new RepositoryException(e); + } + } else + return content.asString(); + } + + + public byte[] getContentByteArray() { + if (content == null) { + try { + return getFileBytes().array(); + } catch (IOException e) { + throw new RepositoryException(e); + } + } else + return content.asByteArray(); + } + + public void setContent(String stringContent) { + getNodeContent().setContent(stringContent); + } + + + public void setContent(InputStream is) { try { - FileChannel fc = new FileInputStream(file).getChannel(); - ByteBuffer buff = ByteBuffer.allocate((int) file.length()); - fc.read(buff); - buff.flip(); - - return Charset.forName( - System.getProperty("file.encoding")).decode( - buff).toString(); + getNodeContent().setContent(is); } catch (IOException e) { throw new RepositoryException(e); } } - public void setContent(String content) { - newContent = content; + public void setContent(byte[] bytes) { + getNodeContent().setContent(bytes); } - public int getRevisionNumber() { - int historicRevisions = getHistory().getRevisionsCount(); - return historicRevisions + (checkForChanges() ? 1 : 0); + public OutputStream getOutputStream() { + return getNodeContent().getOutputStream(); } public InputStream getContentInputStream() { try { - return new FileInputStream(file); + if ((content != null) && (content.getChanged())) + return content.asInputStream(); + else + return new FileInputStream(file); } catch (FileNotFoundException e) { throw new RepositoryException(e); } } + public int getRevisionNumber() { + int historicRevisions = getHistory().getRevisionsCount(); + return historicRevisions + (checkForChanges() ? 1 : 0); + } + public long getLength() { return file.length(); } @@ -72,7 +116,7 @@ } protected boolean checkForChanges() { - return newContent != null || super.checkForChanges(); + return ((content != null) && (content.getChanged())) || (super.checkForChanges()); } protected void saveWithLock(String logMessage) { @@ -81,20 +125,15 @@ save(); // Saving modified content. - if (newContent != null) { - PrintWriter pw; - + if ((content != null) && (content.getChanged())) { try { - pw = new PrintWriter(file); - } catch (FileNotFoundException e) { + content.copyToFile(file); + } catch (Exception e) { service.putWriteLock(id, fullPath); throw new RepositoryException(e); } - pw.print(newContent); - pw.close(); - - newContent = null; + content = null; } service.commit(id, fullPath, logMessage); Modified: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHistoricNode.java =================================================================== --- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHistoricNode.java 2005-10-28 15:56:29 UTC (rev 1465) +++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnHistoricNode.java 2005-10-28 16:32:35 UTC (rev 1466) @@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.InputStream; +import java.io.OutputStream; import java.io.PrintWriter; import java.util.Date; import java.util.Map; @@ -64,6 +65,12 @@ return new ByteArrayInputStream(content.toByteArray()); } + + public byte[] getContentByteArray() throws RepositoryException { + loadContentAndProperties(); + + return content.toByteArray(); + } public long getLength() { loadContentAndProperties(); @@ -116,4 +123,16 @@ public void delete() { throw new NodeReadOnly(); } + + public void setContent(InputStream arg0) { + throw new NodeReadOnly(); + } + + public OutputStream getOutputStream() { + throw new NodeReadOnly(); + } + + public void setContent(byte[] arg0) { + throw new NodeReadOnly(); + } } Modified: trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewNode.java =================================================================== --- trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewNode.java 2005-10-28 15:56:29 UTC (rev 1465) +++ trunk/forge/portal-extensions/shotoku/shotoku-svn/src/java/org/jboss/shotoku/svn/SvnNewNode.java 2005-10-28 16:32:35 UTC (rev 1466) @@ -3,21 +3,22 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.PrintWriter; +import java.io.OutputStream; import java.util.Calendar; import org.jboss.shotoku.History; import org.jboss.shotoku.exceptions.RepositoryException; public class SvnNewNode extends SvnHeadNode { - private String content; + private NodeContent content; + private boolean saved; public SvnNewNode(String id, String fullPath, File file, String name, SvnContentManager svnCm) { super(id, fullPath, file, name, svnCm); - content = null; + content = new NodeContent(); saved = false; } @@ -33,18 +34,28 @@ public String getContent() { if (saved) return super.getContent(); - else - return content; + else { + return content.asString(); + } } @Override public InputStream getContentInputStream() { if (saved) return super.getContentInputStream(); - else - // TODO - return null; + else { + return content.asInputStream(); + } } + + @Override + public byte[] getContentByteArray() { + if (saved) + return super.getContentByteArray(); + else { + return content.asByteArray(); + } + } @Override public History getHistory() { @@ -67,7 +78,7 @@ if (saved) return super.getLength(); else - return content.length(); + return content.getLength(); } @Override @@ -118,6 +129,8 @@ service.putWriteLock(id, fullPath); throw new RepositoryException(e); } + + super.setContent(content.asString()); saveWithLock(logMessage); @@ -126,29 +139,52 @@ } @Override - public void setContent(String content) { - super.setContent(content); - this.content = content; + public void setContent(String stringContent) { + if (saved) + super.setContent(stringContent); + else { + content.setContent(stringContent); + } } + + public void setContent(InputStream is) { + if (saved) + super.setContent(is); + else { + try { + content.setContent(is); + } catch (IOException e) { + throw new RepositoryException(e); + } + } + } + + public void setContent(byte[] bytes) { + if (saved) + super.setContent(bytes); + else { + content.setContent(bytes); + } + } + + public OutputStream getOutputStream() { + if (saved) + return super.getOutputStream(); + else { + return content.getOutputStream(); + } + } @Override public void copyToFile(String filename) throws RepositoryException { if (saved) super.copyToFile(filename); else { - File target = new File(filename); - - PrintWriter pw; - try { - target.createNewFile(); - pw = new PrintWriter(target); + content.copyToFile(file); } catch (Exception e) { throw new RepositoryException(e); } - - pw.print(content); - pw.close(); } } } Modified: trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java =================================================================== --- trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java 2005-10-28 15:56:29 UTC (rev 1465) +++ trunk/forge/portal-extensions/shotoku/shotoku-svn-service/src/java/org/jboss/shotoku/svn/service/SvnRepository.java 2005-10-28 16:32:35 UTC (rev 1466) @@ -136,7 +136,7 @@ op.performOperation(ourClientManager); } catch (SVNException e) { tryCleanup(); - log.warn("Performing delayed op: " + op.getClass().getName() + " failed.", e); + log.error("Performing delayed op: " + op.getClass().getName() + " failed.", e); } } } @@ -146,7 +146,6 @@ } public void getWriteLock(String path) { - // TODO if (path.contains("//")) throw new RuntimeException("Two / in: " + path); Added: trunk/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/test/ContentSettingTest.java =================================================================== --- trunk/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/test/ContentSettingTest.java 2005-10-28 15:56:29 UTC (rev 1465) +++ trunk/forge/portal-extensions/shotoku/shotoku-test/src/java/org/jboss/shotoku/test/ContentSettingTest.java 2005-10-28 16:32:35 UTC (rev 1466) @@ -0,0 +1,68 @@ +package org.jboss.shotoku.test; + +import java.io.IOException; +import java.util.Arrays; + +import org.jboss.shotoku.Node; + +public class ContentSettingTest extends ShotokuTest { + private final static String TEST_FILE = "content-saving-test-1"; + private final static String TEST_CONTENT = "content 1\nline 2"; + private final static String TEST_CONTENT_2 = "content 2\nline 2\nline 3"; + private final static String TEST_CONTENT_3 = "content 3\n\nline 3"; + + @Override + protected void setUp() throws Exception { + Node n = cm.getRootDirectory().newNode(TEST_FILE); + n.save(TEST_FILE); + } + + private void assertNodeContent(Node n, String content) { + assertTrue(content.equals(n.getContent())); + assertTrue(Arrays.equals(content.getBytes(), n.getContentByteArray())); + } + + public void testString() { + // Getting the test node. + Node n = cm.getNode(TEST_FILE); + + // Modifying the content. + n.setContent(TEST_CONTENT); + n.save(TEST_FILE); + + // Checking if changes are visible. + assertNodeContent(n, TEST_CONTENT); + assertNodeContent(cm.getRootDirectory().getNode(TEST_FILE), TEST_CONTENT); + } + + public void testByteArray() { + // Getting the test node. + Node n = cm.getNode(TEST_FILE); + + // Modifying the content. + n.setContent(TEST_CONTENT_2.getBytes()); + n.save(TEST_FILE); + + // Checking if changes are visible. + assertNodeContent(n, TEST_CONTENT_2); + assertNodeContent(cm.getRootDirectory().getNode(TEST_FILE), TEST_CONTENT_2); + } + + public void testOutputStream() throws IOException { + // Getting the test node. + Node n = cm.getNode(TEST_FILE); + + // Modifying the content. + n.getOutputStream().write(TEST_CONTENT_3.getBytes()); + n.save(TEST_FILE); + + // Checking if changes are visible. + assertNodeContent(n, TEST_CONTENT_3); + assertNodeContent(cm.getRootDirectory().getNode(TEST_FILE), TEST_CONTENT_3); + } + + @Override + protected void tearDown() throws Exception { + cm.getNode(TEST_FILE).delete(); + } +} |