[Jsxe-cvs] SF.net SVN: jsxe: [1082] branches/jsxe2/src/net/sourceforge/jsxe
Status: Inactive
Brought to you by:
ian_lewis
From: <ian...@us...> - 2006-07-28 22:46:33
|
Revision: 1082 Author: ian_lewis Date: 2006-07-28 15:46:19 -0700 (Fri, 28 Jul 2006) ViewCVS: http://svn.sourceforge.net/jsxe/?rev=1082&view=rev Log Message: ----------- Added new multi-threading support. XMLDocuments and XMLNodes no longer implement the Document and Element interfaces respectively. The source tree will not currently compile Modified Paths: -------------- branches/jsxe2/src/net/sourceforge/jsxe/dom2/XMLDocument.java branches/jsxe2/src/net/sourceforge/jsxe/dom2/XMLNode.java branches/jsxe2/src/net/sourceforge/jsxe/dom2/ls/XMLDocumentIORequest.java branches/jsxe2/src/net/sourceforge/jsxe/io/VFSManager.java branches/jsxe2/src/net/sourceforge/jsxe/properties Modified: branches/jsxe2/src/net/sourceforge/jsxe/dom2/XMLDocument.java =================================================================== --- branches/jsxe2/src/net/sourceforge/jsxe/dom2/XMLDocument.java 2006-07-28 20:04:32 UTC (rev 1081) +++ branches/jsxe2/src/net/sourceforge/jsxe/dom2/XMLDocument.java 2006-07-28 22:46:19 UTC (rev 1082) @@ -59,19 +59,23 @@ //}}} /** - * The XMLDocument class represents an XML document as a tree structure + * <p>The XMLDocument class represents an XML document as a tree structure * that has nodes, implemented as XMLNodes, as well as text. Methods are * provided to allow user objects to interact with the XML document as text - * or as a tree structure seamlessly. + * or as a tree structure seamlessly.</p> * - * Properties of XMLDocuments are saved by jsXe as string values. And are loaded - * later when if the document was loaded recently. + * <p>It is implemented in the spirit of the {@link javax.swing.text.Document} + * class in that it represents a piece of structured text that can be + * viewed and edited via the text or document structure</p> * + * <p>Properties of XMLDocuments are saved by jsXe as string values. And are loaded + * later when if the document was loaded recently.</p> + * * @author Ian Lewis (<a href="mailto:Ian...@me...">Ian...@me...</a>) * @version $Id: XMLDocument.java 999 2006-07-07 20:59:23Z ian_lewis $ * @see XMLNode */ -public class XMLDocument implements javax.swing.text.Document { +public class XMLDocument { //{{{ XMLDocument defined properties /** @@ -152,7 +156,6 @@ */ public XMLDocument(String uri, InputStream reader, EntityResolver resolver, Map properties) throws IOException { m_entityResolver = resolver; - setDefaultProperties(); setURI(uri); //add properties one by one @@ -168,14 +171,13 @@ reader.close(); }//}}} - //{{{ swing.text.Document methods - //{{{ addDocumentListener /** * Registers a change listener with the XMLDocument * @param listener the listener to register with this document */ public void addDocumentListener(DocumentListener listener) { + //TODO: Create XMLDocumentListeners if (listener != null) { m_docListeners.add(listener); } @@ -189,90 +191,47 @@ } }//}}} - //{{{ createPosition() - - public Position createPosition(int offs) throws BadLocationException { - if (offs < 0 || offs > m_content.getLength()) { - //TODO: fix error messages - throw new BadLocationException("createPosition(): Bad offset", offs); - } - - final int offset = offs; - return new Position() { - public int getOffset() { - return offset; - } - }; - }//}}} - //{{{ getDefaultRootElement() - - public javax.swing.text.Element getDefaultRootElement() { + /** + * Gets the root document element. + */ + public XMLElement getRootElement() { //TODO: return root element return null; }//}}} - //{{{ getEndPosition() - - public Position getEndPosition() { - try { - return createPosition(getLength()-1); - } catch (BadLocationException e) { - //Guaranteed to be good. - return null; - } - }//}}} - //{{{ getLength() /** - * Gets the total number of characters in the document. + * Gets the total number of characters in the document. This method is + * thread-safe. * @return the length of the document */ public int getLength() { + // no need to lock since this just returns a value and that's it return m_content.getLength(); }//}}} - //{{{ getProperty() + //{{{ getRootNodes() - public Object getProperty(Object key) { - return m_properties.get(key); - }//}}} - - //{{{ getRootElements() - - public javax.swing.text.Element[] getRootElements() { + public XMLNode[] getRootNodes() { //TODO: return root nodes return null; }//}}} - //{{{ getStartPosition() - - public Position getStartPosition() { - try { - return createPosition(0); - } catch (BadLocationException e) { - //Guaranteed to be good. - return null; - } - }//}}} - //{{{ getText() - public String getText(int offset, int length) throws BadLocationException { + public String getText(int offset, int length) { if (offset < 0 || length < 0 || offset + length > m_content.getLength()) { - //TODO: fix error messages - throw new BadLocationException("insertString(): Bad Offset", offset); + throw new ArrayIndexOutOfBoundsException(offset); } return m_content.getText(offset,length); }//}}} //{{{ getText() - - public void getText(int offset, int length, Segment txt) throws BadLocationException { + public void getText(int offset, int length, Segment txt) { if (offset < 0 || length < 0 || offset + length > m_content.getLength()) { - //TODO: fix error messages - throw new BadLocationException("insertString(): Bad Offset", offset); + throw new ArrayIndexOutOfBoundsException(offset); } m_content.getText(offset, length, txt); @@ -302,10 +261,9 @@ * @param a the attributes to associate with the inserted content. * This attribute is ignored by XMLDocuments. */ - public void insertString(int offset, String str, AttributeSet a) throws BadLocationException { + public void insertString(int offset, String str) { if (offset < 0 || str.length() < 0 || offset + str.length() > m_content.getLength()) { - //TODO: fix error messages - throw new BadLocationException("insertString(): Bad Offset", offset); + throw new ArrayIndexOutOfBoundsException(offset); } m_content.insert(offset, str); @@ -315,24 +273,11 @@ //TODO: implement undo }//}}} - //{{{ putProperty() - /** - * Add a property to the XMLDocument. - * They are saved in memory as objects however, jsXe saves properties as - * Strings when saving the Document to the recent buffers file, and when - * the document is opened later the property will be loaded as a String. - * Generally String properties are stored here. - */ - public void putProperty(Object key, Object value) { - m_properties.put(key, value); - }//}}} - //{{{ remove() - public void remove(int offs, int len) throws BadLocationException { + public void remove(int offs, int len) { if (offs < 0 || len < 0 || offs + len > m_content.getLength()) { - //TODO: fix error messages - throw new BadLocationException("insertString(): Bad Offset", offs); + throw new ArrayIndexOutOfBoundsException(offs); } m_content.remove(offs, len); @@ -359,12 +304,60 @@ }//}}} //{{{ render() - public void render(Runnable r) { - //TODO: implement concurrency support. + VFSManager.runInWorkThread(new Runnable() { + public void run() { + try { + readLock(); + + r.run(); + + } finally { + readUnlock(); + } + } + }); }//}}} - //}}} + //{{{ Thread safety + + //{{{ readLock() method + /** + * The buffer is guaranteed not to change between calls to + * {@link #readLock()} and {@link #readUnlock()}. + */ + public void readLock() { + lock.readLock(); + } //}}} + + //{{{ readUnlock() method + /** + * The buffer is guaranteed not to change between calls to + * {@link #readLock()} and {@link #readUnlock()}. + */ + public void readUnlock() { + lock.readUnlock(); + } //}}} + + //{{{ writeLock() method + /** + * Attempting to obtain read lock will block between calls to + * {@link #writeLock()} and {@link #writeUnlock()}. + */ + public void writeLock() { + lock.writeLock(); + } //}}} + + //{{{ writeUnlock() method + /** + * Attempting to obtain read lock will block between calls to + * {@link #writeLock()} and {@link #writeUnlock()}. + */ + public void writeUnlock() { + lock.writeUnlock(); + } //}}} + + //}}} //{{{ getDocumentType() @@ -383,6 +376,114 @@ return m_properties; }//}}} + //{{{ getProperty() + + public String getProperty(String key) { + synchronized(propertyLock) { + // First try the buffer-local properties + String o = m_properties.getProperty(key); + if (o == null) { + // Now try xml.document.<property> + o = jsXe.getProperty("xml.document." + name); + } + return o; + } + }//}}} + + //{{{ setProperty() + public void settProperty(String key, String value) { + synchronized(propertyLock) { + if (value == null) { + m_properties.remove(key); + } else { + m_properties.setProperty(key, value); + } + } + }//}}} + + //{{{ getStringProperty() method + /** + * Returns the value of a string property. This method is thread-safe. + * @param name The property name + */ + public String getStringProperty(String name) { + Object obj = getProperty(name); + if (obj != null) { + return obj.toString(); + } else { + return null; + } + } //}}} + + //{{{ setStringProperty() method + /** + * Sets a string property. + * @param name The property name + * @param value The value + */ + public void setStringProperty(String name, String value) { + setProperty(name,value); + } //}}} + + //{{{ getBooleanProperty() method + /** + * Returns the value of a boolean property. This method is thread-safe. + * @param name The property name + */ + public boolean getBooleanProperty(String name) { + Object obj = getProperty(name); + if (obj == null) { + return null; + } + + if (obj instanceof Boolean) { + return ((Boolean)obj).booleanValue(); + } else { + return Boolean.valueOf(obj.toString()).booleanValue(); + } + } //}}} + + //{{{ setBooleanProperty() method + /** + * Sets a boolean property. + * @param name The property name + * @param value The value + */ + public void setBooleanProperty(String name, boolean value) { + setProperty(name, Boolean.valueOf(value)); + } //}}} + + //{{{ getIntegerProperty() method + /** + * Returns the value of an integer property. This method is thread-safe. + * @param name The property name + */ + public int getIntegerProperty(String name, int defaultValue) { + + boolean defaultValueFlag; + Object obj = getProperty(); + + if (obj == null) { + return defaultValue; + } else { + if (obj instanceof Number) { + return ((Number)obj).intValue(); + } else { + return defaultValue; + } + } + } //}}} + + //{{{ setIntegerProperty() method + /** + * Sets an integer property. + * @param name The property name + * @param value The value + */ + public void setIntegerProperty(String name, int value) { + setProperty(name, new Integer(value)); + } //}}} + //{{{ setURI() /** * Sets the URI for the location of this document. @@ -473,16 +574,6 @@ //{{{ Private members - //{{{ setDefaultProperties() - private void setDefaultProperties() { - putProperty(FORMAT_XML, "false"); - putProperty(IS_USING_SOFT_TABS, "false"); - putProperty(WS_IN_ELEMENT_CONTENT, "true"); - putProperty(ENCODING, "UTF-8"); - putProperty(INDENT, "4"); - putProperty(IS_VALIDATING, "false"); - }//}}} - //{{{ ContentManager class /** * Text content manager based off of jEdit's ContentManager class. @@ -712,11 +803,14 @@ private ContentManager m_content; - private HashMap m_properties = new HashMap(); + private Properties m_properties = new Properties(); private ArrayList m_docListeners = new ArrayList(); private ArrayList m_undoListeners = new ArrayList(); + private Object propertyLock = new Object(); + private ReadWriteLock lock = new ReadWriteLock(); + /** * The entity resolver to use when resolving external entities * in this document. Modified: branches/jsxe2/src/net/sourceforge/jsxe/dom2/XMLNode.java =================================================================== --- branches/jsxe2/src/net/sourceforge/jsxe/dom2/XMLNode.java 2006-07-28 20:04:32 UTC (rev 1081) +++ branches/jsxe2/src/net/sourceforge/jsxe/dom2/XMLNode.java 2006-07-28 22:46:19 UTC (rev 1082) @@ -53,6 +53,10 @@ * will correspond to text modifications to the XMLDocument. Direct text * modifications are only allowed at the XMLDocument level.</p> * + * <p>It is implement in the spirit of the {@link javax.swing.text.Element} + * class as it represents a piece of text as well as a structural element + * in the document.</p> + * * <p>It implements a subset of the support offered by standard w3c DOM * interfaces.</p> * @@ -61,7 +65,7 @@ * @see XMLDocument * @since jsXe 0.5 pre2 */ -public abstract class XMLNode implements javax.swing.text.Element { +public abstract class XMLNode { protected static final String USER_DATA_KEY = "net.sourceforge.jsxe.dom.XMLNode"; Modified: branches/jsxe2/src/net/sourceforge/jsxe/dom2/ls/XMLDocumentIORequest.java =================================================================== --- branches/jsxe2/src/net/sourceforge/jsxe/dom2/ls/XMLDocumentIORequest.java 2006-07-28 20:04:32 UTC (rev 1081) +++ branches/jsxe2/src/net/sourceforge/jsxe/dom2/ls/XMLDocumentIORequest.java 2006-07-28 22:46:19 UTC (rev 1082) @@ -23,22 +23,22 @@ from http://www.fsf.org/copyleft/gpl.txt */ -package org.gjt.sp.jedit.buffer; +package net.sourceforge.jsxe.dom2.ls; //{{{ Imports import javax.swing.text.Segment; import java.io.*; import java.util.zip.*; import java.util.Vector; -import org.gjt.sp.jedit.io.*; -import org.gjt.sp.jedit.*; -import org.gjt.sp.util.*; +import net.sourceforge.jsxe.io.*; +import net.sourceforge.jsxe.*; +import net.sourceforge.jsxe.util.*; //}}} /** * A document I/O request. * @author Slava Pestov - * @version $Id: BufferIORequest.java,v 1.28 2004/08/29 02:58:43 spestov Exp $ + * @version $Id$ */ public class XMLDocumentIORequest extends WorkRequest { @@ -53,12 +53,12 @@ */ public static final int PROGRESS_INTERVAL = 300; - public static final String LOAD_DATA = "BufferIORequest__loadData"; - public static final String END_OFFSETS = "BufferIORequest__endOffsets"; - public static final String NEW_PATH = "BufferIORequest__newPath"; + public static final String LOAD_DATA = "XMLDocumentIORequest__loadData"; + public static final String END_OFFSETS = "XMLDocumentIORequest__endOffsets"; + public static final String NEW_PATH = "XMLDocumentIORequest__newPath"; /** - * Buffer boolean property set when an error occurs. + * Boolean property set when an error occurs. */ public static final String ERROR_OCCURRED = "XMLDocumentIORequest__error"; @@ -173,7 +173,7 @@ //{{{ Instance variables private int type; private View view; - private Buffer buffer; + private XMLDocument buffer; private Object session; private VFS vfs; private String path; @@ -288,110 +288,96 @@ * Tries to detect if the stream is gzipped, and if it has an encoding * specified with an XML PI. */ - private Reader autodetect(InputStream in) throws IOException - { + private Reader autodetect(InputStream in) throws IOException { in = new BufferedInputStream(in); String encoding = buffer.getStringProperty(Buffer.ENCODING); - if(!in.markSupported()) + if (!in.markSupported()) { Log.log(Log.WARNING,this,"Mark not supported: " + in); - else if(buffer.getBooleanProperty(Buffer.ENCODING_AUTODETECT)) - { - in.mark(XML_PI_LENGTH); - int b1 = in.read(); - int b2 = in.read(); - int b3 = in.read(); - - if(encoding.equals(MiscUtilities.UTF_8_Y)) - { - // Java does not support this encoding so - // we have to handle it manually. - if(b1 != UTF8_MAGIC_1 || b2 != UTF8_MAGIC_2 - || b3 != UTF8_MAGIC_3) - { - // file does not begin with UTF-8-Y - // signature. reset stream, read as - // UTF-8. - in.reset(); - } - else - { - // file begins with UTF-8-Y signature. - // discard the signature, and read - // the remainder as UTF-8. - } - - encoding = "UTF-8"; - } - else if(b1 == GZIP_MAGIC_1 && b2 == GZIP_MAGIC_2) - { - in.reset(); - in = new GZIPInputStream(in); - buffer.setBooleanProperty(Buffer.GZIPPED,true); - // auto-detect encoding within the gzip stream. - return autodetect(in); - } - else if((b1 == UNICODE_MAGIC_1 - && b2 == UNICODE_MAGIC_2) - || (b1 == UNICODE_MAGIC_2 - && b2 == UNICODE_MAGIC_1)) - { - in.reset(); - encoding = "UTF-16"; - buffer.setProperty(Buffer.ENCODING,encoding); - } - else if(b1 == UTF8_MAGIC_1 && b2 == UTF8_MAGIC_2 - && b3 == UTF8_MAGIC_3) - { - // do not reset the stream and just treat it - // like a normal UTF-8 file. - buffer.setProperty(Buffer.ENCODING, - MiscUtilities.UTF_8_Y); - - encoding = "UTF-8"; - } - else - { - in.reset(); - - byte[] _xmlPI = new byte[XML_PI_LENGTH]; - int offset = 0; - int count; - while((count = in.read(_xmlPI,offset, - XML_PI_LENGTH - offset)) != -1) - { - offset += count; - if(offset == XML_PI_LENGTH) - break; - } - - String xmlPI = new String(_xmlPI,0,offset, - "ASCII"); - if(xmlPI.startsWith("<?xml")) - { - int index = xmlPI.indexOf("encoding="); - if(index != -1 - && index + 9 != xmlPI.length()) - { - char ch = xmlPI.charAt(index - + 9); - int endIndex = xmlPI.indexOf(ch, - index + 10); - encoding = xmlPI.substring( - index + 10,endIndex); - - if(MiscUtilities.isSupportedEncoding(encoding)) + } else { + if(buffer.getBooleanProperty(Buffer.ENCODING_AUTODETECT)) { + in.mark(XML_PI_LENGTH); + int b1 = in.read(); + int b2 = in.read(); + int b3 = in.read(); + + if (encoding.equals(MiscUtilities.UTF_8_Y)) { + // Java does not support this encoding so + // we have to handle it manually. + if (b1 != UTF8_MAGIC_1 || b2 != UTF8_MAGIC_2 || b3 != UTF8_MAGIC_3) { + // file does not begin with UTF-8-Y + // signature. reset stream, read as + // UTF-8. + in.reset(); + } else { + // file begins with UTF-8-Y signature. + // discard the signature, and read + // the remainder as UTF-8. + } + + encoding = "UTF-8"; + } else { + if (b1 == GZIP_MAGIC_1 && b2 == GZIP_MAGIC_2) { + in.reset(); + in = new GZIPInputStream(in); + buffer.setBooleanProperty(Buffer.GZIPPED,true); + // auto-detect encoding within the gzip stream. + return autodetect(in); + } else { + if ((b1 == UNICODE_MAGIC_1 + && b2 == UNICODE_MAGIC_2) + || (b1 == UNICODE_MAGIC_2 + && b2 == UNICODE_MAGIC_1)) { + in.reset(); + encoding = "UTF-16"; buffer.setProperty(Buffer.ENCODING,encoding); + } else { + if (b1 == UTF8_MAGIC_1 && b2 == UTF8_MAGIC_2 + && b3 == UTF8_MAGIC_3) + { + // do not reset the stream and just treat it + // like a normal UTF-8 file. + buffer.setProperty(Buffer.ENCODING, + MiscUtilities.UTF_8_Y); + + encoding = "UTF-8"; + } else { + in.reset(); + + byte[] _xmlPI = new byte[XML_PI_LENGTH]; + int offset = 0; + int count; + while((count = in.read(_xmlPI,offset, + XML_PI_LENGTH - offset)) != -1) + { + offset += count; + if(offset == XML_PI_LENGTH) + break; + } + + String xmlPI = new String(_xmlPI,0,offset, + "ASCII"); + if (xmlPI.startsWith("<?xml")) { + int index = xmlPI.indexOf("encoding="); + if (index != -1 && index + 9 != xmlPI.length()) { + char ch = xmlPI.charAt(index + 9); + int endIndex = xmlPI.indexOf(ch, index + 10); + encoding = xmlPI.substring(index + 10,endIndex); + + if (MiscUtilities.isSupportedEncoding(encoding)) { + buffer.setProperty(Buffer.ENCODING,encoding); + } else { + Log.log(Log.WARNING,this,"XML PI specifies unsupported encoding: " + encoding); + } + } + } + + in.reset(); + } } - else - { - Log.log(Log.WARNING,this,"XML PI specifies unsupported encoding: " + encoding); - } } } - - in.reset(); } } Modified: branches/jsxe2/src/net/sourceforge/jsxe/io/VFSManager.java =================================================================== --- branches/jsxe2/src/net/sourceforge/jsxe/io/VFSManager.java 2006-07-28 20:04:32 UTC (rev 1081) +++ branches/jsxe2/src/net/sourceforge/jsxe/io/VFSManager.java 2006-07-28 22:46:19 UTC (rev 1082) @@ -57,13 +57,13 @@ * * @author Slava Pestov * @author Ian Lewis (<a href="mailto:Ian...@me...">Ian...@me...</a>) - * @version $Id: VFSManager.java,v 1.15 2004/05/10 03:21:11 spestov Exp $ + * @version $Id$ */ public class VFSManager { /** * The service type. See {@link org.gjt.sp.jedit.ServiceManager}. */ - public static final String SERVICE = "org.gjt.sp.jedit.io.VFS"; + public static final String SERVICE = "net.sourceforge.jsxe.io.VFS"; //{{{ init() method /** @@ -95,7 +95,6 @@ //{{{ getFileVFS() method /** * Returns the local filesystem VFS. - * @since jEdit 2.5pre1 */ public static VFS getFileVFS() { @@ -105,7 +104,6 @@ //{{{ getUrlVFS() method /** * Returns the URL VFS. - * @since jEdit 2.5pre1 */ public static VFS getUrlVFS() { @@ -130,7 +128,6 @@ /** * Returns the VFS for the specified protocol. * @param protocol The protocol - * @since jEdit 2.5pre1 */ public static VFS getVFSForProtocol(String protocol) { @@ -153,7 +150,6 @@ /** * Returns the VFS for the specified path. * @param path The path - * @since jEdit 2.6pre4 */ public static VFS getVFSForPath(String path) { @@ -189,7 +185,6 @@ //{{{ getVFSs() method /** * Returns a list of all registered filesystems. - * @since jEdit 4.2pre1 */ public static String[] getVFSs() { @@ -227,7 +222,6 @@ //{{{ waitForRequests() method /** * Returns when all pending requests are complete. - * @since jEdit 2.5pre1 */ public static void waitForRequests() { @@ -256,7 +250,6 @@ /** * Executes the specified runnable in the AWT thread once all * pending I/O requests are complete. - * @since jEdit 2.5pre1 */ public static void runInAWTThread(Runnable run) { @@ -266,7 +259,6 @@ //{{{ runInWorkThread() method /** * Executes the specified runnable in one of the I/O threads. - * @since jEdit 2.6pre2 */ public static void runInWorkThread(Runnable run) { @@ -318,7 +310,6 @@ * @param path The path name that caused the error * @param messageProp The error message property name * @param args Positional parameters - * @since jEdit 4.0pre3 */ public static void error(Component comp, final String path, @@ -367,7 +358,6 @@ * @param path The path that changed * @param parent True if an update should be sent for the path's * parent too - * @since jEdit 2.6pre4 */ public static void sendVFSUpdate(VFS vfs, String path, boolean parent) { Modified: branches/jsxe2/src/net/sourceforge/jsxe/properties =================================================================== --- branches/jsxe2/src/net/sourceforge/jsxe/properties 2006-07-28 20:04:32 UTC (rev 1081) +++ branches/jsxe2/src/net/sourceforge/jsxe/properties 2006-07-28 22:46:19 UTC (rev 1082) @@ -45,4 +45,11 @@ metal.secondary.fontstyle=0 #}}} - +#{{{ XMLDocument default properties +xml.document.encoding=UTF-8 +xml.document.element-content-whitespace=true +xml.document.format-pretty-print=false +xml.document.soft-tabs=false +xml.document.indent=4 +xml.document.validating=false +#}}} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |