OSDN Git Service

[Moxkiriya7]
authorryuhei__terada <shimenoya@gmail.com>
Sun, 4 Nov 2018 02:38:34 +0000 (11:38 +0900)
committerryuhei__terada <shimenoya@gmail.com>
Sun, 4 Nov 2018 02:38:34 +0000 (11:38 +0900)
 * Moxkiriya7ソースレポジトリを作成

104 files changed:
Moxkiriya7/.classpath [new file with mode: 0644]
Moxkiriya7/.gitignore [new file with mode: 0644]
Moxkiriya7/.project [new file with mode: 0644]
Moxkiriya7/.settings/org.eclipse.core.resources.prefs [new file with mode: 0644]
Moxkiriya7/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
Moxkiriya7/build.fxbuild [new file with mode: 0644]
Moxkiriya7/gimp/Icon.xcf [new file with mode: 0644]
Moxkiriya7/lib/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar [new file with mode: 0644]
Moxkiriya7/lib/commons-dbcp/commons-dbcp/1.3/commons-dbcp-1.3.jar [new file with mode: 0644]
Moxkiriya7/lib/commons-io/commons-io/2.6/commons-io-2.6.jar [new file with mode: 0644]
Moxkiriya7/lib/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4.jar [new file with mode: 0644]
Moxkiriya7/lib/concurrent/concurrent/1.3.4/concurrent-1.3.4.jar [new file with mode: 0644]
Moxkiriya7/lib/javax/jcr/jcr/2.0/jcr-2.0.jar [new file with mode: 0644]
Moxkiriya7/lib/log4j/log4j/1.2.17/log4j-1.2.17.jar [new file with mode: 0644]
Moxkiriya7/lib/org/apache/derby/derby/10.12.1.1/derby-10.12.1.1.jar [new file with mode: 0644]
Moxkiriya7/lib/org/apache/derby/derby/10.12.1.1/derbyclient.jar [new file with mode: 0644]
Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-api/2.14.5/jackrabbit-api-2.14.5.jar [new file with mode: 0644]
Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-bundle/2.14.5/jackrabbit-bundle-2.14.5.jar [new file with mode: 0644]
Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-core/2.14.5/jackrabbit-core-2.14.5.jar [new file with mode: 0644]
Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-data/2.14.5/jackrabbit-data-2.14.5.jar [new file with mode: 0644]
Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-jcr-commons/2.14.5/jackrabbit-jcr-commons-2.14.5.jar [new file with mode: 0644]
Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-spi-commons/2.14.5/jackrabbit-spi-commons-2.14.5.jar [new file with mode: 0644]
Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-spi/2.14.5/jackrabbit-spi-2.14.5.jar [new file with mode: 0644]
Moxkiriya7/lib/org/apache/lucene/lucene-core/3.6.0/lucene-core-3.6.0.jar [new file with mode: 0644]
Moxkiriya7/lib/org/apache/tika/tika-core/1.17/tika-core-1.17.jar [new file with mode: 0644]
Moxkiriya7/lib/org/slf4j/slf4j-api/1.7.5/slf4j-api-1.7.5.jar [new file with mode: 0644]
Moxkiriya7/lib/org/slf4j/slf4j-simple/1.6.6/slf4j-simple-1.6.6.jar [new file with mode: 0644]
Moxkiriya7/lib/xalan/serializer/2.7.1/serializer-2.7.1.jar [new file with mode: 0644]
Moxkiriya7/lib/xalan/xalan/2.7.1/xalan-2.7.1.jar [new file with mode: 0644]
Moxkiriya7/lib/xerces/xercesImpl/2.9.1/xercesImpl-2.9.1.jar [new file with mode: 0644]
Moxkiriya7/license/gpl.txt [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/Main.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/PageData.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/ResourceManager.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/SettingManager.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiEngine.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiHistory.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiMainWindow.fxml [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiMainWindow.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiMainWindowController.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiPreviewWindow.fxml [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiPreviewWindow.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiPreviewWindowController.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiRepository.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/application.css [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AboutMoxkiriyaDialog.fxml [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AboutMoxkiriyaDialog.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AboutMoxkiriyaDialogController.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AlertDialog.fxml [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AlertDialog.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AlertDialogController.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/ConfigSettingsDialog.fxml [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/ConfigSettingsDialog.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/ConfigSettingsDialogController.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/DialogBase.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/DialogController.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/DialogControllerBase.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/PageList.fxml [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/SelectPartyDialog.fxml [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/SelectPartyDialog.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/SelectPartyDialogController.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/dialog.css [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockParserBase.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockParserCreator.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockquoteBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBodyBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiCodeBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiDefaultBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiHnBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiHrBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiOrderedListBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiPreBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiTOCBuilder.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiTableBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiTableRowBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiUnorderedListBlockParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiBoldInlineParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiDefaultInlineParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiExternalLinkInlineParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInlineParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInlineParserBase.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInlineParserCreator.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInternalLinkInlineParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiItalicInlineParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiLineThroughInlineParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiOrderedListItemInlineParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiUnderlineInlineParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiUnorderedListItemInlineParser.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/defaultstylesheet.css [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/fixedstylesheet.css [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/icon/Icon_External_Link.png [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_alert.png [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_confirm.png [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_error.png [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_info.jpg [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/image_processing.gif [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/moxkiriya.properties [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/repository_cluster_derby.xml [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/repository_local.xml [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/templateHtmlHead.txt [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/util/DefaultProgramExecutor.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/util/FileIO.java [new file with mode: 0644]
Moxkiriya7/src/com/wiki/standalone/moxkiriya/util/FileTypeDeterminator.java [new file with mode: 0644]

diff --git a/Moxkiriya7/.classpath b/Moxkiriya7/.classpath
new file mode 100644 (file)
index 0000000..483794b
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+       <classpathentry exported="true" kind="con" path="org.eclipse.fx.ide.jdt.core.JAVAFX_CONTAINER"/>
+       <classpathentry kind="lib" path="lib/javax/jcr/jcr/2.0/jcr-2.0.jar"/>
+       <classpathentry kind="lib" path="lib/org/apache/derby/derby/10.12.1.1/derby-10.12.1.1.jar"/>
+       <classpathentry kind="lib" path="lib/org/apache/jackrabbit/jackrabbit-api/2.14.5/jackrabbit-api-2.14.5.jar"/>
+       <classpathentry kind="lib" path="lib/org/apache/jackrabbit/jackrabbit-bundle/2.14.5/jackrabbit-bundle-2.14.5.jar"/>
+       <classpathentry kind="lib" path="lib/org/apache/jackrabbit/jackrabbit-core/2.14.5/jackrabbit-core-2.14.5.jar" sourcepath="C:/usr/local/src/Apache_Jackrabbit/jackrabbit-2.14.5/jackrabbit-core/src/main/java"/>
+       <classpathentry kind="lib" path="lib/org/apache/jackrabbit/jackrabbit-data/2.14.5/jackrabbit-data-2.14.5.jar" sourcepath="C:/usr/local/src/Apache_Jackrabbit/jackrabbit-2.14.5/jackrabbit-core/src/main/java"/>
+       <classpathentry kind="lib" path="lib/org/apache/jackrabbit/jackrabbit-jcr-commons/2.14.5/jackrabbit-jcr-commons-2.14.5.jar"/>
+       <classpathentry kind="lib" path="lib/org/apache/jackrabbit/jackrabbit-spi/2.14.5/jackrabbit-spi-2.14.5.jar"/>
+       <classpathentry kind="lib" path="lib/org/apache/jackrabbit/jackrabbit-spi-commons/2.14.5/jackrabbit-spi-commons-2.14.5.jar"/>
+       <classpathentry kind="lib" path="lib/org/apache/lucene/lucene-core/3.6.0/lucene-core-3.6.0.jar"/>
+       <classpathentry kind="lib" path="lib/org/apache/tika/tika-core/1.17/tika-core-1.17.jar"/>
+       <classpathentry kind="lib" path="lib/org/slf4j/slf4j-api/1.7.5/slf4j-api-1.7.5.jar"/>
+       <classpathentry kind="lib" path="lib/org/slf4j/slf4j-simple/1.6.6/slf4j-simple-1.6.6.jar"/>
+       <classpathentry kind="lib" path="lib/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar"/>
+       <classpathentry kind="lib" path="lib/commons-dbcp/commons-dbcp/1.3/commons-dbcp-1.3.jar"/>
+       <classpathentry kind="lib" path="lib/commons-io/commons-io/2.6/commons-io-2.6.jar"/>
+       <classpathentry kind="lib" path="lib/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4.jar"/>
+       <classpathentry kind="lib" path="lib/concurrent/concurrent/1.3.4/concurrent-1.3.4.jar"/>
+       <classpathentry kind="lib" path="lib/log4j/log4j/1.2.17/log4j-1.2.17.jar"/>
+       <classpathentry kind="lib" path="lib/xalan/serializer/2.7.1/serializer-2.7.1.jar"/>
+       <classpathentry kind="lib" path="lib/xalan/xalan/2.7.1/xalan-2.7.1.jar"/>
+       <classpathentry kind="lib" path="lib/xerces/xercesImpl/2.9.1/xercesImpl-2.9.1.jar"/>
+       <classpathentry kind="lib" path="lib/org/apache/derby/derby/10.12.1.1/derbyclient.jar"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/Moxkiriya7/.gitignore b/Moxkiriya7/.gitignore
new file mode 100644 (file)
index 0000000..c085272
--- /dev/null
@@ -0,0 +1,2 @@
+bin
+derby.log
diff --git a/Moxkiriya7/.project b/Moxkiriya7/.project
new file mode 100644 (file)
index 0000000..1461df7
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>Moxkiriya7</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/Moxkiriya7/.settings/org.eclipse.core.resources.prefs b/Moxkiriya7/.settings/org.eclipse.core.resources.prefs
new file mode 100644 (file)
index 0000000..ee0079f
--- /dev/null
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+encoding//src/com/wiki/standalone/moxkiriya/resources/defaultstylesheet.css=UTF-8
+encoding/license=UTF-8
diff --git a/Moxkiriya7/.settings/org.eclipse.jdt.core.prefs b/Moxkiriya7/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..e40c773
--- /dev/null
@@ -0,0 +1,13 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/Moxkiriya7/build.fxbuild b/Moxkiriya7/build.fxbuild
new file mode 100644 (file)
index 0000000..200ac4e
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ASCII"?>
+<anttasks:AntTask xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:anttasks="http://org.eclipse.fx.ide.jdt/1.0" buildDirectory="${project}/build">
+  <deploy>
+    <application name="Wall-E"/>
+    <info/>
+  </deploy>
+  <signjar/>
+</anttasks:AntTask>
diff --git a/Moxkiriya7/gimp/Icon.xcf b/Moxkiriya7/gimp/Icon.xcf
new file mode 100644 (file)
index 0000000..8208631
Binary files /dev/null and b/Moxkiriya7/gimp/Icon.xcf differ
diff --git a/Moxkiriya7/lib/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar b/Moxkiriya7/lib/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar
new file mode 100644 (file)
index 0000000..fa5df82
Binary files /dev/null and b/Moxkiriya7/lib/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar differ
diff --git a/Moxkiriya7/lib/commons-dbcp/commons-dbcp/1.3/commons-dbcp-1.3.jar b/Moxkiriya7/lib/commons-dbcp/commons-dbcp/1.3/commons-dbcp-1.3.jar
new file mode 100644 (file)
index 0000000..d293397
Binary files /dev/null and b/Moxkiriya7/lib/commons-dbcp/commons-dbcp/1.3/commons-dbcp-1.3.jar differ
diff --git a/Moxkiriya7/lib/commons-io/commons-io/2.6/commons-io-2.6.jar b/Moxkiriya7/lib/commons-io/commons-io/2.6/commons-io-2.6.jar
new file mode 100644 (file)
index 0000000..00556b1
Binary files /dev/null and b/Moxkiriya7/lib/commons-io/commons-io/2.6/commons-io-2.6.jar differ
diff --git a/Moxkiriya7/lib/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4.jar b/Moxkiriya7/lib/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4.jar
new file mode 100644 (file)
index 0000000..43edf99
Binary files /dev/null and b/Moxkiriya7/lib/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4.jar differ
diff --git a/Moxkiriya7/lib/concurrent/concurrent/1.3.4/concurrent-1.3.4.jar b/Moxkiriya7/lib/concurrent/concurrent/1.3.4/concurrent-1.3.4.jar
new file mode 100644 (file)
index 0000000..551f347
Binary files /dev/null and b/Moxkiriya7/lib/concurrent/concurrent/1.3.4/concurrent-1.3.4.jar differ
diff --git a/Moxkiriya7/lib/javax/jcr/jcr/2.0/jcr-2.0.jar b/Moxkiriya7/lib/javax/jcr/jcr/2.0/jcr-2.0.jar
new file mode 100644 (file)
index 0000000..6afce9b
Binary files /dev/null and b/Moxkiriya7/lib/javax/jcr/jcr/2.0/jcr-2.0.jar differ
diff --git a/Moxkiriya7/lib/log4j/log4j/1.2.17/log4j-1.2.17.jar b/Moxkiriya7/lib/log4j/log4j/1.2.17/log4j-1.2.17.jar
new file mode 100644 (file)
index 0000000..1d425cf
Binary files /dev/null and b/Moxkiriya7/lib/log4j/log4j/1.2.17/log4j-1.2.17.jar differ
diff --git a/Moxkiriya7/lib/org/apache/derby/derby/10.12.1.1/derby-10.12.1.1.jar b/Moxkiriya7/lib/org/apache/derby/derby/10.12.1.1/derby-10.12.1.1.jar
new file mode 100644 (file)
index 0000000..5841555
Binary files /dev/null and b/Moxkiriya7/lib/org/apache/derby/derby/10.12.1.1/derby-10.12.1.1.jar differ
diff --git a/Moxkiriya7/lib/org/apache/derby/derby/10.12.1.1/derbyclient.jar b/Moxkiriya7/lib/org/apache/derby/derby/10.12.1.1/derbyclient.jar
new file mode 100644 (file)
index 0000000..f9bf5b9
Binary files /dev/null and b/Moxkiriya7/lib/org/apache/derby/derby/10.12.1.1/derbyclient.jar differ
diff --git a/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-api/2.14.5/jackrabbit-api-2.14.5.jar b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-api/2.14.5/jackrabbit-api-2.14.5.jar
new file mode 100644 (file)
index 0000000..924ee11
Binary files /dev/null and b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-api/2.14.5/jackrabbit-api-2.14.5.jar differ
diff --git a/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-bundle/2.14.5/jackrabbit-bundle-2.14.5.jar b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-bundle/2.14.5/jackrabbit-bundle-2.14.5.jar
new file mode 100644 (file)
index 0000000..077add3
Binary files /dev/null and b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-bundle/2.14.5/jackrabbit-bundle-2.14.5.jar differ
diff --git a/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-core/2.14.5/jackrabbit-core-2.14.5.jar b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-core/2.14.5/jackrabbit-core-2.14.5.jar
new file mode 100644 (file)
index 0000000..91f3fce
Binary files /dev/null and b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-core/2.14.5/jackrabbit-core-2.14.5.jar differ
diff --git a/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-data/2.14.5/jackrabbit-data-2.14.5.jar b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-data/2.14.5/jackrabbit-data-2.14.5.jar
new file mode 100644 (file)
index 0000000..5b545da
Binary files /dev/null and b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-data/2.14.5/jackrabbit-data-2.14.5.jar differ
diff --git a/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-jcr-commons/2.14.5/jackrabbit-jcr-commons-2.14.5.jar b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-jcr-commons/2.14.5/jackrabbit-jcr-commons-2.14.5.jar
new file mode 100644 (file)
index 0000000..ba79181
Binary files /dev/null and b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-jcr-commons/2.14.5/jackrabbit-jcr-commons-2.14.5.jar differ
diff --git a/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-spi-commons/2.14.5/jackrabbit-spi-commons-2.14.5.jar b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-spi-commons/2.14.5/jackrabbit-spi-commons-2.14.5.jar
new file mode 100644 (file)
index 0000000..b7f4f83
Binary files /dev/null and b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-spi-commons/2.14.5/jackrabbit-spi-commons-2.14.5.jar differ
diff --git a/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-spi/2.14.5/jackrabbit-spi-2.14.5.jar b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-spi/2.14.5/jackrabbit-spi-2.14.5.jar
new file mode 100644 (file)
index 0000000..f553bde
Binary files /dev/null and b/Moxkiriya7/lib/org/apache/jackrabbit/jackrabbit-spi/2.14.5/jackrabbit-spi-2.14.5.jar differ
diff --git a/Moxkiriya7/lib/org/apache/lucene/lucene-core/3.6.0/lucene-core-3.6.0.jar b/Moxkiriya7/lib/org/apache/lucene/lucene-core/3.6.0/lucene-core-3.6.0.jar
new file mode 100644 (file)
index 0000000..5cb8dae
Binary files /dev/null and b/Moxkiriya7/lib/org/apache/lucene/lucene-core/3.6.0/lucene-core-3.6.0.jar differ
diff --git a/Moxkiriya7/lib/org/apache/tika/tika-core/1.17/tika-core-1.17.jar b/Moxkiriya7/lib/org/apache/tika/tika-core/1.17/tika-core-1.17.jar
new file mode 100644 (file)
index 0000000..93b72c7
Binary files /dev/null and b/Moxkiriya7/lib/org/apache/tika/tika-core/1.17/tika-core-1.17.jar differ
diff --git a/Moxkiriya7/lib/org/slf4j/slf4j-api/1.7.5/slf4j-api-1.7.5.jar b/Moxkiriya7/lib/org/slf4j/slf4j-api/1.7.5/slf4j-api-1.7.5.jar
new file mode 100644 (file)
index 0000000..8f004d3
Binary files /dev/null and b/Moxkiriya7/lib/org/slf4j/slf4j-api/1.7.5/slf4j-api-1.7.5.jar differ
diff --git a/Moxkiriya7/lib/org/slf4j/slf4j-simple/1.6.6/slf4j-simple-1.6.6.jar b/Moxkiriya7/lib/org/slf4j/slf4j-simple/1.6.6/slf4j-simple-1.6.6.jar
new file mode 100644 (file)
index 0000000..1194ceb
Binary files /dev/null and b/Moxkiriya7/lib/org/slf4j/slf4j-simple/1.6.6/slf4j-simple-1.6.6.jar differ
diff --git a/Moxkiriya7/lib/xalan/serializer/2.7.1/serializer-2.7.1.jar b/Moxkiriya7/lib/xalan/serializer/2.7.1/serializer-2.7.1.jar
new file mode 100644 (file)
index 0000000..99f98db
Binary files /dev/null and b/Moxkiriya7/lib/xalan/serializer/2.7.1/serializer-2.7.1.jar differ
diff --git a/Moxkiriya7/lib/xalan/xalan/2.7.1/xalan-2.7.1.jar b/Moxkiriya7/lib/xalan/xalan/2.7.1/xalan-2.7.1.jar
new file mode 100644 (file)
index 0000000..458fa73
Binary files /dev/null and b/Moxkiriya7/lib/xalan/xalan/2.7.1/xalan-2.7.1.jar differ
diff --git a/Moxkiriya7/lib/xerces/xercesImpl/2.9.1/xercesImpl-2.9.1.jar b/Moxkiriya7/lib/xerces/xercesImpl/2.9.1/xercesImpl-2.9.1.jar
new file mode 100644 (file)
index 0000000..547f563
Binary files /dev/null and b/Moxkiriya7/lib/xerces/xercesImpl/2.9.1/xercesImpl-2.9.1.jar differ
diff --git a/Moxkiriya7/license/gpl.txt b/Moxkiriya7/license/gpl.txt
new file mode 100644 (file)
index 0000000..f288702
--- /dev/null
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/Main.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/Main.java
new file mode 100644 (file)
index 0000000..5ae2da2
--- /dev/null
@@ -0,0 +1,189 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Main routine.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+
+package com.wiki.standalone.moxkiriya;
+       
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.ResourceBundle;
+
+import com.wiki.standalone.moxkiriya.dialog.ConfigSettingsDialog;
+import com.wiki.standalone.moxkiriya.dialog.DialogBase.CloseType;
+import com.wiki.standalone.moxkiriya.dialog.SelectPartyDialog;
+
+import javafx.application.Application;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+
+/**
+ * Application Main.
+ * 
+ *
+ */
+public class Main extends Application {
+       /** primary stage. */
+       private Stage primaryStage_ = null;
+
+       /** Setting Manager */
+       private SettingManager settingManager_ = null;
+
+       /** Resource Bundle */
+       private ResourceBundle resources_;
+
+       /** Resource Manager */
+       public static ResourceManager resourceManagr_ = new ResourceManager();
+
+       /** Wiki Main window */
+       private WikiMainWindow wikiMainWindow_;
+
+       /**
+        * Main routine for this Application.
+        * @param args
+        */
+       public static void main(String[] args) {
+               launch(args);
+       }
+
+       @Override
+       public void start(Stage primaryStage) {
+               primaryStage_   = primaryStage;
+               settingManager_ = SettingManager.getInstance();
+               resources_      = ResourceBundle.getBundle("com.wiki.standalone.moxkiriya.resources.moxkiriya");
+
+               try {
+                       WikiMainWindow.CloseType closeType = WikiMainWindow.CloseType.EXIT;
+
+                       do {
+                               String AppRoot  = null;
+                               String wikiroot = null;
+                               String selectedParty = loadSelectedParty();
+
+                               if(selectedParty != null) {
+                                       AppRoot  = settingManager_.get(SettingManager.SETINGKEY_MOXKIRIYAROOT);
+                                       wikiroot = settingManager_.get(SettingManager.SETTINGSKEY_WIKIROOT);                                    
+                               }
+                               
+                               if( (AppRoot == null)
+                                || (wikiroot == null)) {
+                                       /*
+                                        * selectPartyを未設定の場合
+                                        */
+                                       Stage stage  = new Stage(StageStyle.UNDECORATED);
+                                       stage.initOwner(primaryStage);
+                                       showConfigSettingsDialog(stage, selectedParty);
+                               }
+
+                               /*
+                                * Show a wiki main window.
+                                */
+                               closeType = showWikiMainWindow();
+                               
+                               if(closeType == WikiMainWindow.CloseType.RESTART) {
+                                       wikiMainWindow_.closeSession();
+                               }
+                       } while(closeType != WikiMainWindow.CloseType.EXIT);
+               } catch(Exception e) {
+                       e.printStackTrace();
+               } finally {
+                       if(wikiMainWindow_ != null) {
+                               wikiMainWindow_.closeSession();
+                       }
+                       primaryStage_.hide();
+               }
+       }
+
+       /**
+        * Show wiki main window.
+        * @throws Exception
+        */
+       private WikiMainWindow.CloseType showWikiMainWindow() throws Exception {
+               WikiMainWindow.CloseType closeType = WikiMainWindow.CloseType.EXIT;
+               String                   appRoot   = settingManager_.get(SettingManager.SETINGKEY_MOXKIRIYAROOT);
+
+               if(appRoot != null) {
+                       File    wikirootPath = new File(appRoot + "/" + WikiEngine.WIKIROOT_DIRECTORY);
+       
+                       if (wikirootPath != null) {
+                               wikirootPath.mkdirs();
+       
+                               wikiMainWindow_ = new WikiMainWindow(primaryStage_, resources_);
+       
+                               /*
+                                * wikirootに MainPageを構築する。
+                                */
+                               wikiMainWindow_.buildWikiMainTree(wikirootPath);
+       
+                               /*
+                                * 外部リンクアイコン画像をApprootにアップロードする。
+                                */
+                               wikiMainWindow_.uploadResourcefile(appRoot + "/icon/Icon_External_Link.png",
+                                               "icon/Icon_External_Link.png");
+       
+                               closeType = wikiMainWindow_.show();
+                       }
+               }
+               
+               return closeType;
+       }
+       
+       /**
+        * Load default party.
+        * @return String
+        * @throws Exception
+        */
+       private String loadSelectedParty() throws Exception {
+               String selectedParty = settingManager_.getSelectedParty();
+               
+               if( (selectedParty != null)
+                && (selectedParty.isEmpty() == true)) {
+                       ArrayList<String> partyList = settingManager_.getPartyList();
+                       
+                       if(partyList.isEmpty() != true) {
+                               SelectPartyDialog dialog = new SelectPartyDialog();
+                               if(dialog.showDialog(primaryStage_, resources_) == CloseType.OK) {
+                                       String path     = settingManager_.get(SettingManager.SETTINGSKEY_MOXKIRIYA_USER_DIR);
+                                       settingManager_.savePartyConfig(path);                                  
+                                       selectedParty = settingManager_.getSelectedParty();
+                               }
+                               else {
+                                       selectedParty = "";
+                               }
+                       }
+               }
+               
+               return selectedParty;
+       }
+       
+       
+       /**
+        * WikiConfigSettingDialogを表示する。
+        * @param primaryStage
+        * @param selectedParty
+        * @throws Exception 
+        */
+       private void showConfigSettingsDialog(Stage stage, String selectedParty) throws Exception {
+               ConfigSettingsDialog dialog = new ConfigSettingsDialog(selectedParty);
+               dialog.showDialog(stage, resources_);
+
+               Hashtable<String, String> settingsTable = dialog.getSettingsTable();
+               String                    path          = settingManager_.get(SettingManager.SETTINGSKEY_MOXKIRIYA_USER_DIR);
+
+               if( (selectedParty == null)
+                || (selectedParty.isEmpty() == true)) {
+                       selectedParty = dialog.getPartyName();
+               }
+
+               if(selectedParty.isEmpty() != true) {
+                       settingManager_.putParty(selectedParty, dialog.getDefaultPartyCheckValue());
+                       settingManager_.savePartyConfig(path);
+                       settingManager_.saveSettingConfig(path, selectedParty, settingsTable);
+                       settingManager_.loadSettingFiles(path);
+               }
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/PageData.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/PageData.java
new file mode 100644 (file)
index 0000000..c34868f
--- /dev/null
@@ -0,0 +1,508 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Page data structure.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.regex.Pattern;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.version.Version;
+
+import com.wiki.standalone.moxkiriya.util.FileIO;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+
+/**
+ * Page data structure.
+ *
+ */
+public class PageData {
+       /** JCR node */
+       private Node node_ = null;
+
+       /** Base version */
+       private Version baseVersion_ = null;
+       
+       /** namespace: Main, File, or Category. */
+       private SimpleStringProperty namespace_ = new SimpleStringProperty("");
+       
+       /** page title */
+       private SimpleStringProperty title_ = new SimpleStringProperty("");
+       
+       /** content */
+       private SimpleStringProperty content_ = new SimpleStringProperty("");;
+
+       /** date */
+       private SimpleStringProperty date_ = new SimpleStringProperty("");;
+
+       /** check in Page list view */
+       private SimpleBooleanProperty check_  = new SimpleBooleanProperty(false);
+       
+       /** categories */
+       private ArrayList<String> categories_ = new ArrayList<String>();
+       
+       /** file data */
+       private FileData fileData_ = null;
+
+       /**
+        * Constructor.
+        */
+       public PageData() {
+       }
+
+       /**
+        * Constructor.
+        * @throws Exception
+        */
+       public PageData(Node node) throws Exception {
+               setNode(node);
+       }
+
+       /**
+        * Node getter.
+        * @return Node
+        */
+       public Node getNode() {
+               return node_;
+       }
+
+       /**
+        * node setter
+        * @param node
+        * @throws Exception
+        */
+       public void setNode(Node node) throws Exception {
+               try {
+                       node_ = node;
+       
+                       namespace_.setValue(node.getProperty(WikiRepository.PROPERTY_NAMESPACE).getString());
+                       title_.setValue(node.getProperty(WikiRepository.PROPERTY_TITLE).getString());
+                       content_.setValue(node.getProperty(WikiRepository.PROPERTY_CONTENT).getString());
+                       
+                       Value[] categories = node.getProperty(WikiRepository.PROPERTY_category).getValues();
+                       for(Value category: categories) {
+                               addCategory(category.getString());                      
+                       }
+                       
+                       Node fileNode = node.getNode(WikiRepository.NODE_FILE);
+                       if(fileNode != null) {
+                               fileData_ = new FileData(fileNode);
+                       }
+               } catch(PathNotFoundException e) {
+                       // Ignore exception.
+               }
+       }
+
+       /**
+        * UUID property getter.
+        * @return StringProperty
+        */
+       public StringProperty uuidProperty() {
+               SimpleStringProperty property = new SimpleStringProperty();
+
+               try {
+                       property.setValue(node_.getProperty(Property.JCR_UUID).getString());
+               } catch (RepositoryException e) {
+                       e.printStackTrace();
+               }
+               
+               return property;
+       }
+
+       /**
+        * Check property getter.
+        * @return BooleanProperty
+        */
+       public BooleanProperty checkProperty() {
+               return check_;
+       }
+
+       /**
+        * Namespace getter.
+        * @return String
+        */
+       public String getNamespace() {
+               return namespace_.getValue();
+       }
+       
+       /**
+        * Namespace setter.
+        * @param namespace
+        */
+       public void setNamespace(String namespace) {
+               namespace_.setValue(namespace);
+       }
+
+       /**
+        * Title getter.
+        * @return String
+        */
+       public String getTitle() {
+               return title_.getValue();
+       }
+       
+       /**
+        * Title setter.
+        * @param title
+        */
+       public void setTitle(String title) {
+               title_.setValue(title);
+       }
+
+       /**
+        * titleProperty getter.
+        * @return StringProperty
+        */
+       public StringProperty titleProperty() {
+               return title_;
+       }
+
+       /**
+        * Content getter.
+        * @return String
+        */
+       public String getContent() {
+               return content_.getValue();
+       }
+       
+       /**
+        * Content setter.
+        * @param title
+        */
+       public void setContent(String content) {
+               content_.setValue(content);
+               categories_ = extractCategoriesFromContent(content);
+       }
+
+       /**
+        * Introduction getter.
+        * Introduction is the first part of the page.
+        * The part is extracted until the following conditions are satisfied.
+        * <ul>
+        * <li>Up to the first heading.</li>
+        * <li>255 characters</li>
+        * <li>3 lines</li>
+        * </ul>
+        * @return String
+        * @throws Exception
+        */
+       public String getIntroduction() throws Exception {
+               BufferedReader buffreader = FileIO.bufferedReader(new StringReader(content_.getValue()));
+               String         line;
+               StringBuffer   buf        = new StringBuffer("");
+               int            lineCount  = 0;
+               int            charCount  = 0;
+               Pattern        hnPattern  = Pattern.compile("^={2,6}[^=]+={2,6}$");
+               
+               while((line = buffreader.readLine()) != null) {
+                       if(hnPattern.matcher(line).matches() == true) {
+                               break;
+                       }
+                       else if(charCount + line.length() > 255) {
+                               buf.append(line.substring(0, 255 - charCount));
+                               charCount = 255;
+                               break;
+                       }
+                       else {
+                               buf.append(line + "\n");
+                               charCount += line.length() + 1;
+                               lineCount++;
+                               
+                               if(lineCount >= 3) {
+                                       break;
+                               }
+                       }
+               }
+               
+               String intro = buf.toString();
+               
+               return intro.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
+       }
+       
+       /**
+        * contentProperty getter.
+        * @return StringProperty
+        */
+       public StringProperty introductionProperty() {
+               String introduction = "";
+               try {
+                       introduction = getIntroduction();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+               return new SimpleStringProperty(introduction);
+       }
+       
+       /**
+        * dateProperty getter.
+        * @return StringProperty
+        */
+       public StringProperty dateProperty() {
+               String date = "";
+               try {
+                       date                = baseVersion_.getCreated().getTime().toString();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+               return new SimpleStringProperty(date);
+       }
+
+       /**
+        * Base version setter.
+        * @param baseVersion
+        */
+       public void setBaseVersion(Version baseVersion) {
+               baseVersion_ = baseVersion;
+       }
+       
+       /**
+        * Categories getter.
+        * @return ArrayList<String>
+        */
+       public ArrayList<String> getCategories() {
+               return categories_;
+       }
+       
+       /**
+        * Categories setter.
+        * @param category
+        */
+       public void addCategory(String category) {
+               categories_.add(category);
+       }
+       
+       /**
+        * File data getter.
+        * @return FileData
+        */
+       public FileData getFileData() {
+               return fileData_;
+       }
+       
+       /**
+        * Content setter.
+        * @param title
+        * @throws Exception 
+        */
+       public void setFileData(File file) throws Exception {
+               fileData_ = new FileData(file);
+       }
+
+       /**
+        * content から Categories を抽出する。
+        * @param content
+        * @return ArrayList<String>
+        */
+       private ArrayList<String> extractCategoriesFromContent(String content) {
+               ArrayList<String> categories       = new ArrayList<String>();
+               char[]            charArrayContent = content.toCharArray();
+               int               count            = 0;
+
+               while(count < charArrayContent.length) {
+                       if(charArrayContent[count] == '<') {
+                               String sub = content.substring(count);
+
+                               if(content.startsWith("<code>")) {
+                                       count += extractCategoriesSkipElem(sub, "<code>", "</code>");
+                               }
+                               else if(sub.startsWith("<pre>")) {
+                                       count += extractCategoriesSkipElem(sub, "<pre>", "</pre>");
+                               }
+                               else {
+                                       count++;
+                               }
+                       }
+                       else if(charArrayContent[count] == '[') {
+                               if(content.startsWith("[[Category:", count)) {
+                                       count += "[[Category:".length();
+                                       int startCount = count;
+
+                                       while(count < charArrayContent.length) {
+                                               count++;
+                                               if(charArrayContent[count] == ']') {
+                                                       if(content.startsWith("]]", count) == true) {
+                                                               int endCount   = count;
+                                                               
+                                                               String category = content.substring(startCount, endCount);
+                                                               categories.add(category);
+                                                               count += "]]".length();
+                                                               break;
+                                                       }
+                                               }
+                                       } 
+                               }
+                               else {
+                                       count++;
+                               }
+                       }
+                       else {
+                               count++;
+                       }
+               }
+               
+               return categories;
+       }
+
+       /**
+        * Categories抽出中の指定された要素{<pre>, <code>}をスキップする。
+        * @param content
+        * @param startElem
+        * @param endElem
+        * @return int
+        */
+       private int extractCategoriesSkipElem(String content, String startElem, String endElem) {
+               char[] charArrayContent = content.toCharArray();
+               int    count            = 0;
+
+               while(count < content.length()) {
+                       count++;
+                       if(charArrayContent[count] == '<') {
+                               String sub = content.substring(count);
+                               if(sub.startsWith(endElem) == true) {
+                                       count += endElem.length();
+                                       break;
+                               }
+                               else if(sub.startsWith(startElem) == true) {
+                                       count += extractCategoriesSkipElem(sub, startElem, endElem);
+                               }
+                       }
+               }
+               
+               return count;
+       }
+
+       /**
+        * File data structure.
+        */
+       public class FileData {
+               /** Node */
+               private Node node_ = null;
+               
+               /** Mime type */
+               private String mimeType_;
+
+               /** Data within the file.*/
+               private InputStream inputStream_;
+
+               /** Timestamp of the file. */
+               private Calendar lastModified_;
+
+               /** character encoding. */
+               private String encoding_;
+               
+               /**
+                * Constructor.
+                * @param file
+                * @throws Exception 
+                */
+               public FileData(File file) throws Exception {
+                       setInputStream(file);
+               }
+
+               /**
+                * Constructor.
+                * @param node
+                * @throws Exception 
+                */
+               public FileData(Node node) throws Exception {
+                       setNode(node);
+               }
+
+               /**
+                * Node getter.
+                * @return Node
+                */
+               public Node getNode() {
+                       return node_;
+               }
+
+               /**
+                * Node setter.
+                * @param node
+                * @throws Exception
+                */
+               public void setNode(Node node) throws Exception {
+                       node_ = node;
+                       setInputStream(node);
+               }
+               
+               /**
+                * inputstream getter.
+                * @return InputStream
+                */
+               public InputStream getInputStream() {
+                       return inputStream_;
+               }
+
+               /**
+                * Inputstream setter.
+                * @param file
+                * @throws Exception 
+                */
+               public void setInputStream(File file) throws Exception {
+                       inputStream_ = new FileInputStream(file);
+                       mimeType_  = URLConnection.guessContentTypeFromName(file.getAbsolutePath());
+
+                       lastModified_ = Calendar.getInstance();
+                       lastModified_.setTimeInMillis(file.lastModified());
+
+                       if(mimeType_.startsWith("text/") == true) {
+                               encoding_ = "UTF-8";
+                       }
+               }
+
+               /**
+                * Inputstream setter.
+                * @param file
+                * @throws Exception 
+                */
+               public void setInputStream(Node node) throws Exception {
+                       Node nodeResource = node.getNode(Property.JCR_CONTENT);
+
+                       inputStream_  = nodeResource.getProperty(Property.JCR_DATA).getBinary().getStream();
+                       mimeType_     = nodeResource.getProperty(Property.JCR_MIMETYPE).getString();
+                       lastModified_ = nodeResource.getProperty(Property.JCR_LAST_MODIFIED).getDate();
+
+                       if(mimeType_.startsWith("text/") == true) {
+                               encoding_ = nodeResource.getProperty(Property.JCR_ENCODING).getString();
+                       }
+               }
+
+               /**
+                * Mimetype getter.
+                * @return String
+                */
+               public String getMimeType() {
+                       return mimeType_;
+               }
+
+               /**
+                * Last modified getter. 
+                * @return Calendar
+                */
+               public Calendar getLastModified() {
+                       return lastModified_;
+               }
+       };
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/ResourceManager.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/ResourceManager.java
new file mode 100644 (file)
index 0000000..967f01b
--- /dev/null
@@ -0,0 +1,20 @@
+package com.wiki.standalone.moxkiriya;
+
+import java.util.LinkedHashMap;
+
+import com.wiki.standalone.moxkiriya.dialog.AlertDialog;
+
+import javafx.scene.image.Image;
+
+public class ResourceManager {
+       public static final LinkedHashMap<AlertDialog.DialogType, Image> IconTable
+       = new LinkedHashMap<AlertDialog.DialogType, Image>() {
+               private static final long serialVersionUID = 1L;
+       { put(AlertDialog.DialogType.Error,   new Image(getClass().getResource("resources/image/icon_error.png").toString())); }
+       { put(AlertDialog.DialogType.Alert,   new Image(getClass().getResource("resources/image/icon_alert.png").toString())); }
+       { put(AlertDialog.DialogType.Info,    new Image(getClass().getResource("resources/image/icon_info.jpg").toString())); }
+       { put(AlertDialog.DialogType.Confirm, new Image(getClass().getResource("resources/image/icon_confirm.png").toString())); }
+};
+
+
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/SettingManager.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/SettingManager.java
new file mode 100644 (file)
index 0000000..17bbeb1
--- /dev/null
@@ -0,0 +1,411 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Setting manager.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Set;
+
+import com.wiki.standalone.moxkiriya.util.FileIO;
+
+/**
+ * セッティングマネージャ
+ */
+public class SettingManager {
+       /** SETTINGSMAPKEY USER_HOME */
+       public static final String SETTINGSKEY_USER_HOME = "USER_HOME";
+
+       /** SETTINGSMAPKEY MOXKIRIYA_USER_DIR*/
+       public static final String SETTINGSKEY_MOXKIRIYA_USER_DIR = "MOXKIRIYA_USER_DIR";
+
+       /** SETTINGSMAPKEY MOXKIRIYAROOT */
+       public static final String SETINGKEY_MOXKIRIYAROOT = "moxkiriyaroot";
+       
+       /** SETTINGSMAPKEY WIKIROOT */
+       public static final String SETTINGSKEY_WIKIROOT = "wikiroot";
+
+       /** SETTINGSMAPKEY_CLUSTER */
+       public static final String SETINGKEY_CLUSTER = "clustersetting";
+       
+       /** SETTINGSMAPKEY_DBSERVERURL*/
+       public static final String SETINGKEY_DBSERVER_URL = "dbserverurl";
+       
+       /** SETTINGSMAPKEY_DBSERVERPORT*/
+       public static final String SETINGKEY_DBSERVER_PORT = "dbserverport";
+
+       /** SETTINGSMAPKEY_DBSERVERPORT*/
+       public static final String SETINGKEY_JDBC_DRIVER = "jdbcdriver";
+                       
+       /**/ 
+       private static final String MOXKIRIYA_USER_DIR = "_moxkiriya";
+       
+       /** 設定ファイル名 */
+       public static final String CONFIG_FILENAME = "_moxkiriya.config";
+       
+       /** Party設定ファイル名 */
+       private static final String PARTY_FILENAME = "_party.config";
+
+       private static SettingManager singleton_ = null;
+
+       /** party map */
+       private Hashtable<String, Boolean> partyTable_ = new Hashtable<String, Boolean>();
+
+       /** setting map */
+       private Hashtable<String, String> settingsTable_ = new Hashtable<String, String>();
+
+       /** fullpath map */
+       private Hashtable<String, String> fullpathTable_ = new Hashtable<String, String>();
+       
+       /** selected party */
+       private String selectedParty_ = null;
+       
+       /**
+        * コンストラクタ
+        */
+       private SettingManager() {
+       }
+
+       /**
+        * インスタンスを取得する。
+        */
+       public static SettingManager getInstance() {
+               try {
+                       if (singleton_ == null) {
+                               singleton_ = new SettingManager();
+                               singleton_.initializeSettingsMap();
+                       }
+               } catch (Exception e) {
+                       singleton_ = null;
+                       e.printStackTrace();
+               }
+               
+               return singleton_;
+       }
+       
+       /**
+        * 設定Mapを初期化する
+        * @throws Exception 
+        */
+       private void initializeSettingsMap() throws Exception {
+               String userHome         = System.getProperty("user.home");
+               File   moxkiriyaUserDir = new File(userHome + "/" + MOXKIRIYA_USER_DIR);
+
+               put(SETTINGSKEY_USER_HOME, userHome);
+               put(SETTINGSKEY_MOXKIRIYA_USER_DIR, moxkiriyaUserDir.getAbsolutePath());
+               if(moxkiriyaUserDir.exists() != true) {
+                       moxkiriyaUserDir.mkdirs();
+               }
+
+               loadPartyFile(moxkiriyaUserDir.getAbsolutePath());
+               if( (selectedParty_ != null)
+                && (selectedParty_.isEmpty() != true)) {
+                       loadSettingFiles(moxkiriyaUserDir.getAbsolutePath());                   
+               }
+       }
+
+       /**
+        * Party fileを読み込む。
+        * @param path
+        * @throws Exception 
+        */
+       private void loadPartyFile(String path) throws Exception {
+               File partyFile = new File(path + "/" + PARTY_FILENAME);
+
+               if(partyFile.exists() != true) {
+                       partyFile.createNewFile();
+               }
+               BufferedReader buffreader = FileIO.bufferedReader(partyFile);
+
+               String line = null;
+               while ((line = buffreader.readLine()) != null) {
+                       String[] list  = line.split("=", 2);
+                       String   key   = list[0].trim();
+                       String   value = list[1].trim();
+                       putParty(key, Boolean.valueOf(value));                  
+               }
+
+               Hashtable<String, Boolean> partyTable = getPartyTable();
+
+               if(partyTable.isEmpty() != true) {
+                       selectedParty_ = "";
+
+                       Set<String> keySet = partyTable.keySet();
+                       for(String key: keySet) {
+                               boolean value = partyTable.get(key);
+                               if(value == true) {
+                                       selectedParty_ = key;
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Configファイルを読み込む。
+        * @throws Exception 
+        * @parma path Configファイルのパス名
+        */
+       public void loadSettingFiles(String path) throws Exception {
+               String selectedParty = getSelectedParty();
+               
+               if( (selectedParty != null)
+                && (selectedParty.isEmpty() != true)) {
+                       settingsTable_ = loadConfigSettings(path, selectedParty);
+               }
+
+               String wikiroot          = get(SETTINGSKEY_WIKIROOT);
+               if(wikiroot != null) {
+                       String moxkiriya_userDir = get(SETTINGSKEY_MOXKIRIYA_USER_DIR);
+       
+                       fullpathTable_.put(WikiEngine.TEMPLATE_HTMLHEADER_FILE, moxkiriya_userDir + "/" + selectedParty);
+                       fullpathTable_.put(WikiEngine.USER_STYLESHEET_FILENAME, moxkiriya_userDir + "/" + selectedParty);
+                       fullpathTable_.put(WikiEngine.FIXED_STYLESHEET_FILENAME, wikiroot);
+                       fullpathTable_.put(WikiEngine.DEFAULT_STYLESHEET_FILENAME, wikiroot);
+                       fullpathTable_.put(WikiRepository.REPOSITORY_CUSTER_FILENAME, moxkiriya_userDir + "/" + selectedParty);
+                       fullpathTable_.put(WikiRepository.REPOSITORY_LOCAL_FILENAME, moxkiriya_userDir + "/" + selectedParty);
+       
+                       if(Boolean.valueOf(get(SETINGKEY_CLUSTER)) == true) {
+                               fullpathTable_.put(WikiRepository.REOPSITORY_DIRNAME, moxkiriya_userDir + "/" + selectedParty);
+                       }
+                       else {
+                               fullpathTable_.put(WikiRepository.REOPSITORY_DIRNAME, wikiroot);
+                       }
+               }
+       }
+
+       /**
+        * Load config settings of specified party name.
+        * @param partyName
+        * @throws Exception
+        */
+       public Hashtable<String, String> loadConfigSettings(String path, String partyName) throws Exception {
+               Hashtable<String, String> settingsTable    = new Hashtable<String, String>();
+               
+               File partyDir = new File(path + "/" + partyName);
+               if( (partyDir.exists() != true)
+                && (partyDir.isDirectory() != true)) {
+                       partyDir.mkdirs();
+               }
+
+               File inifile = new File(partyDir.getAbsolutePath()
+                                               + "/" + SettingManager.CONFIG_FILENAME);
+               if (inifile.exists() != true) {
+                       /* 
+                        * ファイルが存在しなかった場合、ファイルを新規作成
+                        */
+                       inifile.createNewFile();
+               }
+               
+               BufferedReader buffreader = FileIO.bufferedReader(inifile);
+
+               String userHome         = System.getProperty("user.home");
+               File   moxkiriyaUserDir = new File(userHome + "/" + MOXKIRIYA_USER_DIR);
+
+               settingsTable.put(SETTINGSKEY_USER_HOME, userHome);
+               settingsTable.put(SETTINGSKEY_MOXKIRIYA_USER_DIR, moxkiriyaUserDir.getAbsolutePath());
+
+               String line = null;
+               while ((line = buffreader.readLine()) != null) {
+                       String[] list = line.split("=", 2);
+
+                       if (list.length >= 2) {
+                               String   key   = list[0].trim();
+                               
+                               if (key.length() > 0) {
+                                       settingsTable.put(key, list[1].trim());
+                               }
+                       }
+               }
+               buffreader.close();
+               
+               return settingsTable;
+       }
+
+       /**
+        * Party table getter.
+        * @return Hashtable<String, Boolean>
+        */
+       public Hashtable<String, Boolean> getPartyTable() {
+               return partyTable_;
+       }
+       
+       /**
+        * Selected party getter.
+        * @return String
+        */
+       public String getSelectedParty() {
+               return selectedParty_;
+       }
+
+       /**
+        * Selected party setter.
+        * @return String
+        * @throws Exception 
+        */
+       public void setSelectedParty(String partyName) throws Exception {
+               selectedParty_ = partyName;
+
+               File moxkiriyaUserDir = new File(get(SETTINGSKEY_MOXKIRIYA_USER_DIR));
+               loadSettingFiles(moxkiriyaUserDir.getAbsolutePath());                                   
+       }
+
+       /**
+        * Party list getter.
+        * @return ArrayList<String>
+        */
+       public ArrayList<String> getPartyList() {
+               ArrayList<String> PartyList = new ArrayList<String>();          
+               Set<String>       keySet       = partyTable_.keySet();
+
+               for(String key: keySet) {
+                       PartyList.add(key);
+               }
+               
+               return PartyList;
+       }
+       
+       /**
+        * Put party.
+        * @param partyName
+        * @param isDefault
+        */
+       public void putParty(String partyName, boolean isDefault) {
+               if(partyName.isEmpty() != true) {
+                       if(isDefault == true) {
+                               Set<String> keySet = partyTable_.keySet();
+                               
+                               for(String key: keySet) {
+                                       partyTable_.put(key, false);
+                               }
+                       }
+                       partyTable_.put(partyName, isDefault);
+               }
+       }
+       
+       /**
+        * 設定情報を追加する。
+        * @param key 設定キー
+        * @parm val 設定値
+        */
+       public void put(String key, String val) {
+               settingsTable_.put(key, val);
+       }
+       
+       /**
+        * keyに該当する設定値を取得する。
+        * @param key
+        * @return
+        */
+       public String get(String key) {
+               return settingsTable_.get(key);
+       }
+       
+       /**
+        * 設定を保存する。
+        * @throws Exception 
+        */
+       public void save() throws Exception {
+               String path             = get(SETTINGSKEY_MOXKIRIYA_USER_DIR);
+               File   moxkiriyaHomeDir = new File(path);
+               
+               if( (moxkiriyaHomeDir.exists() != true)
+                || (moxkiriyaHomeDir.isDirectory() != true)) {
+                       moxkiriyaHomeDir.mkdirs();
+               }
+
+               /*
+                * save _party.config 
+                */
+               savePartyConfig(path);
+               
+               /*
+                * save _moxkiriya.config.
+                */
+               saveSettingConfig(path);
+
+               /*
+                * (Re)load _moxkiriya.config.
+                */
+               loadSettingFiles(path);
+       }
+
+       /**
+        * Translate the setting filename to the absolutepath.
+        * @param filename
+        * @return String
+        */
+       public String getAbsolutePath(String filename) {
+               String path = fullpathTable_.get(filename);
+               
+               return  path + "/" + filename;
+       }
+       
+       /**
+        * Save party configuration to file.
+        * @param path
+        * @throws Exception 
+        */
+       public void savePartyConfig(String path) throws Exception {
+               StringBuffer        stringBuf = new StringBuffer("");
+               Enumeration<String> keys      = partyTable_.keys();
+
+               while (keys.hasMoreElements() == true) {
+                       String  key   = keys.nextElement();
+                       boolean value = partyTable_.get(key);
+                       stringBuf.append(key + "=" + value + "\n");
+               }
+
+               File           inifile  = new File(path + "/" + PARTY_FILENAME);
+               BufferedWriter writer   = FileIO.bufferedWriter(inifile);
+
+               writer.write(stringBuf.toString());
+               writer.close();
+       }
+
+       /**
+        * Save setting configuration to file.
+        * @param path
+        * @throws Exception
+        */
+       public void saveSettingConfig(String path) throws Exception {
+               saveSettingConfig(path, selectedParty_, settingsTable_);
+       }
+
+       /**
+        * Save setting configuration to file.
+        * @param path
+        * @param partyName
+        * @param settingTable
+        * @throws Exception
+        */
+       public void saveSettingConfig(String path, String partyName, Hashtable<String, String> settingTable) throws Exception {
+               StringBuffer        stringBuf = new StringBuffer("");
+               Enumeration<String> keys      = settingTable.keys();
+
+               while (keys.hasMoreElements() == true) {
+                       String key   = keys.nextElement();
+                       String value = settingTable.get(key);
+                       stringBuf.append(key + "=" + value + "\n");
+               }
+               File partyDir = new File(path + "/" + partyName);
+               
+               if(partyDir.exists() != true) {
+                       partyDir.mkdirs();
+               }
+
+               File           inifile  = new File(partyDir.getAbsolutePath() + "/" + CONFIG_FILENAME);
+               BufferedWriter writer   = FileIO.bufferedWriter(inifile);
+
+               writer.write(stringBuf.toString());
+               writer.close();
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiEngine.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiEngine.java
new file mode 100644 (file)
index 0000000..c236e14
--- /dev/null
@@ -0,0 +1,587 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Wiki engine.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.ResourceBundle;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.Value;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionIterator;
+
+import com.wiki.standalone.moxkiriya.parser.blockparser.WikiBodyBlockParser;
+import com.wiki.standalone.moxkiriya.util.FileIO;
+
+/**
+ * Wiki engine.
+ *
+ */
+public class WikiEngine {
+       /** Wiki Root directory */
+       public static final String WIKIROOT_DIRECTORY = "wikiroot";
+
+       /** Main page directory */
+       public static final String MAINPAGE_TITLE = "MainPage";
+
+       /** template file HTML<head>section. */
+       public static final String TEMPLATE_HTMLHEADER_FILE = "templateHtmlHead.txt";
+
+       /** fixedstylesheetファイル名 */
+       public static final String FIXED_STYLESHEET_FILENAME = "fixedstylesheet.css";
+
+       /** user stylesheetファイル名 */
+       public static final String USER_STYLESHEET_FILENAME = "user.css";
+
+       /** defaultstylesheetファイル名 */
+       public static final String DEFAULT_STYLESHEET_FILENAME = "defaultstylesheet.css";
+
+
+       /** jcr_uuid 独自属性 */
+       public static final String ATTRIBUTE_JCR_UUID = "data-jcr_uuid";
+
+       /** namespace "Cagegory" */
+       public static final String NAMESPACE_CATEGORY = WikiRepository.PROPERTY_CATEGORY;
+
+       /** namespace "File" */
+       public static final String NAMESPACE_FILE = WikiRepository.PROPERTY_FILE;
+       
+       /** Wiki Repository. */
+       protected WikiRepository wikiRepository_;
+
+       /** Page data map. */
+       private HashMap<String, PageData> pageDataMap_ = null;
+
+       /** Wiki history manager. */
+       private WikiHistory wikiHistory_ = null;
+
+       /**
+        * Constructor.
+        */
+       public WikiEngine() {
+               wikiHistory_ = new WikiHistory();
+       }
+
+       /**
+        * Wiki repository getter.
+        * return wikiRepository
+        */
+       public WikiRepository getWikiRepository() {
+               return wikiRepository_;
+       }
+
+       /**
+        * Wiki repository setter.
+        * @param wikiRepository
+        */
+       public void setWikiRepository(WikiRepository wikiRepository) {
+               wikiRepository_ = wikiRepository;
+       }
+
+       /**
+        * 
+        * @param wikirootPath
+        * @param mainPageData
+        * @throws Exception 
+        */
+       public void buildWikiRepository(File wikirootPath) throws Exception {
+               wikiRepository_   = new WikiRepository(wikirootPath);
+
+               PageData mainPageData = new PageData();
+               mainPageData.setNamespace(WikiRepository.PROPERTY_MAIN);
+               mainPageData.setTitle(MAINPAGE_TITLE);
+
+               wikiRepository_.buildWikiRepository(mainPageData);              
+       }
+
+       /**
+        * PageData map setter.
+        * @param map
+        */
+       public void setPageDataMap(HashMap<String, PageData> map) {
+               pageDataMap_ = map;
+       }
+       
+       /**
+        * PageData map setter.
+        * @param pageData
+        * @throws Exception 
+        */
+       public void setPageDataMap(PageData pageData) throws Exception {
+               String uuid = pageData.getNode().getProperty(Property.JCR_UUID).getString();
+               pageDataMap_ = queryPageUUID(uuid);
+       }
+       
+       /**
+        * PageData map setter.
+        * @param pageData
+        * @throws Exception 
+        */
+       public void setPageDataMap(String title) throws Exception {
+               pageDataMap_ = queryPageTitle(title);
+       }
+
+       /**
+        * PageData map getter.
+        * return HashMap<String, PageData>
+        */
+       public HashMap<String, PageData> getPageDataMap() {
+               return pageDataMap_;
+       }
+
+       /**
+        * NamespaceList getter.
+        * @return ArrayList<String>
+        * @throws Exception
+        */
+       public ArrayList<String> getNamespaceList() throws Exception {
+               ArrayList<String> namespaceList = new ArrayList<String>();
+               Value[]           namespaces = wikiRepository_.getNamespaceList();
+
+               for(Value value: namespaces) {
+                       namespaceList.add(value.getString());
+               }
+
+               return namespaceList;
+       }
+
+       /**
+        * Checkout.
+        * @throws Exception 
+        */
+       public void checkout() throws Exception {
+               PageData currentPageData = null;
+
+               if(pageDataMap_.size() == 1) {
+                       currentPageData = pageDataMap_.values().iterator().next();
+               }
+               
+               if(currentPageData != null) {
+                       wikiRepository_.checkout(currentPageData);
+               }
+       }
+
+       /**
+        * Checkin.
+        * @throws Exception 
+        */
+       public PageData checkin(PageData pageData) throws Exception {
+               return wikiRepository_.checkin(pageData);
+       }
+       
+       /**
+        * Cancel checkout.
+        * @throws Exception 
+        */
+       public void cancelCheckout() throws Exception {
+               PageData currentPageData = null;
+
+               if(pageDataMap_.size() == 1) {
+                       currentPageData = pageDataMap_.values().iterator().next();
+               }
+               
+               if(currentPageData != null) {
+                       wikiRepository_.cancelCheckout(currentPageData);
+               }
+       }
+       
+       /**
+        * Wikiシンタックスの文字列をHTML形式に変換する。
+        * @return HTMLコンテンツ
+        * @throws Exception 
+        */
+       public String parse() throws Exception {
+               PageData pageData = null;
+               String   bodyHtml = "";
+
+               if(pageDataMap_.size() == 1) {
+                       pageData = pageDataMap_.values().iterator().next();
+                       wikiHistory_.add(pageData);
+                       bodyHtml = markupContents(pageData);
+               }
+               else {
+                       bodyHtml = markupContentsList();
+               }
+
+               /*
+                * Header部の構築
+                */
+               String         headerHtml = buildHtmlHeader();
+               StringBuffer   buf        = new StringBuffer();
+
+               buf.append(headerHtml);
+               buf.append(bodyHtml);
+               buf.append("</html>");
+
+               return buf.toString();
+       }
+
+       /**
+        * Wikiシンタックスの文字列をHTML形式に変換する。
+        * @param pageData
+        * @return HTMLコンテンツ
+        * @throws Exception 
+        */
+       public String parse(PageData pageData) throws Exception {
+               String bodyHtml = markupContents(pageData);
+
+               /*
+                * Header部の構築
+                */
+               String         headerHtml = buildHtmlHeader();
+               StringBuffer   buf        = new StringBuffer();
+
+               buf.append(headerHtml);
+               buf.append(bodyHtml);
+               buf.append("</html>");
+
+               return buf.toString();
+       }
+
+       /**
+        * Wikiシンタックスの文字列をHTML形式に変換する。
+        * @return HTMLコンテンツ
+        * @throws Exception 
+        */
+       public String markupContents(PageData pageData) throws Exception {
+               WikiBodyBlockParser bodyBlockParser = new WikiBodyBlockParser(this);
+               String              bodyHtml        = "";
+
+               /*
+                * Contentsのparse & Body部の構築.
+                */
+               bodyBlockParser.parsePageTitle(pageData.getTitle());
+               BufferedReader buffreader = FileIO.bufferedReader(new StringReader(pageData.getContent()));
+
+               bodyHtml = bodyBlockParser.parse(buffreader)
+                               + buildCategoryList(pageData);
+
+               buffreader.close();
+
+               return bodyHtml;
+       }
+
+       /**
+        * PageリストをHTML形式で生成する。
+        * @return HTMLコンテンツ
+        * @throws Exception 
+        */
+       public String markupContentsList() throws Exception {
+               StringBuffer   bodybuf = new StringBuffer();
+               ResourceBundle resources_ = ResourceBundle.getBundle("com.wiki.standalone.moxkiriya.resources.moxkiriya");
+
+               bodybuf.append("<h1>" + resources_.getString("key.Search.Result") + "</h1>\n");
+               if(pageDataMap_.size() > 1) {
+                       bodybuf.append("<div>\n");
+                       bodybuf.append(resources_.getString("key.Message.found.pages") + "\n");
+                       bodybuf.append("</div>\n");
+       
+                       for(String uuid: pageDataMap_.keySet()) {
+                               PageData pageData = pageDataMap_.get(uuid);
+                               
+                               bodybuf.append("<h3>\n");
+                               bodybuf.append("<a href="
+                                               + "\"" + pageData.getTitle() + "\" "
+                                               + ATTRIBUTE_JCR_UUID + "="
+                                               + pageData.getNode().getProperty(Property.JCR_UUID).getString()
+                                               + ">");
+                               bodybuf.append(pageData.getTitle());
+                               bodybuf.append("</a>\n");
+                               bodybuf.append("</h3>\n");
+                               bodybuf.append("<div>\n");
+                               bodybuf.append(pageData.getIntroduction());
+                               bodybuf.append("</div>\n");
+                       }
+               }
+               else {
+                       /*
+                        * No page was found.
+                        */
+                       bodybuf.append("<div>\n");
+                       bodybuf.append(resources_.getString("key.search.result.message.nopage") + "\n");
+                       bodybuf.append("</div>\n");                             
+               }
+               
+               return bodybuf.toString();
+       }
+       
+       /**
+        * HTMLヘッダ部を構築する。
+        * @return HTMLヘッダ部
+        * @throws IOException
+        */
+       public static String buildHtmlHeader() throws IOException {
+               StringBuffer   stringBuf      = new StringBuffer();
+               SettingManager settingMgr     = SettingManager.getInstance();
+               File           headerTemplate = new File(settingMgr.getAbsolutePath(TEMPLATE_HTMLHEADER_FILE));
+               InputStream  in        = new FileInputStream(headerTemplate);
+               byte         byteBuf[] = new byte[255];
+               int          size;
+
+               while((size = in.read(byteBuf)) != -1) {
+                       stringBuf.append(new String(byteBuf, 0, size));
+               }
+               in.close();
+               File           stylesheetFile;
+
+               stylesheetFile = new File(settingMgr.getAbsolutePath(DEFAULT_STYLESHEET_FILENAME));             
+               stringBuf.append("\t<link rel=\"stylesheet\" type=\"text/css\" href=\""
+                               + stylesheetFile.toURI().toString()
+                               + "\">\n");
+               
+               stylesheetFile = new File(settingMgr.getAbsolutePath(USER_STYLESHEET_FILENAME));                
+               stringBuf.append("\t<link rel=\"stylesheet\" type=\"text/css\" href=\""
+                                               + stylesheetFile.toURI().toString()
+                                               + "\">\n");
+
+               stylesheetFile = new File(settingMgr.getAbsolutePath(FIXED_STYLESHEET_FILENAME));
+               stringBuf.append("\t<link rel=\"stylesheet\" type=\"text/css\" href=\""
+                                       + stylesheetFile.toURI().toString()
+                                       + "\">\n");
+
+               stringBuf.append("<script>\n"
+                                       + "function scrollTo(elementId) {\n"
+                                       + "\tdocument.getElementById(elementId).scrollIntoView()\n"
+                                       + "}\n"
+                                       + "</script>");
+               
+               stringBuf.append("</head>\n");
+               
+               return stringBuf.toString();
+       }
+
+       private String buildCategoryList(PageData pageData) throws Exception {
+               StringBuffer      buf = new StringBuffer("");
+               ArrayList<String> categoryies = pageData.getCategories();
+
+               for(String category: categoryies) {
+                       if(category.isEmpty() != true) {
+                               HashMap<String, PageData> categoryPageMap = queryPageTitle(category, NAMESPACE_CATEGORY);
+                               
+                               if(categoryPageMap.size() == 1) {
+                                       PageData categoryPage = categoryPageMap.values().iterator().next();
+                                       Node     node         = categoryPage.getNode();
+                                       
+                                       buf.append("<a href=" + "\"" + category + "\" ");
+                                       buf.append(ATTRIBUTE_JCR_UUID + "=\"");
+                                       buf.append(node.getProperty(Property.JCR_UUID).getString());
+                                       buf.append("\">");
+                                       buf.append(category);
+                                       buf.append("</a> ");
+                               }
+                       }
+               }
+               
+               String startElem = "";
+               String endElem   = "";
+               
+               if(buf.length() > 0) {
+                       startElem = "<div class=\"categorylist\"> Categories: \n";
+                       endElem   = "</div>";
+               }
+               
+               return startElem + buf.toString() + endElem;                            
+       }
+       
+       
+       /**
+        * Execute query node by namespace.
+        * @param namespace
+        * @return HashMap<String, PageData>
+        * @throws Exception
+        */
+       public HashMap<String, PageData> queryPageNamespace(String namespace) throws Exception {
+               return wikiRepository_.queryPageNamespace(namespace);
+       }
+
+       /**
+        * Execute query node by UUID.
+        * @param uuid
+        * @return HashMap<String, PageData>
+        * @throws Exception
+        */
+       public HashMap<String, PageData> queryPageUUID(String uuid) throws Exception {
+               return wikiRepository_.queryPageUUID(uuid);
+       }
+
+       /**
+        * Execute query node by pageTitle.
+        * @param pageTitle
+        * @param namespace
+        * @return HashMap<String, PageData>
+        * @throws Exception
+        */
+       public HashMap<String, PageData> queryPageTitle(String pageTitle, String namespace) throws Exception {
+               return wikiRepository_.queryPageTitle(pageTitle, namespace);
+       }
+
+       /**
+        * Execute query node by pageTitle.
+        * @param pageTitle
+        * @return HashMap<String, PageData>
+        * @throws Exception
+        */
+       public HashMap<String, PageData> queryPageTitle(String pageTitle) throws Exception {
+               return wikiRepository_.queryPageTitle(pageTitle);
+       }
+
+       /**
+        * Execute query full text search.
+        * @param searchKey
+        * @return HashMap<String, PageData>
+        * @throws Exception
+        */
+       public HashMap<String, PageData> queryPageFullTextSearch(String searchKey) throws Exception {
+               return wikiRepository_.queryPageFullTextSearch(searchKey);
+       }
+
+       /**
+        * Test namespace is contains namespaceList.
+        * @param namespace
+        * @return boolean
+        * @throws Exception
+        */
+       public boolean isContainsNamespaceList(String namespace) throws Exception {
+               return wikiRepository_.isContainsNamespaceList(namespace);
+       }
+
+       /**
+        * Delete page node.
+        * @param pagedata
+        * @throws Exception 
+        */
+       public void deletePage(PageData pagedata) throws Exception {
+               wikiRepository_.deletePage(pagedata);
+       }
+       
+       /**
+        * Refresh session.
+        * @throws Exception 
+        */
+       public void refreshSession() throws Exception {
+               wikiRepository_.refreshSession();
+               if(pageDataMap_ != null) {
+                       if(pageDataMap_.size() == 1) {
+                               PageData pageData = pageDataMap_.values().iterator().next();
+                               String   uuid     = pageData.getNode().getProperty(Property.JCR_UUID).getString();
+                               
+                               pageDataMap_ = wikiRepository_.queryPageUUID(uuid);
+                       }
+               }
+       }
+
+       /**
+        * Is there an older node on a history list.
+        * @return boolean
+        */
+       public boolean canBack() {
+               return wikiHistory_.canBack();
+       }
+
+       /**
+        * Is there an newer node on a history list.
+        * @return boolean
+        */
+       public boolean canForward() {
+               return wikiHistory_.canForward();
+       } 
+
+       /**
+        * Execute history back.
+        * @throws Exception 
+        */
+       public String back() throws Exception {
+               PageData pageData = wikiHistory_.back();
+               setPageDataMap(pageData);
+               return parse(pageData);
+       }
+
+       /**
+        * Execute history forward.
+        * @return PageData
+        * @throws Exception 
+        */
+       public String forward() throws Exception {
+               PageData pageData = wikiHistory_.forward();
+               setPageDataMap(pageData);
+               return parse(pageData);
+       }
+
+       /**
+        * History clear.
+        */
+       public void clearHistory() {
+               wikiHistory_.clear();
+       }
+       
+       /**
+        * VersionHistory getter.
+        * @return VersionIterator
+        * @throws Exception 
+        */
+       public VersionIterator getVersionHistory() throws Exception {
+               PageData pageData = pageDataMap_.values().iterator().next();
+               String   uuid     = pageData.getNode().getProperty(Property.JCR_UUID).getString();
+
+               return wikiRepository_.getVersionHistory(uuid);
+       }
+
+       /**
+        * Base version getter.
+        * @return Version
+        * @throws Exception
+        */
+       public Version getBaseVersion() throws Exception {
+               PageData pageData = pageDataMap_.values().iterator().next();
+
+               return wikiRepository_.getBaseVersion(pageData.getNode());
+       }
+       
+       /**
+        * Restore version.
+        * @param version
+        * @throws Exception 
+        */
+       public void restoreVersion(Version version) throws Exception {
+               PageData pageData = pageDataMap_.values().iterator().next();
+               wikiRepository_.restoreVersion(version, pageData.getNode());
+       }
+
+       /**
+        * Import system vies.
+        * @param outputFile
+        * @throws Exception
+        */
+       public void importSystemView(File outputFile) throws Exception {
+               wikiRepository_.importSystemView(outputFile);
+       }
+       
+       /**
+        * Export system view.
+        * @param outputFile
+        * @throws Exception 
+        */
+       public void exportSystemView(File outputFile) throws Exception {
+               wikiRepository_.exportSystemView(outputFile);
+       }
+       
+       /**
+        * Session closer.
+        */
+       public void closeSession() {
+               wikiRepository_.closeSession();
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiHistory.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiHistory.java
new file mode 100644 (file)
index 0000000..7b4ccca
--- /dev/null
@@ -0,0 +1,131 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * WikiHistory.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya;
+
+import java.util.ArrayList;
+
+import javax.jcr.Property;
+
+/**
+ * Manage wiki history.
+ * 
+ *
+ */
+public class WikiHistory {
+       /** History list*/
+       private ArrayList<PageData> histories_ = new ArrayList<PageData>();
+
+       /** Position on history list. */
+       private int position_ = 0;
+       
+       /**
+        * Constructor.
+        */
+       public WikiHistory() {
+               histories_.clear();
+       }
+
+       /**
+        * Is there an older node on a history list.
+        * @return boolean
+        */
+       public boolean canBack() {
+               boolean canBack = false;
+               
+               if(histories_.size() > 1) {
+                       if(position_ > 0) {
+                               canBack = true;
+                       }
+               }
+               
+               return canBack;
+       }
+
+       /**
+        * Is there an newer node on a history list.
+        * @return boolean
+        */
+       public boolean canForward() {
+               boolean canForward = false;
+               
+               if(histories_.size() > 0) {
+                       if(position_ < histories_.size() - 1) {
+                               canForward = true;
+                       }
+               }
+               
+               return canForward;
+       }
+
+       /**
+        * Execute history back.
+        * @return PageData
+        */
+       public PageData back() {
+               PageData pageData = null;
+
+               if(canBack() == true) {
+                       position_--;
+                       pageData = histories_.get(position_);
+               }
+               
+               return pageData;
+       }
+
+       /**
+        * Execute history forward.
+        * @return PageData
+        */
+       public PageData forward() {
+               PageData pageData = null;
+               
+               if(canForward() == true) {
+                       position_++;
+                       pageData = histories_.get(position_);
+               }
+               
+               return pageData;
+       }
+
+       /**
+        * Add PageData to history list.
+        * @param pageData
+        * @throws Exception
+        */
+       public void add(PageData pageData) throws Exception {
+               if(histories_.size() > 0) {
+                       PageData latestPage = histories_.get(position_);
+                       String   uuid       = latestPage.getNode().getProperty(Property.JCR_UUID).getString();
+
+                       if(pageData.getNode().getProperty(Property.JCR_UUID).getString().equals(uuid) == true) {
+                               /*
+                                * History中に同じページを連続登録しようとした場合、
+                                */
+                               histories_.remove(position_);
+                       }
+                       else {
+                               position_++;                            
+                       }
+               }
+               
+               for(int count = position_; count < histories_.size(); count++) {
+                       histories_.remove(count);
+               }
+               
+               histories_.add(pageData);
+               position_ = histories_.size() - 1;
+       }
+
+       /**
+        * Clear history.
+        */
+       public void clear() {
+               histories_.clear();
+               position_ = 0;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiMainWindow.fxml b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiMainWindow.fxml
new file mode 100644 (file)
index 0000000..6f62f1e
--- /dev/null
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import java.net.*?>
+<?import javafx.collections.*?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.image.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.layout.AnchorPane?>
+<?import javafx.scene.text.*?>
+<?import javafx.scene.web.*?>
+<?scenebuilder-preview-i18n-resource resources/moxkiriya.properties?>
+
+<AnchorPane id="rootAnchorPane" fx:id="topAnchorPain" maxHeight="-1.0" maxWidth="-1.0" mouseTransparent="false" prefHeight="680.0" prefWidth="1024.0" snapToPixel="true" style="" styleClass="rootAnchorPane" visible="true" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.wiki.standalone.moxkiriya.WikiMainWindowController">
+  <children>
+    <MenuBar fx:id="menuBar" maxHeight="-Infinity" maxWidth="-1.0" minHeight="-1.0" minWidth="-1.0" prefHeight="30.0" prefWidth="640.0" visible="true" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+      <menus>
+        <Menu mnemonicParsing="false" text="%key.Menu.File">
+          <items>
+            <MenuItem mnemonicParsing="false" onAction="#onActionMenuItemNew" text="%key.MenuItem.New" fx:id="menuItemNew" />
+            <MenuItem mnemonicParsing="false" onAction="#onActionMenuItemImport" text="%key.MenuItem.Import" fx:id="menuItemImport" />
+            <MenuItem mnemonicParsing="false" onAction="#onActionMenuItemExport" text="%key.MenuItem.Export" fx:id="menuItemExport" />
+            <MenuItem mnemonicParsing="false" onAction="#onActionMenuItemExit" text="%key.MenuItem.Exit" fx:id="menuItemExit" />
+          </items>
+        </Menu>
+        <Menu mnemonicParsing="false" text="%key.Menu.Edit">
+          <items>
+            <MenuItem disable="false" mnemonicParsing="false" onAction="#onActionMenuItemSelectParty" text="%key.MenuItem.Select.Party" fx:id="menuItemSelectParty" />
+          </items>
+        </Menu>
+        <Menu mnemonicParsing="false" text="%key.Menu.Help">
+          <items>
+            <MenuItem mnemonicParsing="false" onAction="#onActionMenuItemAboutMoxkiriya" text="%key.MenuItem.About.Moxkiriya" fx:id="menuItemAboutMoxkiriya" />
+          </items>
+        </Menu>
+      </menus>
+    </MenuBar>
+    <AnchorPane fx:id="sideMenuAnchorPane" prefHeight="736.0" prefWidth="180.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="30.0" />
+    <AnchorPane fx:id="choiceViewAnchorPane" prefHeight="45.0" prefWidth="1010.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="30.0">
+      <children>
+        <Hyperlink fx:id="choiceViewHyperlinkReading" onMouseClicked="#onMouseClickedHyperlinkReading" prefHeight="30.0" text="%key.Hyperlink.Reading" underline="true" AnchorPane.rightAnchor="310.0" AnchorPane.topAnchor="10.0" />
+        <Hyperlink fx:id="choiceViewHyperlinkPageList" onMouseClicked="#onMouseClickedHyperlinkPageList" prefHeight="30.0" text="%key.Hyperlink.Pagelist" underline="true" AnchorPane.rightAnchor="220.0" AnchorPane.topAnchor="10.0" />
+        <Hyperlink id="hyperlink_webViewEdit" fx:id="choiceViewHyperlinkEdit" alignment="CENTER" onMouseClicked="#onMouseClickedHyperlinkEdit" prefHeight="30.0" prefWidth="80.0" text="%key.Hyperlink.Edit" underline="true" AnchorPane.rightAnchor="130.0" AnchorPane.topAnchor="10.0" />
+      </children>
+    </AnchorPane>
+    <AnchorPane id="AnchorPane" fx:id="AnchorPaneWebView" prefHeight="380.0" prefWidth="590.0" visible="true" AnchorPane.bottomAnchor="65.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="80.0">
+      <children>
+        <AnchorPane fx:id="webViewMenuAnchorPane" prefHeight="45.0" prefWidth="590.0" style="" styleClass="webViewMenuAnchorPane" visible="true" AnchorPane.leftAnchor="180.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+          <children>
+            <Button id="webViewMenuAn" fx:id="webViewMenuAnchorPaneButtonBack" disable="true" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" onAction="#onActionButtonBack" prefHeight="35.0" prefWidth="45.0" style="" text="⇦" AnchorPane.leftAnchor="5.0" AnchorPane.topAnchor="2.0">
+              <font>
+                <Font size="17.0" fx:id="x1" />
+              </font>
+            </Button>
+            <Button fx:id="webViewMenuAnchorPaneButtonForward" disable="true" font="$x1" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" onAction="#onActionButtonForward" prefHeight="35.0" prefWidth="45.0" text="⇨" AnchorPane.leftAnchor="55.0" AnchorPane.topAnchor="2.0" />
+            <Button fx:id="webViewMenuAnchorPaneButtonReload" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" onAction="#onActionButtonReload" prefHeight="35.0" prefWidth="70.0" text=" 🔃" AnchorPane.leftAnchor="105.0" AnchorPane.topAnchor="2.0">
+              <font>
+                <Font size="12.0" fx:id="x3" />
+              </font>
+            </Button>
+            <Button fx:id="webViewMenuAnchorPaneButtonHome" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" onAction="#onActionButtonHome" prefHeight="30.0" prefWidth="45.0" text="⌂" AnchorPane.leftAnchor="180.0" AnchorPane.topAnchor="2.0">
+              <font>
+                <Font size="20.0" fx:id="x2" />
+              </font>
+            </Button>
+            <TextField id="TextFieldSearchWiki" fx:id="webViewMenuAnchorPaneTextFieldSearchWiki" maxHeight="-Infinity" maxWidth="-Infinity" onKeyPressed="#onKeyPressedTextFieldSearchWiki" prefHeight="35.0" prefWidth="256.0" promptText="%key.TextField.Search_Wiki" AnchorPane.rightAnchor="85.0" AnchorPane.topAnchor="2.0" />
+            <Button id="ButtonSearch" fx:id="webViewMenuAnchorPaneButtonSearch" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" onAction="#onActionButtonSearch" prefHeight="35.0" prefWidth="80.0" text="%key.Button.Search" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
+          </children>
+          <padding>
+            <Insets right="2.0" top="2.0" />
+          </padding>
+          <stylesheets>
+            <URL value="@application.css" />
+          </stylesheets>
+        </AnchorPane>
+        <Hyperlink id="hyperlinkMain" fx:id="webViewHyperlinkMain" alignment="CENTER" onMouseClicked="#onMouseClickedWebViewHyperlinkMain" prefHeight="30.0" prefWidth="100.0" style="" text="%key.Hyperlink.Main" textAlignment="CENTER" textOverrun="ELLIPSIS" AnchorPane.leftAnchor="180.0" AnchorPane.topAnchor="55.0">
+          <stylesheets>
+            <URL value="@application.css" />
+          </stylesheets>
+        </Hyperlink>
+        <AnchorPane id="webViewMainAnchorPane" fx:id="webViewAnchorPaneMain" prefHeight="453.0" prefWidth="792.0" style="" styleClass="webViewMainAnchorPane" visible="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="180.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="85.0">
+          <children>
+            <HBox alignment="CENTER" prefHeight="200.0" prefWidth="200.0" style="" visible="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
+              <children>
+                <ImageView fx:id="ImageViewLoading" fitHeight="80.0" fitWidth="80.0" opacity="1.0" pickOnBounds="true" preserveRatio="true" style="-fx-background-color: transparent;" visible="true">
+                  <image>
+                    <Image url="@resources/image/image_processing.gif" />
+                  </image>
+                </ImageView>
+              </children>
+            </HBox>
+            <WebView fx:id="webView" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;" visible="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
+              <!-- 
+              <stylesheets>
+                <URL value="@application.css" />
+              </stylesheets>
+              -->
+            </WebView>
+          </children>
+          <stylesheets>
+            <URL value="@application.css" />
+          </stylesheets>
+        </AnchorPane>
+        <AnchorPane id="webViewHistoryAnchorPane" fx:id="webViewAnchorPaneHistory" prefHeight="528.0" prefWidth="843.0" style="" styleClass="webViewMainAnchorPane" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="180.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="85.0">
+          <children>
+            <AnchorPane fx:id="webViewHistoryBreadcrumbs" prefHeight="35.0" prefWidth="200.0" visible="true" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="5.0">
+              <children>
+                <FlowPane fx:id="webViewHistoryBreadcrumbsPane" prefHeight="40.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+                  <padding>
+                    <Insets left="10.0" />
+                  </padding>
+                </FlowPane>
+              </children>
+              <stylesheets>
+                <URL value="@application.css" />
+              </stylesheets>
+            </AnchorPane>
+            <ListView fx:id="webViewHistoryListView" prefHeight="200.0" prefWidth="200.0" visible="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="40.0" />
+            <AnchorPane fx:id="webViewHistoryAnchorPaneContent" prefHeight="200.0" prefWidth="200.0" styleClass="webViewHistoryContentAnchorPane" visible="false" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="40.0">
+              <children>
+                <Label font="$x3" prefHeight="30.0" text="%key.History.Content.Title" AnchorPane.leftAnchor="30.0" AnchorPane.topAnchor="10.0" />
+                <TextField fx:id="webViewHistoryTextFieldTitle" alignment="CENTER_LEFT" editable="false" focusTraversable="false" prefHeight="30.0" prefWidth="200.0" AnchorPane.leftAnchor="30.0" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="40.0" />
+                <Label prefHeight="30.0" text="%key.Edit.Label.Contents" AnchorPane.leftAnchor="30.0" AnchorPane.topAnchor="90.0" />
+                <TextArea fx:id="webViewHistorytextAreaContents" editable="false" focusTraversable="false" prefWidth="200.0" wrapText="true" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="30.0" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="120.0" />
+                <Button fx:id="webViewHistoryButtonRestoreVersion" maxHeight="-Infinity" mnemonicParsing="false" onAction="#onActionButtonRestoreVersion" prefHeight="30.0" text="%key.Button.Restore.Version" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="30.0" />
+              </children>
+              <stylesheets>
+                <URL value="@application.css" />
+              </stylesheets>
+            </AnchorPane>
+          </children>
+          <padding>
+            <Insets />
+          </padding>
+          <stylesheets>
+            <URL value="@application.css" />
+          </stylesheets>
+        </AnchorPane>
+        <Hyperlink fx:id="webViewHyperlinkHistory" alignment="CENTER" maxWidth="-1.0" onMouseClicked="#onMouseClickedWebViewHyperlinkHistory" prefHeight="30.0" prefWidth="100.0" style="" text="%key.Hyperlink.History" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="55.0">
+          <stylesheets>
+            <URL value="@application.css" />
+          </stylesheets>
+        </Hyperlink>
+        <Label prefHeight="29.999900000002526" prefWidth="594.0" styleClass="webViewGapspace" text="" AnchorPane.leftAnchor="280.0" AnchorPane.rightAnchor="100.0" AnchorPane.topAnchor="55.0">
+          <stylesheets>
+            <URL value="@application.css" />
+          </stylesheets>
+        </Label>
+      </children>
+    </AnchorPane>
+    <AnchorPane fx:id="AnchorPaneContentList" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="535.0" prefWidth="590.0" visible="false" AnchorPane.bottomAnchor="70.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="73.0">
+      <children>
+        <Label maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="30.0" prefWidth="100.0" text="%key.PageList.Label.Namespace" AnchorPane.leftAnchor="150.0" AnchorPane.topAnchor="80.0" />
+        <ComboBox fx:id="comboBoxNamespace" prefHeight="25.0" prefWidth="150.0" AnchorPane.leftAnchor="250.0" AnchorPane.topAnchor="82.0">
+          <items>
+            <FXCollections fx:factory="observableArrayList">
+              <String fx:value="アイテム1" />
+              <String fx:value="アイテム2" />
+              <String fx:value="アイテム3" />
+            </FXCollections>
+          </items>
+        </ComboBox>
+        <Hyperlink fx:id="hyperlinkRedraw" onMouseClicked="#onMouseClickedHyperlinkRedraw" prefHeight="30.0" prefWidth="-1.0" text="%key.PageList.Label.Redraw" AnchorPane.leftAnchor="410.0" AnchorPane.topAnchor="80.0" />
+        <TableView id="TableViewContentList" fx:id="tableViewContentList" editable="true" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="400.0" prefWidth="825.0" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="150.0" AnchorPane.topAnchor="110.0">
+          <columns>
+            <TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="45.0" text="" fx:id="tableColumnCheck" />
+            <TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="190.0" text="%key.Table.Row.Title" fx:id="tableColumnTitle" />
+            <TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="340.0" text="%key.Table.Row.Content" fx:id="tableColumnContent" />
+            <TableColumn prefWidth="200.0" text="%key.Table.Row.Date" fx:id="tableColumnDate" />
+            <TableColumn prefWidth="50.0" text="%key.Table.Row.Refs" fx:id="tableColumnRefs" />
+          </columns>
+        </TableView>
+        <Button fx:id="buttonDeletePages" mnemonicParsing="false" onAction="#onActionButtonDeletePages" prefHeight="30.0" text="%key.Button.Delete.Pages" AnchorPane.bottomAnchor="15.0" AnchorPane.leftAnchor="150.0" />
+      </children>
+    </AnchorPane>
+    <AnchorPane id="EditAnchorPane" fx:id="AnchorPaneEdit" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="450.0" prefWidth="590.0" visible="false" AnchorPane.bottomAnchor="60.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="75.0">
+      <children>
+        <Label prefHeight="30.0" text="%key.Edit.Label.Title" AnchorPane.leftAnchor="150.0" AnchorPane.topAnchor="15.0" />
+        <TextField fx:id="textFieldTitle" prefHeight="30.0" prefWidth="380.0" AnchorPane.leftAnchor="150.0" AnchorPane.rightAnchor="9.0" AnchorPane.topAnchor="45.0" />
+        <Label maxWidth="-Infinity" prefHeight="30.0" text="%key.Edit.Label.Contents" AnchorPane.leftAnchor="150.0" AnchorPane.topAnchor="80.0" />
+        <TextArea fx:id="textAreaContents" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="330.0" prefWidth="815.0" visible="true" wrapText="true" AnchorPane.bottomAnchor="98.0" AnchorPane.leftAnchor="150.0" AnchorPane.rightAnchor="9.0" AnchorPane.topAnchor="110.0" />
+        <Button fx:id="buttonSave" mnemonicParsing="false" onAction="#onActionButtonSave" prefHeight="30.0" prefWidth="100.0" text="%key.Button.Save" AnchorPane.bottomAnchor="5.0" AnchorPane.rightAnchor="120.0" />
+        <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#onActionButtonCancel" prefHeight="30.0" prefWidth="100.0" text="%key.Button.Cancel" AnchorPane.bottomAnchor="5.0" AnchorPane.rightAnchor="10.0" />
+        <Label id="textLabelAttacheFile" fx:id="labelAttacheFile" disable="true" prefHeight="30.0" prefWidth="166.0" text="%key.Edit.Label.AttachFile" AnchorPane.bottomAnchor="70.0" AnchorPane.leftAnchor="150.0" AnchorPane.rightAnchor="60.0" />
+        <TextField fx:id="textFieldAttachFile" disable="true" prefHeight="30.0" prefWidth="716.0" promptText="%key.Edit.TextField.InputPathname" AnchorPane.bottomAnchor="42.0" AnchorPane.leftAnchor="150.0" AnchorPane.rightAnchor="60.0" />
+        <Button fx:id="buttonChoiceFile" disable="true" mnemonicParsing="false" onAction="#onActionButtonChoiceFile" prefHeight="30.0" prefWidth="45.0" text="..." AnchorPane.bottomAnchor="42.0" AnchorPane.rightAnchor="10.0" />
+        <Button fx:id="buttonPreview" mnemonicParsing="false" onAction="#onActionButtonPreview" prefHeight="30.0" prefWidth="100.0" text="%key.Button.Preview" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="150.0" />
+      </children>
+    </AnchorPane>
+  </children>
+  <stylesheets>
+    <URL value="@application.css" />
+  </stylesheets>
+</AnchorPane>
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiMainWindow.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiMainWindow.java
new file mode 100644 (file)
index 0000000..bf02522
--- /dev/null
@@ -0,0 +1,196 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Wiki main window.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+
+package com.wiki.standalone.moxkiriya;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ResourceBundle;
+
+import com.wiki.standalone.moxkiriya.util.FileIO;
+
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+
+/**
+ * Application Main.
+ * 
+ *
+ */
+public class WikiMainWindow {
+       /** primary stage. */
+       private Stage primaryStage_ = null;
+
+       /** Resource Bundle */
+       private ResourceBundle resources_ = null;
+
+       /** Setting Manager */
+       private SettingManager settingManager_ = null;
+
+       /** WikiEngine */
+       private WikiEngine wikiEngine_;
+       
+       /** Window Controller */
+       private WikiMainWindowController controller_;
+
+       public enum CloseType {
+               EXIT,
+               RESTART
+       };
+       
+       /**
+        * Constructor.
+        */
+       public WikiMainWindow(Stage primaryStage, ResourceBundle resources) {
+               primaryStage_   = primaryStage;
+               resources_      = resources;
+               settingManager_ = SettingManager.getInstance();
+       }
+
+       /**
+        * Show WikiMainWindow
+        * @throws Exception
+        */
+       public CloseType show() throws Exception {
+               try {
+                       FXMLLoader loader = new FXMLLoader(getClass().getResource("WikiMainWindow.fxml"), resources_);
+                       loader.load();
+
+                       controller_ = loader.getController();
+                       controller_.setWikiEngine(wikiEngine_);
+
+                       Scene scene  = new Scene((Parent)loader.getRoot());
+                       scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
+
+                       wikiEngine_.setPageDataMap(WikiEngine.MAINPAGE_TITLE);
+                       controller_.loadWikiContent();
+
+                       Stage stage  = new Stage(StageStyle.DECORATED);
+                       stage.initOwner(primaryStage_);
+                       controller_.setStage(stage);
+
+                       stage.setScene(scene);
+                       stage.setTitle(resources_.getString("key.Application.Title"));
+                       stage.showAndWait();
+
+                       controller_.hidePreviewWindow();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+               
+               return controller_.getCloseType();
+       }
+       /**
+        * Wikiのメインページのディレクトリツリーを構築する。
+        * @param wikirootPath
+        * @throws Exception 
+        */
+       public void buildWikiMainTree(File wikirootPath) throws Exception {
+               createCssFiles();
+
+               uploadResourcefile(settingManager_.getAbsolutePath(WikiEngine.FIXED_STYLESHEET_FILENAME),
+                               WikiEngine.FIXED_STYLESHEET_FILENAME);
+
+               uploadResourcefile(settingManager_.getAbsolutePath(WikiEngine.DEFAULT_STYLESHEET_FILENAME),
+                               WikiEngine.DEFAULT_STYLESHEET_FILENAME);
+
+               createRepositoryConfig();
+               wikiEngine_ = new WikiEngine();
+               wikiEngine_.buildWikiRepository(wikirootPath);
+       }
+       
+       /**
+        * styleシートをコピーする
+        * @param absolutePath
+        * @param filename
+        * @throws IOException 
+        */
+       public void uploadResourcefile(String absolutePath, String filename) throws IOException {
+               File destFile   = new File(absolutePath);
+
+               if (destFile.exists() != true) {
+                       InputStream in       = getClass().getResourceAsStream("resources/" + filename);
+                       Path        destPath = Paths.get(absolutePath);
+                       Files.createDirectories(destPath.getParent());
+                       Files.copy(in, destPath);
+               }
+       }
+
+       /**
+        * Create Repository.xml
+        * @throws Exception
+        */
+       private void createRepositoryConfig() throws Exception {
+               SettingManager settingMgr     = SettingManager.getInstance();
+               String         path           = settingMgr.get(SettingManager.SETTINGSKEY_MOXKIRIYA_USER_DIR);
+               String         configXML      = settingMgr.get(SettingManager.SETINGKEY_CLUSTER).equals("true")
+                                                                                       ? WikiRepository.REPOSITORY_CUSTER_FILENAME
+                                                                                       : WikiRepository.REPOSITORY_LOCAL_FILENAME;
+               File           file           = new File(path + "/" + settingMgr.getSelectedParty() + "/" + configXML);
+               
+               if(file.exists() != true) {
+                       InputStream       inputStream   = getClass().getResourceAsStream("resources/" + configXML);
+                       InputStreamReader streamReader  = new InputStreamReader(inputStream, "UTF-8");
+                       BufferedReader    reader        = new BufferedReader(streamReader);
+                       StringBuffer      buf           = new StringBuffer();
+                       String            line;                 
+                       
+                       while((line = reader.readLine()) != null) {
+                               buf.append(line + "\n");
+                       }
+                       reader.close();
+                       file.createNewFile();
+
+                       BufferedWriter writer         = FileIO.bufferedWriter(file);
+                       
+                       writer.write(buf.toString());
+                       writer.flush();
+                       writer.close();
+               }
+       }
+
+       /**
+        * Create CSS Files.
+        * @throws Exception
+        */
+       private void createCssFiles() throws Exception {
+               SettingManager settingMgr         = SettingManager.getInstance();
+               String         stylesheetDestPath = settingMgr.getAbsolutePath(WikiEngine.USER_STYLESHEET_FILENAME);
+
+               if (new File(stylesheetDestPath).exists() != true) {
+                       InputStream in       = getClass().getResourceAsStream("resources/" + WikiEngine.DEFAULT_STYLESHEET_FILENAME);
+                       Path        destPath = Paths.get(stylesheetDestPath);
+                       Files.copy(in, destPath);
+               }
+       
+               String templateHtmlHeaderPath = settingMgr.getAbsolutePath(WikiEngine.TEMPLATE_HTMLHEADER_FILE);
+       
+               if (new File(templateHtmlHeaderPath).exists() != true) {
+                       InputStream in       = getClass().getResourceAsStream("resources/" + WikiEngine.TEMPLATE_HTMLHEADER_FILE);
+                       Path        destPath = Paths.get(templateHtmlHeaderPath);
+                       Files.copy(in, destPath);
+               }
+       }
+       
+       /**
+        * Session closer.
+        */
+       public void closeSession() {
+               wikiEngine_.closeSession();
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiMainWindowController.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiMainWindowController.java
new file mode 100644 (file)
index 0000000..797805c
--- /dev/null
@@ -0,0 +1,1359 @@
+/**
+ * WikiMainWindowController
+ * @author Ryuhei Terada
+ */
+package com.wiki.standalone.moxkiriya;
+
+import java.awt.Desktop;
+import java.io.File;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.ResourceBundle;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionIterator;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.events.EventListener;
+import org.w3c.dom.events.EventTarget;
+import org.w3c.dom.events.MouseEvent;
+import org.w3c.dom.html.HTMLAnchorElement;
+
+import com.wiki.standalone.moxkiriya.dialog.AboutMoxkiriyaDialog;
+import com.wiki.standalone.moxkiriya.dialog.AlertDialog;
+import com.wiki.standalone.moxkiriya.dialog.DialogBase;
+import com.wiki.standalone.moxkiriya.dialog.DialogBase.CloseType;
+import com.wiki.standalone.moxkiriya.dialog.SelectPartyDialog;
+
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.concurrent.Worker.State;
+import javafx.event.ActionEvent;
+import javafx.event.Event;
+import javafx.event.EventHandler;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.geometry.Pos;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.Hyperlink;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TableView.TableViewSelectionModel;
+import javafx.scene.control.TextArea;
+import javafx.scene.control.TextField;
+import javafx.scene.control.cell.CheckBoxTableCell;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.FlowPane;
+import javafx.scene.web.WebEngine;
+import javafx.scene.web.WebView;
+import javafx.stage.FileChooser;
+import javafx.stage.FileChooser.ExtensionFilter;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+import javafx.util.Callback;
+
+/**
+ * MainWindowコントローラ
+ */
+public class WikiMainWindowController implements Initializable {
+       /** Primary Stage */
+       private Stage          stage_;
+       
+       /** resourceBundle */
+       private ResourceBundle resourceBundle_;
+       
+       /** WikiEngine */
+       private WikiEngine     wikiEngine_;
+
+       /** Preview window */
+       private WikiPreviewWindow previewWindow_ = null;
+       
+       /*
+        * MenuBar controls.
+        */
+       @FXML   private MenuItem menuItemNew;
+       @FXML   private MenuItem menuItemImport;
+       @FXML   private MenuItem menuItemExport;
+       @FXML   private MenuItem menuItemExit;
+       @FXML   private MenuItem menuItemSelectParty;
+       @FXML   private MenuItem menuItemAboutMoxkiriya;
+
+       /*
+        * ChoiceView controls.
+        */
+       @FXML   private Hyperlink choiceViewHyperlinkReading;
+       @FXML   private Hyperlink choiceViewHyperlinkPageList;
+       @FXML   private Hyperlink choiceViewHyperlinkEdit;
+
+       /*
+        * Loading animation. 
+        */
+       @FXML   private ImageView ImageViewLoading;
+       
+       /*
+        * WebView controls.
+        */
+       @FXML   private AnchorPane AnchorPaneWebView;
+       @FXML   private Button     webViewMenuAnchorPaneButtonBack;
+       @FXML   private Button     webViewMenuAnchorPaneButtonForward;
+       @FXML   private Button     webViewMenuAnchorPaneButtonReload;
+       @FXML   private Button     webViewMenuAnchorPaneButtonHome;
+       @FXML   private TextField  webViewMenuAnchorPaneTextFieldSearchWiki;
+       @FXML   private Button     webViewMenuAnchorPaneButtonSearch;
+
+       @FXML   private Hyperlink  webViewHyperlinkMain;
+       @FXML   private Hyperlink  webViewHyperlinkHistory;
+       @FXML   private AnchorPane webViewAnchorPaneMain;
+       @FXML   private WebView    webView;
+       @FXML   private AnchorPane webViewAnchorPaneHistory;
+       @FXML   private FlowPane   webViewHistoryBreadcrumbsPane;
+       @FXML   private ListView<VersionHistoryListItem>   webViewHistoryListView;
+       @FXML   private AnchorPane webViewHistoryAnchorPaneContent;
+       @FXML   private TextField  webViewHistoryTextFieldTitle;
+       @FXML   private TextArea   webViewHistorytextAreaContents;
+       @FXML   private Button     webViewHistoryButtonRestoreVersion;
+
+       /*
+        * editAnchorPane controls.
+        */
+       @FXML   private AnchorPane      AnchorPaneEdit;
+       @FXML   private TextField       textFieldTitle;
+       @FXML   private TextArea        textAreaContents;
+       @FXML   private Label           labelAttacheFile;
+       @FXML   private TextField       textFieldAttachFile;
+       @FXML   private Button          buttonChoiceFile;
+       @FXML   private Hyperlink       hyperlinkEditAttachFiles;
+       @FXML   private Button          buttonPreview;
+       @FXML   private Button          buttonSave;
+       @FXML   private Button          buttonCancel;
+
+       /*
+        * AnchorPaneContentList controls.
+        */
+       @FXML   private AnchorPane       AnchorPaneContentList;
+       @FXML   private ComboBox<String> comboBoxNamespace;
+       @FXML   private Hyperlink        hyperlinkRedraw;
+       @FXML   private TableView<PageData>             tableViewContentList;
+       @FXML   private TableColumn<PageData, Boolean>  tableColumnCheck;
+       @FXML   private TableColumn<PageData, String>   tableColumnTitle;
+       @FXML   private TableColumn<PageData, String>   tableColumnContent;
+       @FXML   private TableColumn<PageData, String>   tableColumnDate;
+       @FXML   private TableColumn<PageData, String>   tableColumnRefs;
+       @FXML   private Button                          buttonDeletePages;
+       private CheckBox                                checkBoxAll_;   
+
+       /**
+        * Edit mode NEW or MODIFY
+        */
+       private enum EditMode {
+               NONE,
+               NEW,
+               MODIFY
+       };
+
+       /** edit mode.*/
+       private EditMode editMode_ = EditMode.NONE;
+
+       /** Close type */
+       private WikiMainWindow.CloseType closeType_ = WikiMainWindow.CloseType.EXIT;
+
+       /**
+        * Version history list item
+        */
+       public class VersionHistoryListItem {
+               /** version */
+               private Version version_;
+               
+               /** Created data. */
+               private Date created_;
+               
+               /** version node */
+               private Node node_;
+               
+               /**
+                * Constructor.
+                * @param created
+                * @param node
+                */
+               public VersionHistoryListItem(Version version, Date created, Node node) {
+                       version_ = version;
+                       created_ = created;
+                       node_    = node;
+               }
+
+               /**
+                * Version getter.
+                * @return Version
+                */
+               public Version getVersion() {
+                       return version_;
+               }
+               
+               /**
+                * Created getter.
+                * @return Date
+                */
+               public Date getCreated() {
+                       return created_;
+               }
+
+               /**
+                * Node getter.
+                * @return Node
+                */
+               public Node getNode() {
+                       return node_;
+               }               
+       }
+       
+       @Override
+       public void initialize(URL url, ResourceBundle resourceBundle) {
+               resourceBundle_ = resourceBundle;
+
+               setLinkClickListner(webView.getEngine());
+               webView.setContextMenuEnabled(false);
+
+               previewWindow_  = new WikiPreviewWindow(stage_, resourceBundle_);
+               previewWindow_.setMainWindowController(this);
+
+               checkBoxAll_    = new CheckBox();
+               checkBoxAll_.selectedProperty().addListener(new ChangeListener<Boolean>() {
+                       @Override
+                       public void changed(ObservableValue<? extends Boolean> value, Boolean oldValue, Boolean newValue) {
+                               ObservableList<PageData> pageDataList = tableViewContentList.getItems();
+                               
+                               for(PageData pageData: pageDataList) {
+                                       pageData.checkProperty().setValue(newValue);;
+                               }
+                       }
+               });
+               
+               tableColumnCheck.setCellFactory(new Callback<TableColumn<PageData, Boolean>, TableCell<PageData, Boolean>>() {
+                       @Override
+                       public TableCell<PageData, Boolean> call(TableColumn<PageData, Boolean> param) {
+                               CheckBoxTableCell<PageData, Boolean> checkBoxTableCell = new CheckBoxTableCell<PageData, Boolean>();
+                               checkBoxTableCell.setAlignment(Pos.CENTER);
+
+                               return checkBoxTableCell;
+                       }
+               });
+
+               tableColumnTitle.setCellFactory(new Callback<TableColumn<PageData, String>, TableCell<PageData, String>>() {
+                       @Override
+                       public TableCell<PageData, String> call(TableColumn<PageData, String> param) {
+                               TableCell<PageData, String>
+                                          tableCell = new TableCell<PageData, String>() {
+                                       @Override
+                                       public void updateItem(String uuid, boolean empty) {
+                                               super.updateItem(uuid, empty);
+                                               if(empty != true) {
+                                                       try {
+                                                               HashMap<String, PageData> pageMap  = wikiEngine_.queryPageUUID(uuid);
+                                                               PageData                  pageData = pageMap.get(uuid);
+                                                               Hyperlink                 hyperlink = new Hyperlink(pageData.getTitle());
+
+                                                               hyperlink.setUserData(pageData);
+                                                               hyperlink.setOnMouseClicked(new EventHandler<Event>() {
+                                                                       @Override
+                                                                       public void handle(Event event) {
+                                                                               try {
+                                                                                       Hyperlink                 source   = (Hyperlink)event.getSource();
+                                                                                       PageData                  pageData = (PageData)source.getUserData();
+
+                                                                                       wikiEngine_.setPageDataMap(pageData);
+                                                                                       loadWikiContent();
+
+                                                                                       webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+                                                                                       webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+                                                                                       webViewAnchorPaneMain.setVisible(true);
+                                                                                       webViewAnchorPaneHistory.setVisible(false);
+                                                                               } catch (Exception e) {
+                                                                                       e.printStackTrace();
+                                                                               }
+                                                                       }
+                                                               });
+                                                               
+                                                               setGraphic(hyperlink);
+                                                       } catch (Exception e) {
+                                                               e.printStackTrace();
+                                                       }
+                                               }
+                                               else {
+                                                       setGraphic(null);
+                                               }
+                                       }
+                               };
+
+                               return tableCell;
+                       }
+               });
+
+               webViewHistoryListView.setCellFactory(new Callback<ListView<VersionHistoryListItem>, ListCell<VersionHistoryListItem>>() {
+                       @Override
+                       public ListCell<VersionHistoryListItem> call(ListView<VersionHistoryListItem> arg0) {
+                               return new ListCell<VersionHistoryListItem>() {
+                                       @Override
+                                       protected void updateItem(VersionHistoryListItem item, boolean empty) {
+                                               try {
+                                                       super.updateItem(item, empty);
+                                                       if(empty != true) {
+                                                               Hyperlink hyperlinkCreated = new Hyperlink(item.getCreated().toString());
+                                                               Version   version          = item.getVersion();
+                                                               Version   baseVersion      = wikiEngine_.getBaseVersion();
+                                                               
+                                                               if(version.getIdentifier().equals(baseVersion.getIdentifier()) == true) {
+                                                                       hyperlinkCreated.setId("webViewHistoryBaseVersion");
+                                                               }
+                                                               
+                                                               hyperlinkCreated.setUserData(item);
+                                                               hyperlinkCreated.setOnAction(new EventHandler<ActionEvent>() {
+                                                                       @Override
+                                                                       public void handle(ActionEvent event) {
+                                                                               try {
+                                                                                       ObservableList<javafx.scene.Node> breadcrumbsList = webViewHistoryBreadcrumbsPane.getChildren();
+                                                                                       
+                                                                                       breadcrumbsList.clear();
+                                                                                       breadcrumbsList.add(createBreadcrumbsHyperlink("key.History.Breadcrumbs.List", 
+                                                                                                       new EventHandler<ActionEvent>() {
+                                                                                               @Override
+                                                                                               public void handle(ActionEvent event) {
+                                                                                                       ObservableList<javafx.scene.Node> breadcrumbsList = webViewHistoryBreadcrumbsPane.getChildren();
+                                                                                                       
+                                                                                                       breadcrumbsList.clear();
+                                                                                                       breadcrumbsList.add(createBreadcrumbsLabel("key.History.Breadcrumbs.List"));
+                                                                                                       webViewHistoryListView.setVisible(true);
+                                                                                                       webViewHistoryAnchorPaneContent.setVisible(false);
+                                                                                               }
+                                                                                       }));
+                                                                                       breadcrumbsList.add(createBreadcrumbsLabel("key.History.Breadcrumbs.Separator"));
+                                                                                       breadcrumbsList.add(createBreadcrumbsLabel("key.History.Breadcrumbs.Content"));
+               
+                                                                                       Hyperlink              target = (Hyperlink)event.getTarget();
+                                                                                       VersionHistoryListItem item   = (VersionHistoryListItem)target.getUserData();
+                                                                                       Node                   node   = item.getNode();
+       
+                                                                                       webViewHistoryTextFieldTitle.setText(node.getProperty(WikiRepository.PROPERTY_TITLE).getString());
+                                                                                       webViewHistorytextAreaContents.setText((node.getProperty(WikiRepository.PROPERTY_CONTENT).getString()));
+                                                                                       webViewHistoryAnchorPaneContent.setUserData(item);
+       
+                                                                                       webViewHistoryListView.setVisible(false);
+                                                                                       webViewHistoryAnchorPaneContent.setVisible(true);
+                                                                               } catch (Exception e) {
+                                                                                       e.printStackTrace();
+                                                                               }
+                                                                       }                                                               
+                                                               });
+                                                               setGraphic(hyperlinkCreated);
+                                                       }
+                                               } catch (Exception e1) {
+                                                       e1.printStackTrace();
+                                               }
+                                       }
+                               };
+                       }
+               });
+               tableColumnCheck.setGraphic(checkBoxAll_);
+               tableColumnCheck.setCellValueFactory(new PropertyValueFactory<PageData, Boolean>("check"));
+               tableColumnTitle.setCellValueFactory(new PropertyValueFactory<PageData, String>("uuid"));
+               tableColumnContent.setCellValueFactory(new PropertyValueFactory<PageData, String>("introduction"));
+               tableColumnDate.setCellValueFactory(new PropertyValueFactory<PageData, String>("date"));
+               
+               webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+               webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+               webViewAnchorPaneMain.setVisible(true);
+               webViewAnchorPaneHistory.setVisible(false);
+       }
+
+       /**
+        * Close type getter. 
+        * @return WikiMainWindow.CloseType
+        */
+       public WikiMainWindow.CloseType getCloseType() {
+               return closeType_;
+       }
+       
+       /**
+        * Stageを設定する。
+        * @param stage
+        */
+       public void setStage(Stage stage) {
+               stage_ = stage;
+       }
+
+       /**
+        * WikiEngineを設定する。
+        * @param wikiEngine
+        */
+       public void setWikiEngine(WikiEngine wikiEngine) {
+               wikiEngine_ = wikiEngine;
+       }
+       
+       /**
+        * WikiEngineを取得する。
+        * @return WikiEngine
+        */
+       public WikiEngine getWikiEngine() {
+               return wikiEngine_;
+       }
+
+       /**
+        * Hide preview window.
+        */
+       public void hidePreviewWindow() {
+               previewWindow_.hide();
+       }
+       
+       @FXML
+       public void onActionMenuItemNew(ActionEvent event) {
+               /*
+                * 各コントロールの初期値を入力する。
+                */
+               textFieldTitle.clear();
+               textAreaContents.clear();
+               buildEditView("");
+       }
+
+       @FXML
+       public void onActionMenuItemImport(ActionEvent event) {
+               FileChooser fileChooser = new FileChooser();
+               
+               fileChooser.setTitle(resourceBundle_.getString("key.ImportDialog.Title"));
+               fileChooser.getExtensionFilters().addAll(new ExtensionFilter("XML Files", "*.xml"));
+
+               File selectedFile = fileChooser.showOpenDialog(stage_);
+
+               if(selectedFile != null) {
+                       try {
+                               wikiEngine_.importSystemView(selectedFile);
+
+                               AlertDialog dialog = new AlertDialog(AlertDialog.MessageType.SuccessImport);
+                               dialog.showDialog(stage_, resourceBundle_);                             
+                               stage_.hide();
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                               try {
+                                       AlertDialog dialog = new AlertDialog(AlertDialog.MessageType.FailureImport);
+                                       dialog.showDialog(stage_, resourceBundle_);
+                                       stage_.hide();
+                               } catch (Exception e1) {
+                                       e1.printStackTrace();
+                               }                               
+                       }
+               }
+       }
+
+       @FXML
+       public void onActionMenuItemExport(ActionEvent event) {
+               FileChooser fileChooser = new FileChooser();
+               
+               fileChooser.setTitle(resourceBundle_.getString("key.ExportDialog.Title"));
+               fileChooser.getExtensionFilters().addAll(new ExtensionFilter("XML Files", "*.xml"));
+
+               File selectedFile = fileChooser.showSaveDialog(stage_);
+
+               if(selectedFile != null) {
+                       try {
+                               wikiEngine_.exportSystemView(selectedFile);
+                               AlertDialog dialog = new AlertDialog(AlertDialog.MessageType.SuccessExport);
+                               dialog.showDialog(stage_, resourceBundle_);                             
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                               try {
+                                       AlertDialog dialog = new AlertDialog(AlertDialog.MessageType.FailureExport);
+                                       dialog.showDialog(stage_, resourceBundle_);
+                               } catch (Exception e1) {
+                                       e1.printStackTrace();
+                               }
+                       }
+               }
+       }
+
+       @FXML
+       public void onActionMenuItemExit(ActionEvent event) {
+               try {
+                       if (AnchorPaneEdit.isVisible() == true) {
+                               /*
+                                * editAnchorPane表示中の場合、
+                                * 編集キャンセル確認ダイアログを表示する。
+                                */
+                               if(showConfirmEditCancelDialog() == AlertDialog.CloseType.OK) {
+                                       editMode_ = EditMode.NONE;
+                                       wikiEngine_.cancelCheckout();
+                                       previewWindow_.hide();
+                                       stage_.hide();
+                               }
+                       }
+                       else {
+                               stage_.hide();
+                       }
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+       
+       @FXML
+       public void onActionMenuItemSelectParty(ActionEvent event) {
+               try {
+                       if (AnchorPaneEdit.isVisible() == true) {
+                               /*
+                                * editAnchorPane表示中の場合、
+                                * 編集キャンセル確認ダイアログを表示する。
+                                */
+                               if(showConfirmEditCancelDialog() == AlertDialog.CloseType.OK) {
+                                       editMode_ = EditMode.NONE;
+                                       wikiEngine_.cancelCheckout();
+                               }
+                       }
+                       
+                       SelectPartyDialog selectPartyDialog = new SelectPartyDialog();
+
+                       if(selectPartyDialog.showDialog(stage_, resourceBundle_) == CloseType.OK) {
+                               closeType_ = WikiMainWindow.CloseType.RESTART;
+                               stage_.hide();
+                       }
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @FXML
+       public void onActionMenuItemAboutMoxkiriya(ActionEvent event) {
+               try {
+                       DialogBase dialog = new AboutMoxkiriyaDialog();
+                       dialog.showDialog(stage_, resourceBundle_);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @FXML
+       public void onKeyPressedTextFieldSearchWiki(KeyEvent event) {
+               try {
+                       if(event.getCode().equals(KeyCode.ENTER) == true) {
+                               doSearchWiki();
+                       }
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }                       
+       }
+
+       @FXML
+       public void onActionButtonSearch(ActionEvent event) {
+               try {
+                       doSearchWiki();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @FXML
+       public void onMouseClickedHyperlinkReading() {
+               try {
+                       AlertDialog.CloseType closeType = AlertDialog.CloseType.OK;
+
+                       if(AnchorPaneEdit.isVisible() == true) {
+                               /*
+                                * editAnchorPane表示中の場合、
+                                * 編集キャンセル確認ダイアログを表示する。
+                                */
+                               closeType = showConfirmEditCancelDialog();
+                       }
+
+                       if(closeType == AlertDialog.CloseType.OK) {
+                               editMode_ = EditMode.NONE;
+                               wikiEngine_.cancelCheckout();
+
+                               PageData pageData = getSelectingPageData();
+
+                               if(pageData != null) {
+                                       wikiEngine_.setPageDataMap(pageData);
+                               }
+
+                               menuItemNew.setDisable(false);
+
+                               loadWikiContent();
+
+                               AnchorPaneEdit.setVisible(false);
+                               AnchorPaneContentList.setVisible(false);
+                               AnchorPaneWebView.setVisible(true);
+
+                               webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+                               webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+                               webViewAnchorPaneMain.setVisible(true);
+                               webViewAnchorPaneHistory.setVisible(false);
+                       }
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @FXML
+       public void onMouseClickedHyperlinkEdit() {
+               try {
+                       wikiEngine_.refreshSession();
+                       buildEditView(EditMode.MODIFY, "");
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+       
+       @FXML
+       public void onMouseClickedHyperlinkPageList() {
+               try {
+                       AlertDialog.CloseType closeType = AlertDialog.CloseType.OK;
+
+                       if(AnchorPaneEdit.isVisible() == true) {
+                               /*
+                                * editAnchorPane表示中の場合、
+                                * 編集キャンセル確認ダイアログを表示する。
+                                */
+                               closeType = showConfirmEditCancelDialog();
+                       }
+
+                       if(closeType == AlertDialog.CloseType.OK) {
+                               editMode_ = EditMode.NONE;
+                               wikiEngine_.cancelCheckout();
+
+                               buildComboBoxNamespace();
+
+                               buildTableViewPageList();
+                               AnchorPaneWebView.setVisible(false);
+                               AnchorPaneEdit.setVisible(false);               
+                               AnchorPaneContentList.setVisible(true);
+                       }
+               } catch(Exception e) {
+                       e.printStackTrace();
+               }
+       }
+       
+       @FXML
+       public void onActionButtonBack(ActionEvent event) {
+               try {
+                       String    content = wikiEngine_.back();
+                       WebEngine webEngine = webView.getEngine();
+                       webEngine.loadContent(content);
+                       
+                       HashMap<String, PageData> map     = wikiEngine_.getPageDataMap();
+                       boolean                   canEdit = (map.size() != 1) ? true : false;
+
+                       choiceViewHyperlinkEdit.setDisable(canEdit);            
+                       menuItemNew.setDisable(false);
+
+                       AnchorPaneEdit.setVisible(false);
+                       AnchorPaneContentList.setVisible(false);
+                       AnchorPaneWebView.setVisible(true);
+
+                       webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+                       webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+                       webViewAnchorPaneMain.setVisible(true);
+                       webViewAnchorPaneHistory.setVisible(false);
+
+                       webViewMenuAnchorPaneButtonBack.setDisable(!wikiEngine_.canBack());
+                       webViewMenuAnchorPaneButtonForward.setDisable(!wikiEngine_.canForward());
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+       }
+
+       @FXML
+       public void onActionButtonForward(ActionEvent event) {
+               try {
+                       String    content = wikiEngine_.forward();
+                       WebEngine webEngine = webView.getEngine();
+                       webEngine.loadContent(content);
+
+                       HashMap<String, PageData> map     = wikiEngine_.getPageDataMap();
+                       boolean                   canEdit = (map.size() != 1) ? true : false;
+
+                       choiceViewHyperlinkEdit.setDisable(canEdit);
+                       menuItemNew.setDisable(false);
+
+                       AnchorPaneEdit.setVisible(false);
+                       AnchorPaneContentList.setVisible(false);
+                       AnchorPaneWebView.setVisible(true);
+
+                       webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+                       webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+                       webViewAnchorPaneMain.setVisible(true);
+                       webViewAnchorPaneHistory.setVisible(false);
+
+                       webViewMenuAnchorPaneButtonBack.setDisable(!wikiEngine_.canBack());
+                       webViewMenuAnchorPaneButtonForward.setDisable(!wikiEngine_.canForward());
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @FXML
+       public void onActionButtonReload(ActionEvent event) {
+               try {
+                       wikiEngine_.refreshSession();
+                       loadWikiContent();
+
+                       webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+                       webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+                       webViewAnchorPaneMain.setVisible(true);
+                       webViewAnchorPaneHistory.setVisible(false);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @FXML
+       public void onActionButtonHome(ActionEvent event) {
+               try {
+                       wikiEngine_.setPageDataMap(WikiEngine.MAINPAGE_TITLE);
+                       loadWikiContent();
+
+                       webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+                       webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+                       webViewAnchorPaneMain.setVisible(true);
+                       webViewAnchorPaneHistory.setVisible(false);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @FXML
+       public void onMouseClickedHyperlinkRedraw() {
+               try {
+                       buildTableViewPageList();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @FXML
+       public void onMouseClickedWebViewHyperlinkMain() {
+               webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+               webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+               webViewAnchorPaneMain.setVisible(true);
+               webViewAnchorPaneHistory.setVisible(false);
+       }
+
+       @FXML
+       public void onMouseClickedWebViewHyperlinkHistory() {
+               try {
+                       ObservableList<javafx.scene.Node> breadcrumbsList = webViewHistoryBreadcrumbsPane.getChildren();
+                       
+                       breadcrumbsList.clear();
+                       breadcrumbsList.add(createBreadcrumbsLabel("key.History.Breadcrumbs.List"));
+
+                       ObservableList<VersionHistoryListItem> list = webViewHistoryListView.getItems();
+
+                       list.clear();
+       
+                       VersionIterator versionIter = wikiEngine_.getVersionHistory();
+                       versionIter.skip(1);
+                       while(versionIter.hasNext() == true) {
+                               Version      version  = versionIter.nextVersion();
+                               NodeIterator nodeIter = version.getNodes();
+                               
+                               while(nodeIter.hasNext() == true) {
+                                       Node node = nodeIter.nextNode();
+                                       
+                                       list.add(new VersionHistoryListItem(version, version.getCreated().getTime(), node));
+                               }
+                       }
+
+                       webViewHyperlinkMain.setId("webViewMainHyperlinkInactive");
+                       webViewHyperlinkHistory.setId("webViewMainHyperlinkActive");
+                       webViewAnchorPaneMain.setVisible(false);
+                       webViewAnchorPaneHistory.setVisible(true);
+
+                       webViewHistoryListView.setVisible(true);
+                       webViewHistoryAnchorPaneContent.setVisible(false);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @FXML
+       public void onActionButtonRestoreVersion(ActionEvent event) {
+               try {
+                       VersionHistoryListItem item = (VersionHistoryListItem)webViewHistoryAnchorPaneContent.getUserData();
+                       wikiEngine_.restoreVersion(item.getVersion());
+
+                       wikiEngine_.refreshSession();
+                       loadWikiContent();
+
+                       webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+                       webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+                       webViewAnchorPaneMain.setVisible(true);
+                       webViewAnchorPaneHistory.setVisible(false);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+       
+       @FXML
+       public void onActionButtonDeletePages(ActionEvent event) {
+               try {
+                       ObservableList<PageData> pageDataList = tableViewContentList.getItems();
+       
+                       for(PageData pageData: pageDataList) {
+                               if(pageData.checkProperty().getValue() == true) {
+                                       wikiEngine_.deletePage(pageData);
+                               }
+                       }
+
+                       HashMap<String, PageData> map = wikiEngine_.queryPageTitle(WikiEngine.MAINPAGE_TITLE);
+                       if(map.size() < 1) {
+                               /*
+                                * MainPageがなくなった場合
+                                */
+                               PageData pageData = new PageData();
+
+                               pageData.setNamespace(WikiRepository.PROPERTY_MAIN);
+                               pageData.setTitle(WikiEngine.MAINPAGE_TITLE);
+                               pageData  = wikiEngine_.checkin(pageData);
+                       }
+
+                       wikiEngine_.clearHistory();
+                       wikiEngine_.setPageDataMap(WikiEngine.MAINPAGE_TITLE);
+                       loadWikiContent();
+
+                       webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+                       webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+                       webViewAnchorPaneMain.setVisible(true);
+                       webViewAnchorPaneHistory.setVisible(false);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+       
+       @FXML
+       public void onActionButtonChoiceFile(ActionEvent event) {
+               try {
+                       FileChooser fileChooser = new FileChooser();
+                       fileChooser.setTitle("Select " + textFieldTitle.getText());
+                       File file = fileChooser.showOpenDialog(stage_);
+                       
+                       if(file != null) {
+                               textFieldAttachFile.setText(file.getPath());
+                       }
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @FXML
+       public void onActionButtonPreview(ActionEvent event) {
+               try {
+                       previewWindow_.setWikiRepository(wikiEngine_.getWikiRepository());
+                       previewWindow_.show();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }                       
+       }
+
+       @FXML
+       public void onActionButtonSave(ActionEvent event) {
+               try {                   
+                       String  title = textFieldTitle.getText();
+
+                       if(title.isEmpty() == true) {
+                               Stage       stage       = new Stage(StageStyle.UTILITY);
+                               stage.initOwner(stage_);
+                               stage.initModality(Modality.WINDOW_MODAL);
+
+                               AlertDialog alertDialog = new AlertDialog(AlertDialog.MessageType.AlertTitleEmpty);
+                               alertDialog.showDialog(stage, resourceBundle_);
+                       }
+                       else {
+                               PageData pageData = (PageData)AnchorPaneEdit.getUserData();
+                               
+                               if(editMode_ == EditMode.NEW) {
+                                       if(pageData == null) {
+                                               pageData = new PageData();
+                                               pageData.setNamespace(WikiRepository.PROPERTY_MAIN);
+                                       }
+                               }
+                               
+                               pageData.setTitle(title);
+                               pageData.setContent(textAreaContents.getText());
+
+                               String filename = textFieldAttachFile.getText();
+                               if(filename.isEmpty() != true) {
+                                       pageData.setFileData(new File(filename));                                       
+                               }
+                               pageData  = wikiEngine_.checkin(pageData);
+                               editMode_ = EditMode.NONE;
+                               previewWindow_.hide();
+
+                               /*
+                                * 更新後のページを再parse
+                                */
+                               wikiEngine_.setPageDataMap(pageData);
+                               loadWikiContent();
+
+                               menuItemNew.setDisable(false);
+
+                               /*
+                                * PaneをWebViewAnchorPaneに切り替える。
+                                */
+                               AnchorPaneWebView.setVisible(true);
+                               AnchorPaneEdit.setVisible(false);
+
+                               webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+                               webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+                               webViewAnchorPaneMain.setVisible(true);
+                               webViewAnchorPaneHistory.setVisible(false);
+                       }
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @FXML
+       public void onActionButtonCancel(ActionEvent event) {
+               try {
+                       if(showConfirmEditCancelDialog() == AlertDialog.CloseType.OK) {
+                               editMode_ = EditMode.NONE;
+                               wikiEngine_.cancelCheckout();
+                               previewWindow_.hide();
+                               menuItemNew.setDisable(false);
+
+                               /*
+                                * 確認ダイアログでOKが押下された場合
+                                * EditAnchorPaneからWebViewペインに表示を切り替え
+                                */
+                               AnchorPaneWebView.setVisible(true);
+                               AnchorPaneEdit.setVisible(false);
+                       }
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+       
+       /**
+        * 編集キャンセル確認ダイアログを表示する。
+        * @return 終了種別
+        * @throws Exception 
+        */
+       private AlertDialog.CloseType showConfirmEditCancelDialog() throws Exception {
+               AlertDialog alertDialog = new AlertDialog(AlertDialog.MessageType.ConfirmEditCancel);
+
+               return alertDialog.showDialog(stage_, resourceBundle_);
+       }       
+
+       /**
+        * 編集Viewを構築する。
+        */
+       public void buildEditView(String title) {
+               buildEditView(EditMode.NEW, title);
+       }
+
+       /**
+        * 編集Viewを構築する。
+        */
+       public void buildEditView(EditMode editMode, String title) {
+               try {
+                       String content   = "";
+                       String namespace = "";
+
+                       editMode_ = editMode;
+
+                       if(editMode == EditMode.MODIFY) {
+                               HashMap<String, PageData> map      = wikiEngine_.getPageDataMap();
+                               PageData                  pageData = map.values().iterator().next();
+
+                               AnchorPaneEdit.setUserData(pageData);
+                               wikiEngine_.checkout();
+                               title     = pageData.getTitle();
+                               content   = pageData.getContent();
+                               namespace = pageData.getNamespace();
+                       }
+                       else {
+                               AnchorPaneEdit.setUserData(null);
+
+                               if(editMode_ == EditMode.NEW) {
+                                       if(title.isEmpty() != true) {
+                                               PageData pageData  = new PageData();
+                                               String   pageTitle = title;
+
+                                               pageData.setNamespace(WikiRepository.PROPERTY_MAIN);                                            
+
+                                               if(title.contains(":")) {
+                                                       namespace = title.substring(0, title.indexOf(":"));
+                                               }
+
+                                               if(namespace.isEmpty() != true) {
+                                                       if(wikiEngine_.isContainsNamespaceList(namespace) == true) {
+                                                               pageData.setNamespace(namespace);                                                               
+                                                               pageTitle = title.substring(namespace.length() + ":".length(), title.length());
+                                                       }
+                                                       else {
+                                                               pageTitle = title;
+                                                       }
+                                               }
+
+                                               pageData.setTitle(pageTitle);
+                                               AnchorPaneEdit.setUserData(pageData);
+
+                                               title     = pageData.getTitle();
+                                               namespace = pageData.getNamespace();
+                                       }
+                               }
+                       }
+
+                       boolean cannotAttacheFile = namespace.equals(WikiEngine.NAMESPACE_FILE) == true
+                                                                       ? false
+                                                                       : true;
+                       textFieldAttachFile.setDisable(cannotAttacheFile);
+                       labelAttacheFile.setDisable(cannotAttacheFile);
+                       buttonChoiceFile.setDisable(cannotAttacheFile);
+
+                       /*
+                        * 各コントロールの初期値を入力する。
+                        */
+                       textFieldTitle.setText(title);
+                       textAreaContents.setText(content);
+                       textFieldAttachFile.setText("");
+
+                       menuItemNew.setDisable(true);
+
+                       /*
+                        * WebViewペインからEditAnchorPaneに表示を切り替え
+                        */
+                       AnchorPaneWebView.setVisible(false);
+                       AnchorPaneContentList.setVisible(false);
+                       AnchorPaneEdit.setVisible(true);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }               
+       }
+       
+       /**
+        * Latest contents getter.
+        * @return PageData
+        * @throws Exception 
+        */
+       public PageData getLatestContents() throws Exception {
+               PageData pageData = new PageData();
+               PageData editData = (PageData)AnchorPaneEdit.getUserData();
+       
+               pageData.setTitle(textFieldTitle.getText());
+               pageData.setContent(textAreaContents.getText());
+               
+               String namespace = editData != null
+                                                       ? editData.getNamespace()
+                                                       : WikiRepository.PROPERTY_MAIN;
+               pageData.setNamespace(namespace);
+               String pathname = textFieldAttachFile.getText();
+               if( (pathname != null)
+                && (pathname.isEmpty() != true)) {
+                       pageData.setFileData(new File(pathname));
+               }
+
+               return pageData;
+       }
+
+       /**
+        * WikiContentをロードする。
+        * @param contentDir
+        */
+       public void loadWikiContent() {
+               try {
+                       WebEngine webEngine = webView.getEngine();
+                       webEngine.loadContent(wikiEngine_.parse());
+
+                       HashMap<String, PageData> map     = wikiEngine_.getPageDataMap();
+                       boolean                   canEdit = (map.size() != 1) ? true : false;
+
+                       choiceViewHyperlinkEdit.setDisable(canEdit);
+
+                       menuItemNew.setDisable(false);
+                       AnchorPaneEdit.setVisible(false);
+                       AnchorPaneContentList.setVisible(false);
+                       AnchorPaneWebView.setVisible(true);
+
+                       webViewMenuAnchorPaneButtonBack.setDisable(!wikiEngine_.canBack());
+                       webViewMenuAnchorPaneButtonForward.setDisable(!wikiEngine_.canForward());
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * ページ内の指定セクションリンクへジャンプする。
+        * @param target
+        * @throws Exception 
+        */
+       private void jumpToSectionLink(EventTarget target) throws Exception {
+               HTMLAnchorElement anchor      = (HTMLAnchorElement)target;
+               String            href        = anchor.getAttribute("href");
+               String            pageTitle   = URLDecoder.decode(href, "UTF-8");
+               String            sectionName = pageTitle.substring(pageTitle.indexOf("#") + "#".length());
+               webView.getEngine().executeScript("scrollTo('" + sectionName + "')");
+       }
+
+       /**
+        * webViewを取得する。
+        * @return webView
+        */
+       public WebView getWebView() {
+               return webView;
+       }
+       
+       /**
+        * ImageViewLoadingを取得する。
+        * @return ImageViewLoading
+        */
+       public ImageView getImageViewLoading() {
+               return ImageViewLoading;
+       }
+
+       /**
+        * Execute search wiki.
+        * @throws Exception
+        */
+       private void doSearchWiki() throws Exception {
+               String key = webViewMenuAnchorPaneTextFieldSearchWiki.getText();
+               
+               if(key.isEmpty() != true) {                             
+                       HashMap<String, PageData> map = wikiEngine_.queryPageFullTextSearch(key);
+
+                       wikiEngine_.setPageDataMap(map);
+                       loadWikiContent();
+
+                       webViewHyperlinkMain.setId("webViewMainHyperlinkActive");
+                       webViewHyperlinkHistory.setId("webViewMainHyperlinkInactive");
+                       webViewAnchorPaneMain.setVisible(true);
+                       webViewAnchorPaneHistory.setVisible(false);
+               }
+       }
+       
+       /**
+        * 選択中または現在表示中のコンテンツのディレクトリを取得する。
+        * @return 選択中または表示中のコンテンツのディレクトリ
+        * @throws Exception 
+        */
+       private PageData getSelectingPageData() throws Exception {
+               PageData pageData = null;
+               
+               if(AnchorPaneContentList.isVisible() == true) {
+                       TableViewSelectionModel<PageData> selectedData = tableViewContentList.selectionModelProperty().getValue();
+                       pageData = selectedData.getSelectedItem();
+               }
+               else if(AnchorPaneEdit.isVisible() == true) {
+                       pageData = (PageData)AnchorPaneEdit.getUserData();
+               }
+               
+               return pageData;
+       }
+
+       /**
+        * Build a namespace comboBox.
+        * @throws Exception
+        */
+       private void buildComboBoxNamespace() throws Exception {
+               ArrayList<String>      namespaceList = wikiEngine_.getNamespaceList();
+               ObservableList<String> items         = comboBoxNamespace.getItems();
+
+               items.clear();
+               for(int index = 0; index < namespaceList.size(); index++) {
+                       String item = namespaceList.get(index);
+                       items.add(item);
+                       
+                       if(item.equals(WikiRepository.PROPERTY_MAIN) == true) {
+                               comboBoxNamespace.getSelectionModel().select(index);
+                       }
+               }
+       }
+
+       /**
+        * Build page list view
+        * @throws Exception
+        */
+       private void buildTableViewPageList() throws Exception {
+               String                    namespace      = comboBoxNamespace.getSelectionModel().getSelectedItem();
+               HashMap<String, PageData> pageMap        = wikiEngine_.queryPageNamespace(namespace);
+               ObservableList<PageData>  observableList = FXCollections.observableArrayList();
+               
+               tableViewContentList.getItems().clear();
+
+               for(String key: pageMap.keySet()) {
+                       observableList.add(pageMap.get(key));
+               }
+               tableViewContentList.setItems(observableList);
+       }
+
+       /**
+        * A要素のクリックリスナーを登録する。
+        * @param webEngine
+        */
+       private void setLinkClickListner(WebEngine webEngine) {
+               webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
+                       @Override
+                       public void changed(ObservableValue<? extends State> arg0, State oldState, State newState) {
+                               WebView        webView  = getWebView();
+                               EventListener  listener =  new EventListener() {                                                
+                                       @Override
+                                       public void handleEvent(org.w3c.dom.events.Event event) {
+                                               try {
+                                                       MouseEvent        mouseEvent  = (MouseEvent)event;
+                                                       EventTarget       target      = mouseEvent.getCurrentTarget();
+
+                                                       if(isExternalLink(target) == true) {
+                                                               /*
+                                                                * WebEngineのデフォルトの動作(リンク先ページをロード)をキャンセル
+                                                                */
+                                                               event.preventDefault(); 
+                                                               externalLinkHandle(target);
+                                                       }
+                                                       else {
+                                                               internalLinkHandle(target);
+                                                       }
+                                               } catch (Exception e) {
+                                                       e.printStackTrace();
+                                               }
+                                       }
+
+                                       /**
+                                        * targetが外部リンクか判定する。
+                                        * @param target
+                                        * @return
+                                        */
+                                       private boolean isExternalLink(EventTarget target) {
+                                               final ArrayList<String> schemeList = new ArrayList<String>() {
+                                                       private static final long serialVersionUID = 1L;
+                                                       { add("http://"); }
+                                                       { add("https://"); }
+                                                       { add("file://"); }
+                                               };
+
+                                               HTMLAnchorElement aElem      = (HTMLAnchorElement)target;
+                                               String            href       = aElem.getAttribute("href");
+                                               boolean           isExternal = false;
+
+                                               for(String scheme: schemeList) {
+                                                       if(href.startsWith(scheme) == true) {
+                                                               isExternal = true;
+                                                               break;
+                                                       }
+                                               }
+
+                                               return isExternal;
+                                       }
+                                       
+                                       /**
+                                        * ExternalLinkを処理する。
+                                        * @param target
+                                        * @throws Exception
+                                        */
+                                       private void externalLinkHandle(EventTarget target) throws Exception {
+                                               String targetpath   = target.toString();
+                                               if(targetpath.startsWith("file:///") == true) {
+                                                       targetpath = URLDecoder.decode(targetpath, "UTF-8");
+                                               }
+                                               /*
+                                                * 既定のブラウザを起動してリンク先ページを開く
+                                                */
+                                               Desktop.getDesktop().browse(new URI(targetpath));
+                                       }
+
+                                       /**
+                                        * InternalLinkを処理する。
+                                        * @param target
+                                        * @throws Exception
+                                        */
+                                       private void internalLinkHandle(EventTarget target) throws Exception {
+                                               HashMap<String, PageData> pageDataMap;
+                                               HTMLAnchorElement         anchor    = (HTMLAnchorElement)target;
+                                               String                    href      = anchor.getAttribute("href");
+                                               String                    pageTitle = URLDecoder.decode(href, "UTF-8");
+                                               String                    uuid      = anchor.getAttribute(WikiEngine.ATTRIBUTE_JCR_UUID);
+
+                                               if(uuid != null) {
+                                                       pageDataMap = wikiEngine_.queryPageUUID(uuid);
+                                               }
+                                               else {
+                                                       pageDataMap = wikiEngine_.queryPageTitle(pageTitle);                                                            
+                                               }
+                                               if(pageDataMap.size() == 1) {
+                                                       wikiEngine_.setPageDataMap(pageDataMap);
+                                                       loadWikiContent();
+                                               }
+                                               else {
+                                                       if(href.contains("#")) {
+                                                               /*
+                                                                * ページ内セクションリンク
+                                                                */
+                                                               jumpToSectionLink(target);
+                                                       }
+                                                       else {
+                                                               buildEditView(href);
+                                                       }
+                                               }
+
+                                       }
+               };
+
+                               if(newState == State.SUCCEEDED) {
+                                       Document  doc   = webView.getEngine().getDocument();
+                           NodeList  listA = doc.getElementsByTagName("a");
+                           
+                           for(int index = 0; index < listA.getLength(); index++) {
+                               ((EventTarget)listA.item(index)).addEventListener("click", listener, false);
+                           }
+                                       getImageViewLoading().setVisible(false);
+                                       webView.setVisible(true);
+                               }
+                       }
+               });
+       }
+
+       /**
+        * Bread crumbs label creator.
+        * @param key
+        * @return Label
+        */
+       private Label createBreadcrumbsLabel(String key) {
+               Label labelCrumbsList = new Label(resourceBundle_.getString(key));
+               
+               labelCrumbsList.setId("webViewBreadcrumbs");
+               labelCrumbsList.setPrefHeight(40);
+
+               return labelCrumbsList;
+       }
+
+       /**
+        * Bread crumbs hyperlink creator.
+        * @param key
+        * @param eventHandler
+        * @param layoutX
+        * @return Label
+        */
+       private Hyperlink createBreadcrumbsHyperlink(String key, EventHandler<ActionEvent> eventHandler) {
+               Hyperlink linkCrumbsList = new Hyperlink(resourceBundle_.getString(key));
+               
+               linkCrumbsList.setId("webViewBreadcrumbs");
+               linkCrumbsList.setPrefHeight(40);
+               linkCrumbsList.setOnAction(eventHandler);
+               
+               return linkCrumbsList;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiPreviewWindow.fxml b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiPreviewWindow.fxml
new file mode 100644 (file)
index 0000000..8711666
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import java.net.*?>
+<?import java.util.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.paint.*?>
+<?import javafx.scene.web.*?>
+<?scenebuilder-preview-i18n-resource resources/moxkiriya.properties?>
+
+<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="513.0" prefWidth="842.0" styleClass="webViewMainAnchorPane" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.wiki.standalone.moxkiriya.WikiPreviewWindowController">
+  <children>
+    <Button fx:id="buttonReload" mnemonicParsing="false" onAction="#onActionButtonReload" prefHeight="35.0" prefWidth="70.0" text=" 🔃" textAlignment="CENTER" AnchorPane.leftAnchor="5.0" AnchorPane.topAnchor="10.0" />
+    <WebView fx:id="webView" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white;" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="50.0" />
+    <Button fx:id="buttonClose" mnemonicParsing="false" onAction="#onActionButtonClose" prefHeight="35.0" prefWidth="100.0" text="%key.Button.Close" AnchorPane.bottomAnchor="5.0" AnchorPane.rightAnchor="5.0" />
+  </children>
+  <stylesheets>
+    <URL value="@application.css" />
+  </stylesheets>
+</AnchorPane>
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiPreviewWindow.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiPreviewWindow.java
new file mode 100644 (file)
index 0000000..f235663
--- /dev/null
@@ -0,0 +1,132 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Wiki preview window.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya;
+
+import java.util.ResourceBundle;
+
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+
+/**
+ * Show preview editing content.
+ *
+ */
+public class WikiPreviewWindow {
+       /** mother stage. */
+       private Stage motherStage_ = null;
+
+       /** Resource Bundle */
+       private ResourceBundle resources_ = null;
+
+       /** Stage */
+       private Stage stage_;
+
+       /** Preview window controller */
+       private WikiPreviewWindowController controller_;
+
+       /** Main window controller */
+       private WikiMainWindowController mainController_;
+       
+       /**
+        * Status of preview window.
+        *
+        */
+       private enum PreviewWindowStatus {
+               SHOW,
+               HIDE
+       };
+
+       /** Preview window status */
+       private PreviewWindowStatus previewWindowStatus_ = PreviewWindowStatus.HIDE; 
+       
+       /**
+        * Constructor.
+        */
+       public WikiPreviewWindow(Stage motherStage, ResourceBundle resources) {
+               motherStage_ = motherStage;
+               resources_   = resources;
+
+               try {
+                       FXMLLoader loader = new FXMLLoader(getClass().getResource("WikiPreviewWindow.fxml"), resources_);
+                       loader.load();
+
+                       Scene scene  = new Scene((Parent)loader.getRoot());
+                       scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
+
+                       controller_ = loader.getController();
+                       controller_.setWikiPreviewWindow(this);
+
+                       stage_  = new Stage(StageStyle.DECORATED);
+                       stage_.initOwner(motherStage_);
+                       stage_.setScene(scene);
+                       stage_.setTitle(resources_.getString("key.PreviewWindow.Title"));
+                       stage_.setResizable(true);
+                       stage_.showingProperty().addListener(new ChangeListener<Boolean>() {
+                               @Override
+                               public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
+                                       previewWindowStatus_ = newValue == false
+                                                       ? PreviewWindowStatus.HIDE
+                                                       : PreviewWindowStatus.SHOW;
+                               }
+                       });
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * Main windowController setter.
+        * @param mainController
+        */
+       public void setMainWindowController(WikiMainWindowController mainController) {
+               mainController_ = mainController;
+       }
+
+       /**
+        * Wiki repository setter.
+        * @param wikiRepository
+        */
+       public void setWikiRepository(WikiRepository wikiRepository) {
+               controller_.setWikiRepository(wikiRepository);
+       }
+
+       /**
+        * Latest contents getter.
+        * @return PageData
+        * @throws Exception 
+        */
+       public PageData getLatestContents() throws Exception {
+               return mainController_.getLatestContents();
+       }
+       
+       /**
+        * Show Wiki preview window
+        * @throws Exception
+        */
+       public void show() throws Exception {
+               controller_.loadWikiContent(mainController_.getLatestContents());
+
+               if(previewWindowStatus_ == PreviewWindowStatus.HIDE) {
+                       stage_.show();                          
+               } else {
+                       controller_.loadWikiContent(mainController_.getLatestContents());
+               }
+       }
+
+       /**
+        * Hide Wiki preview window
+        */
+       public void hide() {
+               stage_.hide();
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiPreviewWindowController.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiPreviewWindowController.java
new file mode 100644 (file)
index 0000000..fd813e4
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Wiki preview window controller.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.ResourceBundle;
+
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.web.WebView;
+
+/**
+ * Controll preview window.
+ *
+ */
+public class WikiPreviewWindowController implements Initializable {
+       /** Wiki engine */
+       private WikiEngine wikiEngine_;
+
+       /** Wiki preview window */
+       private WikiPreviewWindow wikiPreviewWindow_;
+
+       @FXML private Button   buttonReload;
+       @FXML private Button   buttonClose;
+       @FXML private WebView  webView;
+       
+       @Override
+       public void initialize(URL url, ResourceBundle resource) {
+               wikiEngine_ = new WikiEngine();
+       }
+
+       /**
+        * WikiPreviewWindow setter.
+        */
+       public void setWikiPreviewWindow(WikiPreviewWindow previewWindow) {
+               wikiPreviewWindow_ = previewWindow;
+       }
+
+       /**
+        * Wiki repository setter.
+        * @param wikiRepository
+        */
+       public void setWikiRepository(WikiRepository wikiRepository) {
+               wikiEngine_.setWikiRepository(wikiRepository);
+       }
+
+       /**
+        * Wiki content loader.
+        * @param pageData
+        */
+       public void loadWikiContent(PageData pageData) {
+               try {
+                       HashMap<String, PageData> map = new HashMap<String, PageData>();
+                       map.put("preview", pageData);
+                       wikiEngine_.setPageDataMap(map);
+
+                       String content = wikiEngine_.parse(pageData);
+                       webView.getEngine().loadContent(content);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+       
+       @FXML
+       public void onActionButtonReload(ActionEvent event) {
+               try {
+                       PageData pageData = wikiPreviewWindow_.getLatestContents();
+                       loadWikiContent(pageData);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+       
+       @FXML
+       public void onActionButtonClose(ActionEvent event) {
+               ((Node)event.getSource()).getScene().getWindow().hide();
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiRepository.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/WikiRepository.java
new file mode 100644 (file)
index 0000000..c140e25
--- /dev/null
@@ -0,0 +1,693 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Wiki Repository.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+
+package com.wiki.standalone.moxkiriya;
+       
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.net.NetworkInterface;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+
+import javax.jcr.Credentials;
+import javax.jcr.ImportUUIDBehavior;
+import javax.jcr.NamespaceException;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.Workspace;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryManager;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionIterator;
+import javax.jcr.version.VersionManager;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+import org.apache.jackrabbit.core.jndi.RegistryHelper;
+import org.apache.jackrabbit.value.StringValue;
+
+import com.wiki.standalone.moxkiriya.PageData.FileData;
+
+/**
+ * WikiRepository class.
+ *
+ */
+public class WikiRepository {
+       /** repository_cluster_derby.xml */
+       public static final String REPOSITORY_CUSTER_FILENAME = "repository_cluster_derby.xml";
+
+       /** repository_local.xml */
+       public static final String REPOSITORY_LOCAL_FILENAME = "repository_local.xml";  
+
+       public static final String REOPSITORY_DIRNAME = "Repository";
+       
+       /** Moxkiriya repository generic namespace */
+       public static final String NAMESPACE_MOXKI = "moxki";
+       
+       public static final String NAMESPACE_MOXKI_URI = "https://osdn.net/users/ryuhei__terada/pf/Moxkiriya7/moxki/1.0";
+
+       /** Node name "wikiroot" */
+       public static final String NODE_WIKIROOT = NAMESPACE_MOXKI      + ":wikiroot";
+
+       /** Node name "namespace" */
+       public static final String NODE_NAMESPACE = NAMESPACE_MOXKI + ":namespacelist";
+
+       /** Property name "namespace" */
+       public static final String PROPERTY_NAMESPACE = NAMESPACE_MOXKI + ":namespace";
+
+       /** Property value "Main" in namespace */
+       public static final String PROPERTY_MAIN = "Main";
+
+       /** Property value "Category" in namespace */
+       public static final String PROPERTY_CATEGORY = "Category";
+
+       /** Property value "File" in namespace */
+       public static final String PROPERTY_FILE = "File";
+
+       /** Node name "pages" */
+       public static final String NODE_PAGES = NAMESPACE_MOXKI + ":pages";
+
+       /** Node name "page" */
+       public static final String NODE_PAGE = NAMESPACE_MOXKI + ":page";
+
+       /** Property name "title" */
+       public static final String PROPERTY_TITLE = NAMESPACE_MOXKI + ":title";
+
+       /** Property name "content" */
+       public static final String PROPERTY_CONTENT = NAMESPACE_MOXKI + ":content";
+
+       /** Property name "category" */
+       public static final String PROPERTY_category = NAMESPACE_MOXKI + ":category";
+
+       /** Node name "file" */
+       public static final String NODE_FILE = NAMESPACE_MOXKI + ":file";
+       
+       /** Repository Home directory */
+       private String repositoryHomeDir_;
+
+       /** repository.xml */
+       private String repositoryFile_;
+
+       /** Initial context settings table */
+       private static Hashtable<String, String> envHashTable = new  Hashtable<String, String>() {
+               private static final long serialVersionUID = 1L;
+               {
+                       put(Context.INITIAL_CONTEXT_FACTORY,
+                               "org.apache.jackrabbit.core.jndi.provider.DummyInitialContextFactory");
+               }
+               {
+                       put(Context.PROVIDER_URL, "localhost");
+               }
+       };
+
+       /** Repository */
+       private Repository repository_;
+
+       /** Session */
+       private Session    session_;
+
+       /**
+        * Constructor.
+        * @param wikirootPath
+        * @throws Exception 
+        */
+       public WikiRepository(File wikirootPath) throws Exception {
+               SettingManager settingMgr = SettingManager.getInstance();
+
+               setSystemProperties();
+               
+               String configXML = settingMgr.get(SettingManager.SETINGKEY_CLUSTER).equals("true")
+                               ? REPOSITORY_CUSTER_FILENAME
+                               : REPOSITORY_LOCAL_FILENAME;
+
+               repositoryHomeDir_ = settingMgr.getAbsolutePath(REOPSITORY_DIRNAME);
+               repositoryFile_    = settingMgr.getAbsolutePath(configXML);
+
+               InitialContext initialContext = new InitialContext(envHashTable);
+       RegistryHelper.registerRepository(initialContext,
+                       "repo",
+                       repositoryFile_,
+                       repositoryHomeDir_,
+                       true);
+       repository_ = (Repository)initialContext.lookup("repo");
+       session_    = repository_.login((Credentials)null);
+       }
+
+       /**
+        * Session closer.
+        */
+       public void closeSession() {
+               session_.logout();
+       }
+       
+       /**
+        * Build Apache Jackrabbit Repository.
+        * @param pageData
+        * @throws Exception 
+        */
+       public void buildWikiRepository(PageData pageData) throws Exception {           
+               Workspace         workspace  = session_.getWorkspace();
+
+               try {
+                       NamespaceRegistry nsRegistry = workspace.getNamespaceRegistry();
+
+                       nsRegistry.getPrefix(NAMESPACE_MOXKI_URI);
+               } catch(NamespaceException e) {
+                       /*
+                        * Build Apache Jackrabbit Repository if namespace"moxki" hasnot registered.
+                        */
+                       workspace.getNamespaceRegistry().registerNamespace(NAMESPACE_MOXKI, NAMESPACE_MOXKI_URI);
+
+               Node root      = session_.getRootNode();
+               Node wikiroot  = root.addNode(NODE_WIKIROOT);
+               Node namespace = wikiroot.addNode(NODE_NAMESPACE);
+               namespace.setProperty(PROPERTY_NAMESPACE,
+                                                               new Value[] {
+                                                                       new StringValue(PROPERTY_MAIN), 
+                                                                       new StringValue(PROPERTY_CATEGORY),
+                                                                       new StringValue(PROPERTY_FILE)
+                                                               });
+               wikiroot.addNode(NODE_PAGES);
+
+               /*
+                * "page"ノードを作成
+                */
+               checkin(pageData);
+               }
+       }
+
+       /**
+        * Add pageNode.
+        * @param pageData
+        * @throws Exception 
+        */
+       public Node addPageNode(PageData pageData) throws Exception {
+       Node root      = session_.getRootNode();
+       Node wikiroot  = root.getNode(NODE_WIKIROOT);
+       Node pagesNode = wikiroot.getNode(NODE_PAGES);
+       Node pageNode  = pagesNode.addNode(NODE_PAGE);
+
+       pageNode.addMixin(NodeType.MIX_VERSIONABLE);
+       pageNode.addMixin(NodeType.MIX_REFERENCEABLE);
+
+       return transformPageDataToNode(pageData, pageNode);
+       }
+
+       /**
+        * Transform PageData to node.
+        * @param pageData
+        * @param node
+        * @return Node
+        * @throws Exception
+        */
+       public Node transformPageDataToNode(PageData pageData, Node node) throws Exception {
+               node.setProperty(PROPERTY_NAMESPACE, new StringValue(pageData.getNamespace()));
+               node.setProperty(PROPERTY_TITLE, new StringValue(pageData.getTitle()));
+               node.setProperty(PROPERTY_CONTENT, new StringValue(pageData.getContent()));
+
+        ArrayList<String> categories = pageData.getCategories();
+       Value[] values = new Value[] { new StringValue("") };
+        if(categories.size() > 0) {
+               values = new Value[categories.size()];
+               for(int count = 0; count < categories.size(); count++) {
+                       values[count] = new StringValue(categories.get(count));
+               }
+        }
+       node.setProperty(PROPERTY_category, values);
+
+               FileData fileData = pageData.getFileData();
+
+               if(fileData != null) {
+                       Node fileNode;                  
+                       if(node.hasNode(WikiRepository.NODE_FILE) == true) {
+                               fileNode = node.getNode(WikiRepository.NODE_FILE);
+                       }
+                       else {
+                               fileNode     = node.addNode(WikiRepository.NODE_FILE, NodeType.NT_FILE);
+                               fileNode.addNode(Property.JCR_CONTENT, NodeType.NT_RESOURCE);
+                       }
+
+                       Node         nodeResource = fileNode.getNode(Property.JCR_CONTENT);
+                       ValueFactory valueFactory = session_.getValueFactory();
+                       
+                       nodeResource.setProperty(Property.JCR_DATA, valueFactory.createBinary(fileData.getInputStream()));
+                       nodeResource.setProperty(Property.JCR_MIMETYPE, new StringValue(fileData.getMimeType()));
+                       nodeResource.setProperty(Property.JCR_LAST_MODIFIED, valueFactory.createValue(fileData.getLastModified()));
+                       if(fileData.getMimeType().startsWith("text/") == true) {
+                               nodeResource.setProperty(Property.JCR_ENCODING, new StringValue("UTF-8"));
+                       }
+               }
+       
+        return node;
+       }
+
+       /**
+        * Execute query.
+        * @param sql
+        * @return HashMap<String, PageData>
+        * @throws Exception
+        */
+       private HashMap<String, PageData> executeQuery(String sql) throws Exception {
+               Workspace    workspace = session_.getWorkspace();
+               QueryManager queryMgr  = workspace.getQueryManager();
+               Query        query     = queryMgr.createQuery(sql, Query.JCR_SQL2);             
+        NodeIterator iter      = query.execute().getNodes();
+
+        return convertNodeIteratorToPageDataMap(iter);
+       }
+       
+       /**
+        * Get node matched namespace.
+        * @param pageTitle
+        * @return HashMap<String, PageData>
+        * @throws Exception 
+        */
+       public HashMap<String, PageData> queryPageNamespace(String namespace) throws Exception {
+        return executeQuery(
+                               "SELECT * "
+                               + "     FROM [nt:unstructured]"
+                               + " WHERE"
+                               + " ISDESCENDANTNODE(["
+                                       + "/" + NODE_WIKIROOT + "/" + NODE_PAGES + "])"
+                               + " AND"
+                               + " [" + PROPERTY_NAMESPACE + "] = '" + namespace + "'"
+               );
+       }
+
+       /**
+        * Get node matched uuid.
+        * @param uuid
+        * @return HashMap<String, PageData>
+        * @throws Exception 
+        */
+       public HashMap<String, PageData> queryPageUUID(String uuid) throws Exception {
+        return executeQuery(
+                       "SELECT * " 
+                       + "     FROM [nt:unstructured]"
+                       + " WHERE"
+                       + " ISDESCENDANTNODE(["
+                                       + "/" + NODE_WIKIROOT + "/" + NODE_PAGES + "])"
+                       + " AND"
+                       + " [" + Property.JCR_UUID + "] = '" + uuid + "'"
+               );
+       }
+       
+       /**
+        * Get node matched page title.
+        * @param pageTitle
+        * @return HashMap<String, PageData>
+        * @throws Exception 
+        */
+       public HashMap<String, PageData> queryPageTitle(String pageTitle) throws Exception {
+               String       namespace = PROPERTY_MAIN;
+               String       title     = pageTitle;
+               
+               if(pageTitle.contains(":") == true) {
+                       namespace = pageTitle.substring(0, pageTitle.indexOf(":"));
+                       title     = pageTitle.substring(pageTitle.indexOf(":") + ":".length());
+               }
+               
+        return queryPageTitle(title, namespace);
+       }
+       
+       /**
+        * Get node matched page title.
+        * @param pageTitle
+        * @param namespace
+        * @return HashMap<String, PageData>
+        * @throws Exception 
+        */
+       public HashMap<String, PageData> queryPageTitle(String pageTitle, String namespace) throws Exception {
+        return executeQuery(
+                       "SELECT * " 
+                       + "     FROM [nt:unstructured]"
+                       + " WHERE"
+                       + " ISDESCENDANTNODE(["
+                               + "/" + NODE_WIKIROOT + "/" + NODE_PAGES + "])"
+                       + " AND"
+                       + " [" + PROPERTY_NAMESPACE + "] = '" + namespace + "'"
+                       + " AND"
+                       + " [" + PROPERTY_TITLE + "] = '" + pageTitle + "'"
+                       );
+       }
+
+       /**
+        * Execute full text search.
+        * @param searchKey
+        * @return String
+        * @throws Exception 
+        */
+       public HashMap<String, PageData> queryPageFullTextSearch(String searchKey) throws Exception {
+        return executeQuery(
+                       "SELECT * " 
+                       + "     FROM [nt:unstructured]"
+                       + " WHERE"
+                       + " ISDESCENDANTNODE(["
+                               + "/" + NODE_WIKIROOT + "/" + NODE_PAGES + "])"
+                       + " AND "
+                       + " CONTAINS([" + PROPERTY_TITLE + "], '" + searchKey + "')"
+                       + " OR "
+                       + " CONTAINS([" + PROPERTY_CONTENT + "], '" + searchKey +  "')"
+               );
+       }
+
+       /**
+        * Converter NodeIterator to PageDatMap.
+        * @param nodeIter
+        * @return HashMap<String, PageData>
+        * @throws Exception 
+        */
+       public HashMap<String, PageData> convertNodeIteratorToPageDataMap(NodeIterator nodeIter) throws Exception {
+        HashMap<String, PageData> pageDataMap = new HashMap<String, PageData>();
+        while(nodeIter.hasNext() == true) {
+               Node     node     = nodeIter.nextNode();
+               Version  baseVersion = getBaseVersion(node);
+               PageData pageData = new PageData(node);
+
+               pageData.setBaseVersion(baseVersion);
+               pageDataMap.put(node.getProperty(Property.JCR_UUID).getString(), pageData);
+        }        
+               
+        return pageDataMap;
+       }
+
+       /**
+        * NamespaceList getter
+        * @return Value[]
+        * @throws Exception
+        */
+       public Value[] getNamespaceList() throws Exception {
+               Node namespace      = session_.getNode("/" + NODE_WIKIROOT + "/" + NODE_NAMESPACE);
+               
+               return namespace.getProperty(PROPERTY_NAMESPACE).getValues();
+       }
+       
+       /**
+        * Checkout
+        * @param pageData
+        * @throws Exception
+        */
+       public void checkout(PageData pageData) throws Exception {
+               Node node = pageData.getNode();
+               if(node != null) {
+                       session_.refresh(false);
+                       
+                       Workspace      workspace = session_.getWorkspace();
+                       VersionManager versionMgr = workspace.getVersionManager();
+                       versionMgr.checkout(node.getPath());
+               }
+       }
+
+       /**
+        * Checkin.
+        * @param pageData
+        * @throws Exception
+        */
+       public PageData checkin(PageData pageData) throws Exception {
+               Workspace      workspace  = session_.getWorkspace();
+               VersionManager versionMgr = workspace.getVersionManager();
+               Node           node       = pageData.getNode();
+
+               if(node == null) {
+                       node = addPageNode(pageData);
+                       session_.save();                        
+                       versionMgr.checkout(node.getPath());
+               }
+               else {
+                       String uuid = node.getProperty(Property.JCR_UUID).getString();
+
+                       node = transformPageDataToNode(pageData, session_.getNodeByIdentifier(uuid));
+                       session_.save();
+               }
+               
+               versionMgr.checkin(node.getPath());
+               createCategoryPages(node);
+               
+               String uuid = node.getProperty(Property.JCR_UUID).getString();
+               
+               return new PageData(session_.getNodeByIdentifier(uuid));
+       }
+
+       /**
+        * Cancel checkout
+        * @param pageData
+        * @throws Exception
+        */
+       public void cancelCheckout(PageData pageData) throws Exception {
+               Node node = pageData.getNode();
+               if(node != null) {
+                       Workspace      workspace  = session_.getWorkspace();
+                       VersionManager versionMgr = workspace.getVersionManager();
+                       String         path       = node.getPath();
+                       if(versionMgr.isCheckedOut(path) == true) {
+                               versionMgr.restore(versionMgr.getBaseVersion(path), true);
+                       }
+               }
+       }
+
+       /**
+        * Delete page node.
+        * @param pageData
+        * @throws Exception
+        */
+       public void deletePage(PageData pageData) throws Exception {
+               pageData.getNode().remove();
+               session_.save();                        
+       }
+
+       /**
+        * Refresh session.
+        * @throws RepositoryException 
+        */
+       public void refreshSession() throws RepositoryException {
+               session_.refresh(false);
+       }
+       
+       /**
+        * Set SystemProperties. 
+        * @throws Exception
+        */
+       private void setSystemProperties() throws Exception {
+               SettingManager settingMgr = SettingManager.getInstance();
+
+               String macAddress = getMacAddress();
+               String username   = System.getProperty("user.name");
+               String approot    = settingMgr.get(SettingManager.SETTINGSKEY_WIKIROOT);
+               String partyName  = settingMgr.getSelectedParty();
+
+               System.setProperty("cluster.id", String.valueOf(macAddress.hashCode() 
+                               + "-" + partyName
+                               + "-" + username));
+               System.setProperty("wiki.root", approot);
+
+               if(settingMgr.get(SettingManager.SETINGKEY_CLUSTER).equals("true")) {
+                       System.setProperty("party.name", partyName);
+                       System.setProperty("cluster.setting", "TRUE");
+                       System.setProperty("dbserver.url", settingMgr.get(SettingManager.SETINGKEY_DBSERVER_URL));
+                       System.setProperty("dbserver.port", settingMgr.get(SettingManager.SETINGKEY_DBSERVER_PORT));
+                       System.setProperty("jdbc.driver", settingMgr.get(SettingManager.SETINGKEY_JDBC_DRIVER));
+               }
+               else {
+                       System.setProperty("cluster.setting", "FALSE");
+                       System.setProperty("dbserver.url", "");
+                       System.setProperty("dbserver.port", "");                        
+                       System.setProperty("jdbc.driver", "");
+               }
+       }
+
+       /**
+        * Mac Address getter.
+        * @return
+        * @throws Exception
+        */
+       private String getMacAddress() throws Exception {
+               StringBuffer                  buf     = new StringBuffer();
+               Enumeration<NetworkInterface> nicList = NetworkInterface.getNetworkInterfaces();
+       
+               while(nicList.hasMoreElements() == true) {
+                       NetworkInterface nic = nicList.nextElement();
+                       if(nic.getName().equals("lo") != true) {
+                               byte[] macAddress = nic.getHardwareAddress();
+                               if(macAddress != null) {
+                                       for(byte b: macAddress) {
+                                               buf.append(String.format("%02X-", b));
+                                       }
+                                       break;
+                               }
+                       }
+               }
+               
+               return buf.toString();
+       }
+
+       /**
+        * 
+        * @param node
+        * @throws Exception 
+        */
+       private void createCategoryPages(Node node) throws Exception {
+               Workspace      workspace  = session_.getWorkspace();
+               VersionManager versionMgr = workspace.getVersionManager();
+               Value[]        categories = node.getProperty(PROPERTY_category).getValues();
+
+               for(Value category: categories) {
+                       String                    title = category.getString();
+
+                       if(title.isEmpty() != true) {
+                               HashMap<String, PageData> map   = queryPageTitle(title, PROPERTY_CATEGORY);
+                               
+                               if(map.size() == 0) {
+                                       /*
+                                        * category pageが未作成の場合、
+                                        */
+                                       PageData pageData = new PageData();
+                                       pageData.setNamespace(PROPERTY_CATEGORY);
+                                       pageData.setTitle(title);
+       
+                                       Node categoryNode = addPageNode(pageData);
+                                       session_.save();
+                                       versionMgr.checkout(categoryNode.getPath());
+                                       versionMgr.checkin(categoryNode.getPath());                             
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Test namespace is contains namespaceList.
+        * @param namespace
+        * @return boolean
+        * @throws Exception
+        */
+       public boolean isContainsNamespaceList(String namespace) throws Exception {
+        Node root          = session_.getRootNode();
+        Node wikiroot      = root.getNode(NODE_WIKIROOT);
+        Node namespaceNode = wikiroot.getNode(NODE_NAMESPACE);
+
+        Value[] list       = namespaceNode.getProperty(PROPERTY_NAMESPACE).getValues();
+        boolean isContains = false;
+
+        for(Value entry: list) {
+               if(entry.getString().equals(namespace) == true) {
+                       isContains = true;
+                       break;
+               }
+        }
+        
+        return isContains;
+       }
+
+       /**
+        * Version history getter.
+        * @param uuid
+        * @return VersionIterator
+        * @throws Exception
+        */
+       public VersionIterator getVersionHistory(String uuid) throws Exception {
+               HashMap<String, PageData> nodeMap  =  queryPageUUID(uuid);
+               PageData                  pageData = nodeMap.values().iterator().next();
+               Node                      node     = pageData.getNode();
+
+               Workspace      workspace      = session_.getWorkspace();
+               VersionManager versionMgr     = workspace.getVersionManager();
+               VersionHistory versionHistory = versionMgr.getVersionHistory(node.getPath());
+               
+               return versionHistory.getAllVersions();
+       }
+
+       /**
+        * Base version getter.
+        * @param node
+        * @return Version
+        * @throws Exception
+        */
+       public Version getBaseVersion(Node node) throws Exception {
+               Workspace      workspace      = session_.getWorkspace();
+               VersionManager versionMgr     = workspace.getVersionManager();
+               
+               return versionMgr.getBaseVersion(node.getPath());
+       }
+       
+       /**
+        * Restore version.
+        * @param version
+        * @param node
+        * @throws Exception
+        */
+       public void restoreVersion(Version version, Node node) throws Exception {
+               Workspace      workspace      = session_.getWorkspace();
+               VersionManager versionMgr     = workspace.getVersionManager();
+
+               versionMgr.restore(version, true);
+       }
+       
+       /**
+        * Import system view.
+        * @param outputFile
+        * @throws Exception
+        */
+       public void importSystemView(File outputFile) throws Exception {
+               FileInputStream inStream = new FileInputStream(outputFile);
+
+               try {
+               Node root      = session_.getRootNode();
+               Node wikiroot  = root.getNode(NODE_WIKIROOT);
+               Node pagesNode = wikiroot.getNode(NODE_PAGES);
+       
+               session_.importXML(pagesNode.getPath(), inStream, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
+               session_.save();
+
+               Node    namespaceNode = wikiroot.getNode(NODE_NAMESPACE);
+               Value[] namespaces    = namespaceNode.getProperty(PROPERTY_NAMESPACE).getValues();
+               
+               for(Value namespace: namespaces) {
+                       HashMap<String,PageData> map = queryPageNamespace(namespace.getString());
+                       Iterator<PageData>       iter = map.values().iterator();
+                       while(iter.hasNext() == true) {
+                               PageData pageData = iter.next();
+                               checkout(pageData);
+                               checkin(pageData);
+                       }
+               }
+               } finally {
+                       inStream.close();
+               }
+       }
+
+       /**
+        * Export system view.
+        * @param outputFile
+        * @throws Exception
+        */
+       public void exportSystemView(File outputFile) throws Exception {
+               FileOutputStream outStream = new FileOutputStream(outputFile);
+
+               try {
+               Node root      = session_.getRootNode();
+               Node wikiroot  = root.getNode(NODE_WIKIROOT);
+               Node pagesNode = wikiroot.getNode(NODE_PAGES);
+       
+               session_.exportSystemView(pagesNode.getPath(), outStream, false, false);
+               } finally {
+                       outStream.close();
+               }
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/application.css b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/application.css
new file mode 100644 (file)
index 0000000..674c89d
--- /dev/null
@@ -0,0 +1,60 @@
+/* JavaFX CSS - Leave this comment until you have at least create one rule which uses -fx-Property */
+.rootAnchorPane {
+       -fx-background-color: white;
+}
+
+.webViewMenuAnchorPane {
+    -fx-border-color: #c0c0c0;
+    -fx-border-style:solid;
+    -fx-border-width:1px;
+    -fx-background-color: #f5f5f5;
+}
+
+.webViewMainAnchorPane {
+       -fx-border-color:#c0c0c0;
+    -fx-border-style:solid;
+    -fx-border-width:0px 1px 1px 1px;
+    -fx-background-color: #f5f5f5;
+}
+
+.webViewGapspace {
+       -fx-border-color:#c0c0c0;
+    -fx-border-style:solid;
+    -fx-border-width:0px 0px 1px 0px;
+    -fx-background-color: transparent;
+}
+.webViewHistoryContentAnchorPane {
+       -fx-border-color:#c0c0c0;
+    -fx-border-style:solid;
+    -fx-border-width:1px;
+    -fx-background-color: #f8f8ff;
+}
+
+.selectPartyRadioButtonTableCell {
+       -fx-pref-width: 80;
+       -fx-alignment:center;
+}
+
+#webViewMainHyperlinkActive {
+    -fx-background-color: #f5f5f5;
+    -fx-border-color: #c0c0c0;
+    -fx-border-width:1px 1px 0px 1px;
+    -fx-border-style: solid;
+}
+
+#webViewMainHyperlinkInactive {
+    -fx-background-color: #e0e0e0;
+    -fx-border-color: #c0c0c0;
+    -fx-border-width:1px 1px 1px 1px;
+    -fx-border-style: solid;
+}
+
+#webViewBreadcrumbs {  
+       -fx-alignment: center-left;
+       -fx-padding: 0.0 2.0 0.0 2.0;
+}
+
+#webViewHistoryBaseVersion {
+       -fx-font-weight: bold;
+       -fx-text-fill: crimson;
+}
\ No newline at end of file
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AboutMoxkiriyaDialog.fxml b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AboutMoxkiriyaDialog.fxml
new file mode 100644 (file)
index 0000000..9459d87
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import java.util.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.paint.*?>
+<?scenebuilder-preview-i18n-resource ../resources/moxkiriya.properties?>
+
+<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.wiki.standalone.moxkiriya.dialog.AboutMoxkiriyaDialogController">
+  <children>
+    <Button fx:id="buttonOK" layoutX="250.0" layoutY="358.0" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" onAction="#onActionButtonOK" prefHeight="30.0" prefWidth="100.0" text="%key.Button.OK" />
+    <Label prefHeight="30.0" prefWidth="480.0" text="%key.About.Moxkiriya" AnchorPane.leftAnchor="50.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="30.0" />
+    <Label prefHeight="30.0" prefWidth="500.0" text="%key.About.Moxkiriya.Copyright" AnchorPane.leftAnchor="80.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="55.0" />
+    <Label prefHeight="30.0" prefWidth="500.0" text="%key.About.Moxkiriya.License" AnchorPane.leftAnchor="80.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="80.0" />
+    <Label maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="30.0" prefWidth="480.0" text="%key.About.Moxkiriya.Other.info" AnchorPane.leftAnchor="50.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="230.0" />
+    <Label maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="30.0" prefWidth="500.0" text="%key.About.Moxkiriya.Powered.Apache.Lucene" AnchorPane.leftAnchor="80.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="255.0" />
+    <Label prefHeight="30.0" prefWidth="500.0" text="%key.About.Moxkiriya.System.requirement" AnchorPane.leftAnchor="50.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="130.0" />
+    <Label prefHeight="30.0" prefWidth="500.0" text="%key.About.Moxkiriya.System.requirement.Java" AnchorPane.leftAnchor="80.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="155.0" />
+    <Label maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="30.0" prefWidth="500.0" text="%key.About.Moxkiriya.Lucene.license" AnchorPane.leftAnchor="80.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="285.0" />
+  </children>
+</AnchorPane>
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AboutMoxkiriyaDialog.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AboutMoxkiriyaDialog.java
new file mode 100644 (file)
index 0000000..157d0df
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * About Moxkiriya Dialog.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.dialog;
+
+/**
+ * About Moxkiriyaダイアログを表示する。
+ */
+public class AboutMoxkiriyaDialog extends DialogBase {
+
+       @Override
+       protected String getFXML() {
+               return "AboutMoxkiriyaDialog.fxml";
+       }
+
+       @Override
+       protected DialogController getController() throws Exception {
+               AboutMoxkiriyaDialogController controller = loader_.getController();
+               
+               return controller;
+       }
+
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AboutMoxkiriyaDialogController.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AboutMoxkiriyaDialogController.java
new file mode 100644 (file)
index 0000000..0be5394
--- /dev/null
@@ -0,0 +1,25 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * About Moxkiriya Dialog Controller.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.dialog;
+
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+
+/**
+ * About Moxkiriyaダイアログのコントローラ。
+ */
+public class AboutMoxkiriyaDialogController extends DialogControllerBase {
+       @FXML private Button buttonOK;
+
+       @FXML
+       void onActionButtonOK(ActionEvent event) {
+               ((Node)event.getSource()).getScene().getWindow().hide();
+       }       
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AlertDialog.fxml b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AlertDialog.fxml
new file mode 100644 (file)
index 0000000..d4571e2
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import java.util.*?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.image.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.paint.*?>
+<?import javafx.scene.text.*?>
+<?scenebuilder-preview-i18n-resource ../resources/moxkiriya.properties?>
+
+<GridPane hgap="14.0" maxHeight="+Infinity" maxWidth="+Infinity" minHeight="-Infinity" minWidth="-Infinity" vgap="20.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.wiki.standalone.moxkiriya.dialog.AlertDialogController">
+  <children>
+    <ImageView fx:id="ImageViewIcon" fitHeight="60.0" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.rowIndex="0" GridPane.valignment="TOP" />
+    <VBox maxHeight="+Infinity" maxWidth="+Infinity" minHeight="-Infinity" prefWidth="400.0" spacing="7.0" GridPane.columnIndex="1" GridPane.rowIndex="0">
+      <children>
+        <Label id="messageLabel" fx:id="labelMessage" text="" textAlignment="LEFT" wrapText="true">
+          <font>
+            <Font name="System Bold" size="13.0" />
+          </font>
+        </Label>
+        <Label id="detailsLabel" fx:id="labelDetails" text="" textAlignment="LEFT" wrapText="true">
+          <font>
+            <Font size="12.0" />
+          </font>
+        </Label>
+      </children>
+    </VBox>
+    <HBox maxHeight="-Infinity" maxWidth="+Infinity" minHeight="-Infinity" minWidth="-Infinity" GridPane.columnIndex="1" GridPane.rowIndex="1">
+      <children>
+        <HBox id="HBox" fx:id="actionParent" alignment="CENTER">
+          <HBox.margin>
+            <Insets />
+          </HBox.margin>
+        </HBox>
+        <Pane maxWidth="+Infinity" HBox.hgrow="ALWAYS" />
+        <Button id="cancelButton" fx:id="buttonCancel" cancelButton="true" minWidth="80.0" mnemonicParsing="false" onAction="#onActionButtonCancel" text="%key.Button.Cancel" HBox.hgrow="NEVER">
+          <HBox.margin>
+            <Insets />
+          </HBox.margin>
+        </Button>
+        <HBox id="HBox" fx:id="okParent" alignment="CENTER">
+          <children>
+            <Button id="okButton" fx:id="buttonOK" minWidth="80.0" mnemonicParsing="false" onAction="#onActionButtonOK" text="%key.Button.OK" HBox.hgrow="NEVER">
+              <HBox.margin>
+                <Insets left="14.0" />
+              </HBox.margin>
+            </Button>
+          </children>
+        </HBox>
+      </children>
+    </HBox>
+  </children>
+  <columnConstraints>
+    <ColumnConstraints hgrow="NEVER" maxWidth="-Infinity" minWidth="-Infinity" />
+    <ColumnConstraints halignment="CENTER" hgrow="ALWAYS" maxWidth="+Infinity" minWidth="-Infinity" />
+  </columnConstraints>
+  <padding>
+    <Insets bottom="14.0" left="14.0" right="14.0" top="14.0" />
+  </padding>
+  <rowConstraints>
+    <RowConstraints maxHeight="+Infinity" minHeight="-Infinity" valignment="CENTER" vgrow="ALWAYS" />
+    <RowConstraints maxHeight="-Infinity" minHeight="-Infinity" vgrow="NEVER" />
+  </rowConstraints>
+</GridPane>
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AlertDialog.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AlertDialog.java
new file mode 100644 (file)
index 0000000..b68c85b
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ * AlertDialog
+ * @author Ryuhei Terada
+ */
+package com.wiki.standalone.moxkiriya.dialog;
+
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+
+/**
+ * AlertDialog
+ *
+ */
+public class AlertDialog extends DialogBase {
+       /**
+        * Message種別列挙定数
+        */
+       public enum MessageType {
+               ConfirmEditCancel,      // 編集キャンセル確認ダイアログ   
+               AlertTitleEmpty,        // Title未入力警告ダイアログ
+               SuccessImport,          // Import成功情報ダイアログ
+               FailureImport,          // Import失敗情報ダイアログ
+               SuccessExport,          // Export成功情報ダイアログ
+               FailureExport,          // Export失敗情報ダイアログ
+       };
+       
+       /**
+        * Dialog種別列挙定数
+        */
+       public enum DialogType {
+               Error,  // エラーダイアログ
+               Alert,  // 警告ダイアログ
+               Info,   // 情報ダイアログ
+               Confirm // 確認ダイアログ
+       };
+
+       /**
+        * Button種別列挙定数
+        */
+       public enum ButtoType {
+               OK,
+               CANCEL_OK
+       }
+       
+       /**
+        * メッセージタイプ
+        */
+       private MessageType msgType_;
+
+
+       /**
+        * コンストラクタ
+        * @param msgType
+        */
+       public AlertDialog(MessageType msgType) {
+               msgType_ = msgType;
+               Stage       stage       = new Stage(StageStyle.UTILITY);
+               stage.initOwner(parentStage_);
+               stage.initModality(Modality.WINDOW_MODAL);
+       }
+       
+       @Override
+       protected String getFXML() {
+               return "AlertDialog.fxml";
+       }
+
+       @Override
+       protected DialogController getController() throws Exception {
+               AlertDialogController controller = loader_.getController();
+               controller.setMessageType(msgType_);
+               
+               return controller;
+       }
+
+       @Override
+       protected CloseType getCloseType() {
+               return ((AlertDialogController)controller_).getCloseType();
+       }
+}
\ No newline at end of file
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AlertDialogController.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/AlertDialogController.java
new file mode 100644 (file)
index 0000000..59f0072
--- /dev/null
@@ -0,0 +1,160 @@
+package com.wiki.standalone.moxkiriya.dialog;
+
+import java.net.MalformedURLException;
+import java.util.LinkedHashMap;
+
+import com.wiki.standalone.moxkiriya.ResourceManager;
+
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+
+public class AlertDialogController extends DialogControllerBase {
+       @FXML
+       private ImageView ImageViewIcon;
+
+       @FXML
+       private Label labelMessage;
+       
+       @FXML
+       private Label labelDetails;
+       
+       @FXML
+       private Button buttonCancel;
+
+       /**
+        * 終了種別
+        */
+       private AlertDialog.CloseType closeType_; 
+
+       /**
+        * Dialogに表示するicon, メッセージ, 詳細を設定する。
+        */
+       static class DialogProperty {
+               /**
+                * Constructor
+                * @param messageResourceKey
+                * @param detailResourceKey
+                * @param dialogType
+                */
+               DialogProperty(String messageResourceKey, String detailResourceKey, AlertDialog.DialogType dialogType) {
+                       this(messageResourceKey, detailResourceKey, dialogType, AlertDialog.ButtoType.CANCEL_OK);
+               };
+
+               /**
+                * Constructor.
+                * @param messageResourceKey
+                * @param detailResourceKey
+                * @param dialogType
+                * @param buttonType
+                */
+               DialogProperty(String messageResourceKey, String detailResourceKey, AlertDialog.DialogType dialogType, AlertDialog.ButtoType buttonType) {
+                       messageResourceKey_ = messageResourceKey;
+                       detailResourceKey_  = detailResourceKey;
+                       dialogType_         = dialogType;
+                       buttonType_         = buttonType;
+               };
+
+               String                 messageResourceKey_;
+               String                 detailResourceKey_;
+               AlertDialog.DialogType dialogType_;
+               AlertDialog.ButtoType  buttonType_;
+       };
+       
+       /**
+        * MessageType/DialogPropertyテーブル
+        */
+       private final static LinkedHashMap<AlertDialog.MessageType, DialogProperty> dialogPropertyTable
+               = new LinkedHashMap<AlertDialog.MessageType, DialogProperty>() {
+                       private static final long serialVersionUID = 1L;
+
+               {
+                       put(AlertDialog.MessageType.ConfirmEditCancel,
+                               new DialogProperty("key.Dialog.Message.Cancel.Editing",
+                                               "key.Dialog.Detail.Cancel.Editing",
+                                               AlertDialog.DialogType.Confirm));
+                       put(AlertDialog.MessageType.AlertTitleEmpty,
+                                       new DialogProperty("key.Dialog.Message.Empty.Title",
+                                                       "key.Dialog.Detail.Input.Title",
+                                                       AlertDialog.DialogType.Alert,
+                                                       AlertDialog.ButtoType.OK));
+                       put(AlertDialog.MessageType.SuccessImport,
+                                       new DialogProperty("key.Dialog.Import.Result.Title",
+                                                       "key.Dialog.Detail.Import.Success",
+                                                       AlertDialog.DialogType.Info,
+                                                       AlertDialog.ButtoType.OK));
+                       put(AlertDialog.MessageType.FailureImport,
+                                       new DialogProperty("key.Dialog.Import.Result.Title",
+                                                       "key.Dialog.Detail.Import.Failure",
+                                                       AlertDialog.DialogType.Error,
+                                                       AlertDialog.ButtoType.OK));
+                       put(AlertDialog.MessageType.SuccessExport,
+                                       new DialogProperty("key.Dialog.Export.Result.Title",
+                                                       "key.Dialog.Detail.Export.Success",
+                                                       AlertDialog.DialogType.Info,
+                                                       AlertDialog.ButtoType.OK));
+                       put(AlertDialog.MessageType.FailureExport,
+                                       new DialogProperty("key.Dialog.Export.Result.Title",
+                                                       "key.Dialog.Detail.Export.Failure",
+                                                       AlertDialog.DialogType.Error,
+                                                       AlertDialog.ButtoType.OK));
+               }
+       };
+
+       /**
+        * MessageTypeを設定する。
+        * @param msgType
+        * @throws MalformedURLException 
+        */
+       public void setMessageType(AlertDialog.MessageType msgType) throws MalformedURLException {
+               DialogProperty dialogProperty = dialogPropertyTable.get(msgType);
+
+               if(dialogProperty != null) {
+                       /*
+                        * メッセージ、詳細情報を設定する。
+                        */
+                       labelMessage.setText(resource_.getString(dialogProperty.messageResourceKey_));
+                       labelDetails.setText(resource_.getString(dialogProperty.detailResourceKey_));
+       
+                       /*
+                        * アイコンを設定する。
+                        */
+                       Image  image = ResourceManager.IconTable.get(dialogProperty.dialogType_);
+                       ImageViewIcon.setImage(image);
+                       
+                       /*
+                        * ボタンを設定する。
+                        */
+                       if(dialogProperty.buttonType_ == AlertDialog.ButtoType.OK) {
+                               buttonCancel.setVisible(false);
+                       }
+                       else {
+                               buttonCancel.setVisible(true);
+                       }
+               }
+       }
+
+       /**
+        * 終了種別を取得する。
+        * @param closeType
+        */
+       public AlertDialog.CloseType getCloseType() {
+               return closeType_;
+       }
+
+       @FXML
+       public void onActionButtonOK(ActionEvent event) {
+               closeType_ = AlertDialog.CloseType.OK;
+               ((Node)event.getSource()).getScene().getWindow().hide();
+       }
+
+       @FXML
+       public void onActionButtonCancel(ActionEvent event) {
+               closeType_ = AlertDialog.CloseType.Cancel;
+               ((Node)event.getSource()).getScene().getWindow().hide();
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/ConfigSettingsDialog.fxml b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/ConfigSettingsDialog.fxml
new file mode 100644 (file)
index 0000000..288d6e6
--- /dev/null
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import java.util.*?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.paint.*?>
+<?scenebuilder-preview-i18n-resource ../resources/moxkiriya.properties?>
+
+<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="339.0" prefWidth="690.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.wiki.standalone.moxkiriya.dialog.ConfigSettingsDialogController">
+  <children>
+    <Label prefHeight="30.0" prefWidth="574.0" text="%key.Config.Setting.Dialog.Message" AnchorPane.leftAnchor="25.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="15.0" />
+    <Button id="ButtonOK" fx:id="buttonOK" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" onAction="#onActionButtonOK" prefHeight="30.0" prefWidth="100.0" text="%key.Button.OK" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="87.0" />
+    <GridPane prefHeight="144.0" prefWidth="505.0" AnchorPane.bottomAnchor="40.0" AnchorPane.leftAnchor="45.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="46.0">
+      <children>
+        <Label prefHeight="28.0" prefWidth="197.0" text="%key.Config.Setting.Approot" GridPane.columnIndex="0" GridPane.rowIndex="2">
+          <GridPane.margin>
+            <Insets left="20.0" fx:id="x1" />
+          </GridPane.margin>
+        </Label>
+        <TextField id="TextFieldWikiroot" fx:id="textFieldApproot" disable="false" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="30.0" prefWidth="384.0" promptText="%key.Config.Setting.Approot.textField.prompt" text="" GridPane.columnIndex="1" GridPane.rowIndex="2" />
+        <Button id="ButtonChooseDirectory" fx:id="buttonChooseDirectory" maxHeight="-Infinity" maxWidth="-1.0" minWidth="27.0" mnemonicParsing="false" onAction="#onActionButtonChooseDirectory" prefHeight="25.0" prefWidth="30.0" text="..." GridPane.columnIndex="2" GridPane.rowIndex="2" />
+        <Label prefHeight="30.0" prefWidth="197.0" text="%key.Config.Setting.Cluster.setting" GridPane.columnIndex="0" GridPane.margin="$x1" GridPane.rowIndex="3" />
+        <CheckBox fx:id="checkBoxClusterSetting" mnemonicParsing="false" prefHeight="30.0" prefWidth="384.0" text="" GridPane.columnIndex="1" GridPane.rowIndex="3" />
+        <Label prefHeight="30.0" prefWidth="177.0" text="%key.Config.Setting.DBServer.URL" GridPane.columnIndex="0" GridPane.rowIndex="4">
+          <GridPane.margin>
+            <Insets left="40.0" fx:id="x2" />
+          </GridPane.margin>
+        </Label>
+        <TextField fx:id="textFieldDBServerURL" disable="true" prefHeight="28.0" prefWidth="325.0" promptText="%key.Config.Setting.DBServer.URL.textField.prompt" GridPane.columnIndex="1" GridPane.rowIndex="4" />
+        <Label prefHeight="30.0" prefWidth="177.0" text="%key.Config.Setting.DBServer.port" GridPane.columnIndex="0" GridPane.margin="$x2" GridPane.rowIndex="5" />
+        <TextField fx:id="textFieldPortNumber" disable="true" prefHeight="30.0" prefWidth="271.0" promptText="%key.Config.Setting.DBServer.port.textField.prompt" GridPane.columnIndex="1" GridPane.rowIndex="5" />
+        <Label prefHeight="30.0" prefWidth="177.0" text="%key.Config.Setting.DBServer.JDBC.Driver" GridPane.columnIndex="0" GridPane.margin="$x2" GridPane.rowIndex="6" />
+        <TextField fx:id="textFieldJDBCDriver" disable="true" prefHeight="30.0" prefWidth="271.0" promptText="%key.Config.Setting.DBServer.JDBC.Driver.textField.prompt" text="" GridPane.columnIndex="1" GridPane.rowIndex="6" />
+        <Label prefHeight="28.0" prefWidth="227.0" text="%key.Config.Setting.Party.name" GridPane.columnIndex="0" GridPane.rowIndex="0" />
+        <Label prefHeight="24.999900000002526" prefWidth="227.0" text="%key.Config.Setting.Party.Default.check" GridPane.columnIndex="0" GridPane.rowIndex="1">
+          <GridPane.margin>
+            <Insets left="20.0" fx:id="x1" />
+          </GridPane.margin>
+        </Label>
+        <TextField id="textFieldDivisionName" fx:id="textFieldPartyName" prefHeight="30.0" prefWidth="384.0" promptText="%key.Config.Setting.Party.textField.prompt" text="" GridPane.columnIndex="1" GridPane.rowIndex="0" />
+        <CheckBox fx:id="checkBoxDefaultParty" mnemonicParsing="false" prefHeight="30.0" prefWidth="384.0" text="" GridPane.columnIndex="1" GridPane.rowIndex="1" />
+      </children>
+      <columnConstraints>
+        <ColumnConstraints hgrow="SOMETIMES" maxWidth="270.0" minWidth="10.0" prefWidth="197.0" />
+        <ColumnConstraints hgrow="SOMETIMES" maxWidth="444.0" minWidth="10.0" prefWidth="271.0" />
+        <ColumnConstraints hgrow="SOMETIMES" maxWidth="444.0" minWidth="10.0" prefWidth="37.0" />
+      </columnConstraints>
+      <rowConstraints>
+        <RowConstraints maxHeight="31.0" minHeight="10.0" prefHeight="31.0" vgrow="SOMETIMES" />
+        <RowConstraints maxHeight="31.0" minHeight="10.0" prefHeight="31.0" vgrow="SOMETIMES" />
+        <RowConstraints maxHeight="31.0" minHeight="10.0" prefHeight="31.0" vgrow="SOMETIMES" />
+        <RowConstraints maxHeight="31.0" minHeight="10.0" prefHeight="31.0" vgrow="SOMETIMES" />
+        <RowConstraints maxHeight="30.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints maxHeight="30.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+        <RowConstraints maxHeight="30.0" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
+      </rowConstraints>
+    </GridPane>
+  </children>
+</AnchorPane>
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/ConfigSettingsDialog.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/ConfigSettingsDialog.java
new file mode 100644 (file)
index 0000000..2cf67d4
--- /dev/null
@@ -0,0 +1,88 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * ConfigSettingsDialog.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.dialog;
+
+import java.util.Hashtable;
+
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+
+/**
+ * ConfigSettingsDialog
+ */
+public class ConfigSettingsDialog extends DialogBase {
+       /** target party name. */
+       private String partyName_;
+
+       /**
+        * Constructor.
+        */
+       public ConfigSettingsDialog() {
+               this(null);
+       }
+
+       /**
+        * Constructor.
+        * @param partyName
+        */
+       public ConfigSettingsDialog(String partyName) {
+               super();
+               partyName_ = partyName;
+       }
+       
+       @Override
+       protected String getFXML() {
+               return "ConfigSettingsDialog.fxml";
+       }
+
+       @Override
+       protected DialogController getController() {
+               ConfigSettingsDialogController controller = loader_.getController();
+               controller.setWindow(scene_.getWindow());
+               controller.setPartyName(partyName_);
+               return controller;
+       }
+
+       @Override
+       protected CloseType show() {
+               Stage stage = new Stage();
+
+               stage.initOwner(parentStage_);
+               stage.initModality(Modality.APPLICATION_MODAL);
+               stage.setScene(scene_);
+               stage.setResizable(false);
+               stage.showAndWait();
+
+               return getCloseType();          
+       }
+
+       /**
+        * Settings table getter.
+        * @return Hashtable<String, String>
+        */
+       public Hashtable<String, String> getSettingsTable() {
+               return ((ConfigSettingsDialogController)controller_).getSettingsTable();
+       }
+
+       /**
+        * Default party checkbox value getter.
+        * @return boolean
+        */
+       public boolean getDefaultPartyCheckValue() {
+               return ((ConfigSettingsDialogController)controller_).getDefaultPartyCheckValue();
+       }
+
+       /**
+        * Party name getter.
+        * @return String
+        */
+       public String getPartyName() {
+               return ((ConfigSettingsDialogController)controller_).getPartyName();
+       }
+
+}
\ No newline at end of file
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/ConfigSettingsDialogController.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/ConfigSettingsDialogController.java
new file mode 100644 (file)
index 0000000..2009ec1
--- /dev/null
@@ -0,0 +1,276 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * ConfigSettingsDialogController.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */package com.wiki.standalone.moxkiriya.dialog;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Hashtable;
+import java.util.ResourceBundle;
+
+import com.wiki.standalone.moxkiriya.SettingManager;
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.TextField;
+import javafx.stage.DirectoryChooser;
+import javafx.stage.Window;
+
+/**
+ * ConfigSettingダイアログコントローラ
+ */
+public class ConfigSettingsDialogController extends DialogControllerBase {
+       @FXML   private TextField textFieldPartyName;
+       @FXML   private CheckBox  checkBoxDefaultParty;
+       @FXML   private TextField textFieldApproot;
+       @FXML   private Button    buttonChooseDirectory;
+       @FXML   private CheckBox  checkBoxClusterSetting;
+       @FXML   private TextField textFieldDBServerURL;
+       @FXML   private TextField textFieldPortNumber;
+       @FXML   private TextField textFieldJDBCDriver;
+       @FXML   private Button    buttonOK;
+
+       /** parent window */
+       private Window parentWindow_;
+
+       /** party name specified parent window. */
+       private String partyName_;
+       
+       /** setting map */
+       private Hashtable<String, String> settingsTable_;
+
+       /**
+        * 親Windowを設定する。
+        * @param window
+        */
+       public void setWindow(Window window) {
+               parentWindow_ = window;
+       }
+
+       /**
+        * Party name setter.
+        * @param partyName
+        */
+       public void setPartyName(String partyName) {
+               partyName_ = partyName;
+
+               if( (partyName_ != null)
+                && (partyName_.isEmpty() != true)) {
+                       SettingManager settingMgr = SettingManager.getInstance();
+                       String         path       = settingMgr.get(SettingManager.SETTINGSKEY_MOXKIRIYA_USER_DIR);
+                       try {
+                               settingsTable_ = settingMgr.loadConfigSettings(path, partyName_);
+                               textFieldPartyName.setText(partyName_);
+                               if( (partyName_ != null)
+                                && (partyName_.isEmpty() != true)) {
+                                       textFieldPartyName.setEditable(false);
+                                       textFieldPartyName.setDisable(true);
+                               }
+                               Hashtable<String, Boolean> partyTable = settingMgr.getPartyTable();
+                               if(partyTable.get(partyName_) == true) {
+                                       checkBoxDefaultParty.setSelected(true);
+                               }
+       
+                               String text = settingsTable_.get(SettingManager.SETINGKEY_MOXKIRIYAROOT);
+
+                               textFieldApproot.setText(text == null ? "" : text);
+                               String clusterSetting = settingsTable_.get(SettingManager.SETINGKEY_CLUSTER);
+                               if( (clusterSetting != null)
+                                && (clusterSetting.equals("true"))) {
+                                       checkBoxClusterSetting.setSelected(true);
+                                       
+                                       text = settingsTable_.get(SettingManager.SETINGKEY_DBSERVER_URL);
+                                       textFieldDBServerURL.setText(text == null ? "" : text);
+                                       
+                                       text = settingsTable_.get(SettingManager.SETINGKEY_DBSERVER_PORT);
+                                       textFieldPortNumber.setText(text == null ? "" : text);
+
+                                       text = settingsTable_.get(SettingManager.SETINGKEY_JDBC_DRIVER);
+                                       textFieldJDBCDriver.setText(text == null ? "" : text);
+                               }
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+       }
+       
+       @Override
+       public void initialize(URL url, ResourceBundle resource) {
+               super.initialize(url, resource);
+               buttonOK.setDisable(true);
+               
+               ChangeListener<String> textFieldchangeListener = new ChangeListener<String>() {
+                       @Override
+                       public void changed(ObservableValue<? extends String> arg0, String oldValue, String newValue) {
+                               buttonOK.setDisable(canEnableOKButton());
+                       }
+               };
+               textFieldPartyName.textProperty().addListener(textFieldchangeListener);
+               textFieldApproot.textProperty().addListener(textFieldchangeListener);
+               textFieldDBServerURL.textProperty().addListener(textFieldchangeListener);
+               textFieldPortNumber.textProperty().addListener(textFieldchangeListener);
+               textFieldJDBCDriver.textProperty().addListener(textFieldchangeListener);
+
+               checkBoxClusterSetting.selectedProperty().addListener(new ChangeListener<Boolean>() {
+                       @Override
+                       public void changed(ObservableValue<? extends Boolean> value, Boolean oldValue, Boolean newValue) {
+                               if(newValue == true) {
+                                       textFieldDBServerURL.setDisable(false);
+                                       textFieldPortNumber.setDisable(false);
+                                       textFieldJDBCDriver.setDisable(false);
+                               }
+                               else {
+                                       textFieldDBServerURL.setDisable(true);
+                                       textFieldPortNumber.setDisable(true);
+                                       textFieldJDBCDriver.setDisable(true);
+                               }
+                               buttonOK.setDisable(canEnableOKButton());
+                       }                       
+               });
+
+       }
+       
+       @FXML
+       void onActionButtonChooseDirectory(ActionEvent event) {
+               DirectoryChooser directoryChooser = new DirectoryChooser();
+               String home = SettingManager.getInstance().get(SettingManager.SETTINGSKEY_USER_HOME);
+
+               directoryChooser.setInitialDirectory(new File(home));
+               File choicedDirectory = directoryChooser.showDialog(parentWindow_);
+               
+               if ((choicedDirectory.exists() == true)
+                && (choicedDirectory.isDirectory() == true)) {
+                       textFieldApproot.setText(choicedDirectory.getPath());
+                       buttonOK.setDisable(false);
+               }
+       }
+
+       @FXML
+       void onActionButtonOK(ActionEvent event) {
+               try {
+                       if(partyName_ == null) {
+                               SettingManager settingMgr    = SettingManager.getInstance();
+                               String         selectedParty = textFieldPartyName.getText();
+                               String         moxkiriyaRoot = textFieldApproot.getText();
+       
+                               settingMgr.putParty(selectedParty, checkBoxDefaultParty.isSelected());
+                               settingMgr.setSelectedParty(selectedParty);
+                               
+                               settingMgr.put(SettingManager.SETINGKEY_MOXKIRIYAROOT, moxkiriyaRoot);
+                               settingMgr.put(SettingManager.SETTINGSKEY_WIKIROOT,
+                                               moxkiriyaRoot
+                                               + "/"
+                                               + WikiEngine.WIKIROOT_DIRECTORY);
+               
+                               File wikiroot = new File(settingMgr.get(SettingManager.SETTINGSKEY_WIKIROOT));
+                               if(wikiroot.exists() != true) {
+                                       wikiroot.mkdirs();
+                               }
+                               if(checkBoxClusterSetting.selectedProperty().get() == true) {
+                                       settingMgr.put(SettingManager.SETINGKEY_CLUSTER, "true");
+                                       settingMgr.put(SettingManager.SETINGKEY_DBSERVER_URL, textFieldDBServerURL.getText());
+                                       settingMgr.put(SettingManager.SETINGKEY_DBSERVER_PORT, textFieldPortNumber.getText());
+                                       settingMgr.put(SettingManager.SETINGKEY_JDBC_DRIVER, textFieldJDBCDriver.getText());
+                               }
+                               else {
+                                       settingMgr.put(SettingManager.SETINGKEY_CLUSTER, "false");
+                                       settingMgr.put(SettingManager.SETINGKEY_DBSERVER_URL, "");
+                                       settingMgr.put(SettingManager.SETINGKEY_DBSERVER_PORT, "");
+                                       settingMgr.put(SettingManager.SETINGKEY_JDBC_DRIVER, "");
+                               }
+                               settingMgr.save();
+                               settingMgr.putParty(selectedParty, true);       
+                       }
+                       ((Node)event.getSource()).getScene().getWindow().hide();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * Judge whether OK button can enable or not.
+        * @return
+        */
+       private boolean canEnableOKButton() {
+               boolean isDisable = textFieldPartyName.getText().isEmpty();
+               
+               if(isDisable == false) {
+                       String text = textFieldApproot.getText();
+                       isDisable = (text == null) || (text.isEmpty() == true);
+               }
+
+               if(checkBoxClusterSetting.selectedProperty().getValue() == true) {
+                       if(isDisable == false) {
+                               String text = textFieldDBServerURL.getText();
+                               isDisable = (text == null) || (text.isEmpty() == true);
+                       }
+                       
+                       if(isDisable == false) {
+                               String text = textFieldPortNumber.getText();
+                               isDisable = (text == null) || (text.isEmpty() == true);
+                       }
+                       
+                       if(isDisable == false) {
+                               String text = textFieldJDBCDriver.getText();
+                               isDisable = (text == null) || (text.isEmpty() == true);
+                       }
+               }
+               
+               return isDisable;
+       }
+
+       /**
+        * Settings table getter.
+        * @return Hashtable<String, String>
+        */
+       public Hashtable<String, String> getSettingsTable() {
+               Hashtable<String, String> settingsTable = new Hashtable<String, String>();              
+               String                    moxkiriyaRoot = textFieldApproot.getText();
+
+               settingsTable.put(SettingManager.SETINGKEY_MOXKIRIYAROOT, moxkiriyaRoot);
+               settingsTable.put(SettingManager.SETTINGSKEY_WIKIROOT,
+                               moxkiriyaRoot
+                               + "/"
+                               + WikiEngine.WIKIROOT_DIRECTORY);
+
+               if(checkBoxClusterSetting.selectedProperty().get() == true) {
+                       settingsTable.put(SettingManager.SETINGKEY_CLUSTER, "true");
+                       settingsTable.put(SettingManager.SETINGKEY_DBSERVER_URL, textFieldDBServerURL.getText());
+                       settingsTable.put(SettingManager.SETINGKEY_DBSERVER_PORT, textFieldPortNumber.getText());
+                       settingsTable.put(SettingManager.SETINGKEY_JDBC_DRIVER, textFieldJDBCDriver.getText());
+               }
+               else {
+                       settingsTable.put(SettingManager.SETINGKEY_CLUSTER, "false");
+                       settingsTable.put(SettingManager.SETINGKEY_DBSERVER_URL, "");
+                       settingsTable.put(SettingManager.SETINGKEY_DBSERVER_PORT, "");
+                       settingsTable.put(SettingManager.SETINGKEY_JDBC_DRIVER, "");
+               }
+               
+               return settingsTable;
+       }
+
+       /**
+        * Default party checkbox value getter.
+        * @return boolean
+        */
+       public boolean getDefaultPartyCheckValue() {
+               return checkBoxDefaultParty.isSelected();
+       }
+
+       /**
+        * Party name getter.
+        * @return String
+        */
+       public String getPartyName() {
+               return textFieldPartyName.getText();
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/DialogBase.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/DialogBase.java
new file mode 100644 (file)
index 0000000..0593598
--- /dev/null
@@ -0,0 +1,124 @@
+/**
+ * ダイアログ基本クラス
+ * @author Ryuhei Terada
+ */
+
+package com.wiki.standalone.moxkiriya.dialog;
+
+import java.io.IOException;
+import java.util.ResourceBundle;
+
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+
+/**
+ * DialogBase
+ *
+ */
+public abstract class DialogBase {
+       /**
+        * リソースバンドル
+        */
+       protected ResourceBundle resource_;
+
+       /**
+        * FXMLローダー
+        */
+       protected FXMLLoader     loader_;
+
+       /**
+        * 親Windowのstage
+        */
+       protected Stage          parentStage_;
+
+       /**
+        * My stage.
+        */
+       protected Stage          stage_;
+       /**
+        * シーン
+        */
+       Scene scene_;
+
+       /**
+        * Dialogコントローラ
+        */
+       DialogController controller_;
+       
+       /**
+        * Dialogの終了種別列挙定数
+        */
+       public enum CloseType {
+               OK,
+               Cancel
+       };
+
+       /**
+        * ダイアログを表示する
+        * @param stage
+        * @param resouces
+        * @throws Exception 
+        */
+       public CloseType showDialog(Stage stage, ResourceBundle resource) throws Exception {
+               parentStage_ = stage;
+               resource_    = resource;
+               loader_      = FXMLLoad();
+               scene_       = new Scene((Parent)loader_.getRoot());
+               controller_  = getController();
+               scene_.getStylesheets().add(getClass().getResource("dialog.css").toExternalForm());
+
+               return show();
+       }
+
+       /**
+        * FXMLをロードする。
+        * return FXMLLoader
+        * @throws IOException 
+        */
+       protected FXMLLoader FXMLLoad() throws IOException {
+               FXMLLoader loader = new FXMLLoader(getClass().getResource(getFXML()), resource_);
+               loader.load();
+               
+               return loader;
+       }
+       
+       /**
+        * Dialogのクローズ種別を取得する。
+        * @return CloseType
+        */
+       protected CloseType getCloseType() {
+               return CloseType.OK;
+       }
+       
+       /**
+        * FXMLファイル名を取得する。
+        * @return String FXMLファイル名 
+        */
+       protected abstract String getFXML();
+
+       /**
+        * コントローラを取得する。
+        * @return Initializable
+        * @throws Exception 
+        */
+       protected abstract DialogController getController() throws Exception;
+
+       /**
+        * ダイアログをj表示する。
+        * @return CloseTypeダイアログの終了種別
+        */
+       protected CloseType show() {
+               stage_ = new Stage();
+               
+               stage_.initOwner(parentStage_);
+               stage_.initModality(Modality.APPLICATION_MODAL);
+               stage_.setScene(scene_);
+               stage_.setResizable(false);
+               stage_.showAndWait();
+
+               return getCloseType();          
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/DialogController.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/DialogController.java
new file mode 100644 (file)
index 0000000..7a308b4
--- /dev/null
@@ -0,0 +1,18 @@
+/**
+ * DialogController
+ * @author Ryuhei Terada
+ */
+package com.wiki.standalone.moxkiriya.dialog;
+
+import javafx.fxml.Initializable;
+
+/**
+ * DialogController
+ */
+public interface DialogController extends Initializable {      
+       /**
+        * 終了種別を取得する。
+        * @param closeType
+        */
+       public DialogBase.CloseType getCloseType();
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/DialogControllerBase.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/DialogControllerBase.java
new file mode 100644 (file)
index 0000000..bbee8a1
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * DialogControllerベースクラス
+ * @author Ryuhei Terada
+ */
+package com.wiki.standalone.moxkiriya.dialog;
+
+import java.net.URL;
+import java.util.ResourceBundle;
+
+
+/**
+ * DialogControllerBase
+ */
+public abstract class DialogControllerBase implements DialogController {
+       /** URL */
+       URL url_;
+       
+       /** Resource Bundle */
+       protected ResourceBundle resource_;
+
+       @Override
+       public void initialize(URL url, ResourceBundle resource) {
+               url_      = url;
+               resource_ = resource;
+       }
+
+       /**
+        * 終了種別を取得する。
+        * @param closeType
+        */
+       public DialogBase.CloseType getCloseType() {
+               return DialogBase.CloseType.OK;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/PageList.fxml b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/PageList.fxml
new file mode 100644 (file)
index 0000000..45d0f5a
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import java.util.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.paint.*?>
+
+<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
+  <children>
+    <Label prefHeight="30.0" prefWidth="600.0" text="Label" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
+    <TreeView prefHeight="370.0" prefWidth="500.0" AnchorPane.bottomAnchor="40.0" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="30.0" />
+  </children>
+</AnchorPane>
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/SelectPartyDialog.fxml b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/SelectPartyDialog.fxml
new file mode 100644 (file)
index 0000000..99db903
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import java.util.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.paint.*?>
+<?scenebuilder-preview-i18n-resource ../resources/moxkiriya.properties?>
+
+<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.wiki.standalone.moxkiriya.dialog.SelectPartyDialogController">
+  <children>
+    <Label maxHeight="-Infinity" prefHeight="30.0" text="%key.Config.Select.Party.Dialog.Message" AnchorPane.leftAnchor="40.0" AnchorPane.topAnchor="35.0" />
+    <TableView fx:id="tableViewPartyList" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="270.0" prefWidth="520.0" AnchorPane.bottomAnchor="65.0" AnchorPane.leftAnchor="40.0" AnchorPane.rightAnchor="40.0" AnchorPane.topAnchor="65.0">
+      <columns>
+        <TableColumn id="selectPartyRadioButtonTableCell" prefWidth="80.0" resizable="false" sortable="false" text="%key.Config.Select.Party.Select" fx:id="tableColumnSelect" />
+        <TableColumn maxWidth="520.0" minWidth="439.0" prefWidth="520.0" resizable="false" text="%key.Config.Select.Party.name" fx:id="tableColumnPartyName" />
+      </columns>
+    </TableView>
+    <Button fx:id="buttonOK" mnemonicParsing="false" onAction="#onActionButtonOK" prefHeight="30.0" prefWidth="100.0" text="%key.Button.OK" AnchorPane.bottomAnchor="15.0" AnchorPane.rightAnchor="40.0" />
+    <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#onActionButtonCancel" prefHeight="30.0" prefWidth="100.0" text="%key.Button.Cancel" AnchorPane.bottomAnchor="15.0" AnchorPane.rightAnchor="150.0" />
+    <Button fx:id="buttonAddNewParty" mnemonicParsing="false" onAction="#onActionButtonAddNewParty" prefHeight="30.0" prefWidth="120.0" text="%key.Button.Add.Party" AnchorPane.bottomAnchor="15.0" AnchorPane.leftAnchor="40.0" />
+  </children>
+</AnchorPane>
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/SelectPartyDialog.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/SelectPartyDialog.java
new file mode 100644 (file)
index 0000000..aa156b5
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Select party dialog.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.dialog;
+
+/**
+ * SelectPartyDialog
+ */
+public class SelectPartyDialog extends DialogBase {
+
+       /**
+        * Constructor.
+        */
+       public SelectPartyDialog() {
+       }
+       
+       @Override
+       protected String getFXML() {
+               return "SelectPartyDialog.fxml";
+       }
+
+       @Override
+       protected DialogController getController() {
+               SelectPartyDialogController controller = loader_.getController();
+
+               controller.setStage(parentStage_);
+
+               return controller;
+       }
+
+       @Override
+       protected CloseType getCloseType() {
+               return controller_.getCloseType();
+       }
+}
\ No newline at end of file
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/SelectPartyDialogController.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/SelectPartyDialogController.java
new file mode 100644 (file)
index 0000000..4ac8e97
--- /dev/null
@@ -0,0 +1,314 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Select party dialog controller.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */package com.wiki.standalone.moxkiriya.dialog;
+
+import java.net.URL;
+import java.util.Hashtable;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+import com.wiki.standalone.moxkiriya.SettingManager;
+
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.Hyperlink;
+import javafx.scene.control.RadioButton;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.ToggleGroup;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.stage.Stage;
+import javafx.util.Callback;
+
+/**
+ * SelectPartyダイアログコントローラ
+ */
+public class SelectPartyDialogController extends DialogControllerBase {
+       /**
+        * Party property.
+        */
+       public class PartyProperty {
+               /** Select status. */
+               private SimpleBooleanProperty select_;
+
+               /** Party name. */
+               private SimpleStringProperty partyName_;
+               
+               /**
+                * Constructor.
+                * @param aSelect
+                * @param aPartyName
+                */
+               public PartyProperty(boolean aSelect, String aPartyName) {
+                       select_    = new SimpleBooleanProperty(aSelect);
+                       partyName_ = new SimpleStringProperty(aPartyName);                      
+               }
+
+               /**
+                * Select property getter.
+                * @return BooleanProperty
+                */
+               public BooleanProperty selectProperty() {
+                       return select_;
+               }
+
+               /**
+                * Party name getter.
+                * @return StringProperty
+                */
+               public StringProperty partyNameProperty() {
+                       return partyName_;
+               }
+       }
+       
+       @FXML   private TableView<PartyProperty>             tableViewPartyList;
+       @FXML   private TableColumn<PartyProperty, Boolean>  tableColumnSelect;
+       @FXML   private TableColumn<PartyProperty, String>   tableColumnPartyName;
+       @FXML   private Button                               buttonCancel;
+       @FXML   private Button                               buttonOK;
+       @FXML   private Button                               buttonAddNewParty;
+
+       /** Selected party name. */
+       private String selectedParty_;
+
+       /** ToggleGroup for select RadioButton. */
+       private ToggleGroup toggleGroupSelect_;
+
+       /** Close type. */
+       private DialogBase.CloseType closeType_;
+
+       /** My stage */
+       private Stage          stage_;
+       
+       @Override
+       public void initialize(URL url, ResourceBundle resource) {
+               super.initialize(url, resource);
+
+               buttonOK.setDisable(true);
+
+               toggleGroupSelect_  = new ToggleGroup();
+
+               setCellFactory(tableColumnSelect, toggleGroupSelect_, new EventHandler<ActionEvent>() {
+                       @Override
+                       public void handle(ActionEvent event) {
+                               RadioButton   target        = (RadioButton)event.getTarget();
+                               PartyProperty partyProperty = (PartyProperty)target.getUserData();
+
+                               if(target.isSelected() == true) {
+                                       buttonOK.setDisable(false);
+                                       
+                                       selectedParty_ = partyProperty.partyNameProperty().getValue();
+                               }
+                       }                       
+               });
+
+               setCellFactory(tableColumnPartyName, new EventHandler<ActionEvent>() {
+                       @Override
+                       public void handle(ActionEvent event) {
+                               Hyperlink     target        = (Hyperlink)event.getTarget();
+                               PartyProperty partyProperty = (PartyProperty)target.getUserData();
+                               String        partyName     = partyProperty.partyName_.get();
+                               
+                               try {
+                                       if(showConfigSettingsDialog(stage_, partyName) == DialogBase.CloseType.OK) {
+                                               SettingManager settingMgr = SettingManager.getInstance();
+                                               String         path       = settingMgr.get(SettingManager.SETTINGSKEY_MOXKIRIYA_USER_DIR);
+                                               settingMgr.loadSettingFiles(path);
+                                       }
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                               }
+                       }                       
+               });
+
+               buildTableViewPartyList();
+
+               SettingManager settingMgr   = SettingManager.getInstance();
+               String         defaultParty = settingMgr.getSelectedParty();
+
+               if(defaultParty != null) {
+                       buttonCancel.setDisable(false);
+               }
+       }
+
+       /**
+        * Stage setter.
+        * @param stage
+        */
+       public void setStage(Stage stage) {
+               stage_ = stage;
+       }
+
+       /**
+        * 終了種別を取得する。
+        * @param closeType
+        */
+       public DialogBase.CloseType getCloseType() {
+               return closeType_;
+       }
+
+       @FXML
+       public void onActionButtonCancel(ActionEvent event) {
+               closeType_ = DialogBase.CloseType.Cancel;
+               ((Node)event.getSource()).getScene().getWindow().hide();
+       }
+
+       @FXML
+       public void onActionButtonOK(ActionEvent event) {
+               try {
+                       SettingManager                settingMgr     = SettingManager.getInstance();
+                       settingMgr.setSelectedParty(selectedParty_);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+               
+               closeType_ = DialogBase.CloseType.OK;
+               ((Node)event.getSource()).getScene().getWindow().hide();
+       }
+
+       @FXML
+       public void onActionButtonAddNewParty(ActionEvent event) {
+               try {
+                       showConfigSettingsDialog(stage_, null);
+
+                       SettingManager                settingMgr     = SettingManager.getInstance();
+                       Hashtable<String, Boolean>    partyTable     = settingMgr.getPartyTable();
+                       Set<String>                   keys           = partyTable.keySet();
+                       ObservableList<PartyProperty> observableList = FXCollections.observableArrayList();
+
+                       for(String key: keys) {
+                               boolean       isDefault     = partyTable.get(key);
+                               PartyProperty partyProperty = new PartyProperty(isDefault, key);
+                               observableList.add(partyProperty);
+                       }
+                       tableViewPartyList.getItems().clear();
+                       tableViewPartyList.setItems(observableList);            
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * Cell factory setter.
+        * @param tableColumn
+        * @param toggleGroup
+        */
+       private void setCellFactory(TableColumn<PartyProperty, Boolean> tableColumn, final ToggleGroup toggleGroup, final EventHandler<ActionEvent> eventHandler) {
+               tableColumn.setCellFactory(new Callback<TableColumn<PartyProperty, Boolean>, TableCell<PartyProperty, Boolean>>() {
+                       @Override
+                       public TableCell<PartyProperty, Boolean> call(TableColumn<PartyProperty, Boolean> param) {
+                               TableCell<PartyProperty, Boolean> tableCell = new TableCell<PartyProperty, Boolean>() {
+                                       @Override
+                                       public void updateItem(Boolean select, boolean empty) {
+                                               super.updateItem(select, empty);
+                                               if(empty != true) {
+                                                       RadioButton radioButton = new RadioButton();
+
+                                                       radioButton.setOnAction(eventHandler);
+                                                       radioButton.setToggleGroup(toggleGroup);
+                                                       setGraphic(radioButton);
+
+                                                       int                           index = getIndex();
+                                                       ObservableList<PartyProperty> items = getTableView().getItems();
+                                                       radioButton.setUserData(items.get(index));
+                                               }
+                                       }
+                               };
+                               tableCell.setId("selectPartyRadioButtonTableCell");
+                               
+                               return tableCell;
+                       }
+               });
+       }
+       
+       /**
+        * Cell factory setter.
+        * @param tableColumn
+        */
+       private void setCellFactory(TableColumn<PartyProperty, String> tableColumn, final EventHandler<ActionEvent> eventHandler) {
+               tableColumn.setCellFactory(new Callback<TableColumn<PartyProperty, String>, TableCell<PartyProperty, String>>() {
+                       @Override
+                       public TableCell<PartyProperty, String> call(TableColumn<PartyProperty, String> param) {
+                               TableCell<PartyProperty, String> tableCell = new TableCell<PartyProperty, String>() {
+                                       @Override
+                                       public void updateItem(String partyName, boolean empty) {
+                                               super.updateItem(partyName, empty);
+                                               if(empty != true) {
+                                                       Hyperlink hyperlink = new Hyperlink(partyName);
+                                                       
+                                                       hyperlink.setOnAction(eventHandler);
+                                                       setGraphic(hyperlink);
+
+                                                       int                           index = getIndex();
+                                                       ObservableList<PartyProperty> items = getTableView().getItems();
+                                                       hyperlink.setUserData(items.get(index));
+                                               }
+                                       }
+                               };
+                               
+                               return tableCell;
+                       }
+               });
+       }
+
+       /**
+        * Build party list TableView
+        */
+       private void buildTableViewPartyList() {
+               tableColumnSelect.setCellValueFactory(new PropertyValueFactory<PartyProperty, Boolean>("select"));
+               tableColumnPartyName.setCellValueFactory(new PropertyValueFactory<PartyProperty, String>("partyName"));
+               
+               SettingManager                settingMgr     = SettingManager.getInstance();
+               Hashtable<String, Boolean>    partyTable     = settingMgr.getPartyTable();
+               Set<String>                   keys           = partyTable.keySet();
+               ObservableList<PartyProperty> observableList = FXCollections.observableArrayList();
+
+               for(String key: keys) {
+                       boolean       isDefault     = partyTable.get(key);
+                       PartyProperty partyProperty = new PartyProperty(isDefault, key);
+                       observableList.add(partyProperty);
+               }
+               tableViewPartyList.setItems(observableList);
+       }
+
+       /**
+        * WikiConfigSettingDialogを表示する。
+        * @param primaryStage
+        * @param selectedParty
+        * @return DialogBase.CloseType
+        * @throws Exception 
+        */
+       private DialogBase.CloseType showConfigSettingsDialog(Stage stage, String partyName) throws Exception {
+               SettingManager settingMgr_ = SettingManager.getInstance();
+               
+               ConfigSettingsDialog dialog = new ConfigSettingsDialog(partyName);
+               
+               DialogBase.CloseType closeType = dialog.showDialog(stage, resource_);
+               if(closeType == DialogBase.CloseType.OK) {
+
+                       Hashtable<String, String> settingsTable = dialog.getSettingsTable();
+                       String                    path          = settingMgr_.get(SettingManager.SETTINGSKEY_MOXKIRIYA_USER_DIR);
+
+                       partyName = dialog.getPartyName();
+                       settingMgr_.putParty(partyName, dialog.getDefaultPartyCheckValue());
+                       settingMgr_.savePartyConfig(path);
+                       settingMgr_.saveSettingConfig(path, partyName, settingsTable);                  
+               }
+               
+               return closeType;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/dialog.css b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/dialog/dialog.css
new file mode 100644 (file)
index 0000000..7c4f4a2
--- /dev/null
@@ -0,0 +1,5 @@
+/* JavaFX CSS - Leave this comment until you have at least create one rule which uses -fx-Property */
+#selectPartyRadioButtonTableCell {
+       -fx-pref-width: 80;
+       -fx-alignment: center;
+}
\ No newline at end of file
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockParser.java
new file mode 100644 (file)
index 0000000..68f6820
--- /dev/null
@@ -0,0 +1,54 @@
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+
+public interface WikiBlockParser {
+       /** parse状態 */
+       public enum Status {
+               INIT,
+               OPEN,
+               NESTING,
+               CLOSE
+       };
+
+       /**
+        * Block要素開始処理。
+        * @param buf バッファ
+        * @return 処理後の文字列
+        */
+       public String startElementProcess(String line, StringBuffer buf);
+
+       /**
+        * WikiのSyntaxを解析し、HTML形式の文字列に変換する。
+        * @param line readerから読み込んだ最初の行
+        * @param buf バッファ
+        * @return 処理後の文字列
+        */
+       public String parse(String line, StringBuffer buf) throws Exception;
+
+       /**
+        * Block要素終了処理。
+        * @param buf
+        * @return 処理後の文字列
+        */
+       public String endElementProcess(String line, StringBuffer buf);
+
+       /**
+        * ネスト要素のcloseをヘルプする。
+        * 先祖の要素に<code>があった場合、ネスト要素を&lt;要素&gt;にするため。
+        * @param tagPart
+        * @return 処理したクローズタグ文字列
+        */
+       public String daughterElementCloseHelper(String tagPart);
+
+               /**
+        * 要素Block終了判定
+        * @return 終了判定結果
+        */
+       public boolean isBlockEnd();
+
+       /**
+        * 処理中の1行のうち処理した文字数を取得する。
+        * @return 処理した文字数
+        */
+       public int getCount();
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockParserBase.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockParserBase.java
new file mode 100644 (file)
index 0000000..e381365
--- /dev/null
@@ -0,0 +1,150 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Base class of Blocklevel element parser, processor.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+import com.wiki.standalone.moxkiriya.parser.inlineparser.WikiInlineParser;
+import com.wiki.standalone.moxkiriya.parser.inlineparser.WikiInlineParserCreator;
+
+public abstract class WikiBlockParserBase implements WikiBlockParser {
+       /** Wiki engine */
+       WikiEngine wikiEngine_;
+       
+       /**     ブロック終了状態 */
+       protected boolean isBlockEnd_ = false;
+
+       /** 処理終了後の残り文字列 */
+       protected String  remain_ = "";
+
+       /** 処理した文字数 */
+       protected int     count_  = 0;
+
+       /** parse状態 */
+       protected Status status_;
+
+       /** インスタンス生成時のparse状態 */
+       protected Status initialStatus_;
+
+       /** ネスト元要素parser */
+       protected WikiBlockParser motherParser_;
+
+       /** ネスト要素parser */
+       protected WikiBlockParser daughterParser_;
+       
+       /**
+        * Constructor.
+        * @param wikiRepository
+        */
+       public WikiBlockParserBase(WikiEngine wikiEngine) {
+               isBlockEnd_     = false;
+               wikiEngine_ = wikiEngine;
+       }
+       
+       @Override
+       public String parse(String line, StringBuffer buf) throws Exception {
+               buf.append(inlineParse(line));
+               return "";
+       }
+
+       @Override
+       public String daughterElementCloseHelper(String tagPart) {
+               return tagPart;
+       }
+
+       @Override
+       public boolean isBlockEnd() {
+               return isBlockEnd_;
+       }
+
+       /**
+        * インライン要素を解析する。
+        * @param line
+        * @return インライン要素の解析結果
+        */
+       public String inlineParse(String line) {
+               return inlineParse(line, new WikiInlineParserCreator(wikiEngine_));
+       }
+
+       /**
+        * インライン要素を解析する。
+        * @param line
+        * @param creatorList
+        * @return インライン要素の解析結果
+        */
+       public String inlineParse(String line, WikiInlineParserCreator creator) {
+               StringBuffer buf        = new StringBuffer();
+               String       inlineHtml = line;
+
+               WikiInlineParserCreator inlineParserCreator = creator;
+               WikiInlineParser        inlineParser        = inlineParserCreator.create(line);
+
+               inlineHtml = inlineParser.parse(line);
+               buf.append(inlineHtml);
+
+               return buf.toString();
+       }
+
+       @Override
+       public int getCount() {
+               return count_;
+       }
+
+       /**
+        * ネストparser開始処理
+        * @param creator
+        * @param line
+        */
+       protected void startDaughterParse(WikiBlockParserCreator creator, String line) {
+               if(status_ == Status.INIT) {
+                       /*
+                        * インスタンス生成後初parse&初matchの場合
+                        */
+                       isBlockEnd_ = false;
+                       status_     = Status.OPEN;
+               }
+               else {
+                       status_        = Status.NESTING;
+                       daughterParser_ = creator.create(line);
+               }
+       }
+
+       /**
+        * ネストparser開始処理
+        * @param creator
+        */
+       protected void startDaughterParse(WikiBlockParserCreator.Creator creator) {
+               if(status_ == Status.INIT) {
+                       /*
+                        * インスタンス生成後初parse&初matchの場合
+                        */
+                       isBlockEnd_ = false;
+                       status_     = Status.OPEN;
+               }
+               else {
+                       status_         = Status.NESTING;
+                       daughterParser_ = creator.create(wikiEngine_);
+               }
+       }
+
+       /**
+        * lineの行頭からのtokenの数をカウントする。
+        * @param line
+        * @parma token
+        * @return 行頭からのtokenの数
+        */
+       public int countToken(String line, char token) {
+               int count = 0;
+               for(count = 0; count < line.length(); count++) {
+                       if(token != line.charAt(count)) {
+                               break;
+                       }
+               }
+               
+               return count;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockParserCreator.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockParserCreator.java
new file mode 100644 (file)
index 0000000..06d86b1
--- /dev/null
@@ -0,0 +1,127 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Blocklevel element parser, processor creator.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import java.util.LinkedHashMap;
+import java.util.Set;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+/**
+ * WikiBlockParserインスタンスを生成する。
+ *
+ */
+public class WikiBlockParserCreator {
+       /**     TOC構築クラス */
+       private WikiTOCBuilder wikiTOCBuilder_;
+       
+       /** Wiki engine */
+       private WikiEngine wikiEngine_;
+       
+       interface Creator {
+               public WikiBlockParser create(WikiEngine wikiEngine);
+       };
+       
+       /** WikiBlockParser Creator Table*/
+       private LinkedHashMap<String, Creator> creatorMap 
+               = new LinkedHashMap<String, Creator>() {
+
+               private static final long serialVersionUID = 1L;
+
+               {
+                       put(WikiHnBlockParser.NOTATION_REGEX, new Creator() {
+                               @Override 
+                               public WikiBlockParser create(WikiEngine wikiEngine) {
+                                       return new WikiHnBlockParser(wikiEngine, wikiTOCBuilder_);
+                               }
+                       } );
+                       put(WikiHrBlockParser.NOTATION_REGEX, new Creator() {
+                               @Override 
+                               public WikiBlockParser create(WikiEngine wikiEngine) {
+                                       return new WikiHrBlockParser(wikiEngine);
+                               }
+                       } );
+                       put(WikiTableBlockParser.NOTATION_REGEX, new Creator() {
+                               @Override 
+                               public WikiBlockParser create(WikiEngine wikiEngine) {
+                                       return new WikiTableBlockParser(wikiEngine);
+                               }
+                       } );
+                       put(WikiUnorderedListBlockParser.NOTATION_REGEX, new Creator() {
+                               @Override 
+                               public WikiBlockParser create(WikiEngine wikiEngine) {
+                                       return new WikiUnorderedListBlockParser(wikiEngine);
+                               }
+                       } );
+                       put(WikiOrderedListBlockParser.NOTATION_REGEX, new Creator() {
+                               @Override 
+                               public WikiBlockParser create(WikiEngine wikiEngine) {
+                                       return new WikiOrderedListBlockParser(wikiEngine);
+                               }
+                       } );
+                       put(WikiBlockquoteBlockParser.NOTATION_REGEX, new Creator() {
+                               @Override 
+                               public WikiBlockParser create(WikiEngine wikiEngine) {
+                                       return new WikiBlockquoteBlockParser(wikiEngine);
+                               }
+                       } );
+                       put(WikiPreBlockParser.NOTATION_REGEX, new Creator() {
+                               @Override 
+                               public WikiBlockParser create(WikiEngine wikiEngine) {
+                                       return new WikiPreBlockParser(wikiEngine);
+                               }
+                       } );
+                       put(WikiCodeBlockParser.NOTATION_REGEX, new Creator() {
+                               @Override 
+                               public WikiBlockParser create(WikiEngine wikiEngine) {
+                                       return new WikiCodeBlockParser(wikiEngine);
+                               }
+                       } );
+               }
+       };
+
+       /**
+        * Constructor
+        * @param wikiRepository
+        */
+       public WikiBlockParserCreator(WikiEngine wikiEngine) {
+               wikiTOCBuilder_ = new WikiTOCBuilder();
+               wikiEngine_ = wikiEngine;
+       }
+       
+       /**
+        * lineのSyntaxにマッチするWikiBlockParserのインスタンスを生成する。
+        * @param line
+        * @return WikiBlockParser
+        */
+       public WikiBlockParser create(String line) {
+               WikiBlockParser parser = null;
+               Set<String>     keySet = creatorMap.keySet();
+
+               for(String key: keySet) {
+                       if(line.toLowerCase().matches(key) == true) {
+                               parser = creatorMap.get(key).create(wikiEngine_);
+                               break;
+                       }
+               }
+               
+               if (parser == null) {
+                       parser = new WikiDefaultBlockParser(wikiEngine_);
+               }
+               
+               return parser;
+       }
+       
+       /** 
+        * TOC(目次)ノードを取得する
+        * @param firstLine
+        * @return
+        */
+       public String getTOC(String firstLine) {
+               return wikiTOCBuilder_.buildTOC(firstLine);
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockquoteBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBlockquoteBlockParser.java
new file mode 100644 (file)
index 0000000..7b733b0
--- /dev/null
@@ -0,0 +1,120 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Unordered list block parser.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+/**
+ * 番号なしリストのマークアップを解析し、HTML形式に変換する。
+ *
+ */
+public class WikiBlockquoteBlockParser extends WikiBlockParserBase {
+       private static final String START_TAG = "<blockquote";
+
+       private static final String END_TAG = "</blockquote>\n";
+       
+       /** WIKI記法の正規表現文字列 行頭パターン */
+       private static final String NOTATION_REGEX_LINEHEAD = "^>";
+
+       /** WIKI記法の正規表現文字列 行末パターン */
+       private static final String NOTATION_REGEX_LINETAIL = "";
+       
+       /** WIKI記法の正規表現文字列 */
+       public static final String NOTATION_REGEX = NOTATION_REGEX_LINEHEAD
+                       + "..*"
+                       + NOTATION_REGEX_LINETAIL;
+
+       /**     ブロック終了状態 */
+       private boolean isBlockEnd_ = false;
+
+       /** 処理終了後の残り文字列 */
+       private String  remain_;
+       
+       /** 
+        *  コンストラクタ
+        */
+       public WikiBlockquoteBlockParser(WikiEngine wikiEngine) {
+               this(wikiEngine, Status.INIT);
+       }
+
+       /** 
+        *  コンストラクタ
+        */
+       public WikiBlockquoteBlockParser(WikiEngine wikiEngine, Status status) {
+               super(wikiEngine);
+               status_ = status;
+       }
+       
+       @Override
+       public String startElementProcess(String line, StringBuffer buf) {
+               status_ = Status.OPEN;
+               buf.append(START_TAG + " class=\"quotation\">");
+               return line;
+       }
+
+       @Override
+       public String parse(String line, StringBuffer buf) throws Exception {
+               if(line.matches(NOTATION_REGEX) == true) {
+                       String token      = line.substring(line.indexOf(">"));
+                       int    countToken = countToken(token, '>');
+                       if(countToken > 1) {
+                               /*
+                                * '>'を一つ減らして子parserへ渡す。
+                                */
+                               String daughterPart = token.substring(1);
+                               
+                               if(status_ == Status.OPEN) {
+                                       startDaughterParse(new WikiBlockParserCreator.Creator() {
+                                               @Override
+                                               public WikiBlockquoteBlockParser create(WikiEngine wikiEngine) {
+                                                       return new WikiBlockquoteBlockParser(wikiEngine, Status.OPEN);
+                                               }
+                                       });
+                                       
+                                       daughterParser_.startElementProcess(daughterPart, buf);
+                               }
+                               daughterParser_.parse(daughterPart, buf);
+                       }
+                       else {
+                               if(status_ == Status.NESTING) {
+                                       /*
+                                        * トークンが1つでネスト処理中の場合、
+                                        * ネスト処理を終了する。
+                                        */
+                                       daughterParser_.endElementProcess(line, buf);
+                                       daughterParser_ = null;
+                                       status_ = Status.OPEN;
+                               }
+                               buf.append("<div>");
+                               super.parse(token.substring(countToken), buf);
+                               buf.append("</div>\n");
+                               remain_ = "";                           
+                       }
+               }
+               else {
+                       isBlockEnd_ = true;
+                       remain_     = line;
+               }
+
+               return "";
+       }
+
+       @Override
+       public String endElementProcess(String line, StringBuffer buf) {
+               if(status_ == Status.NESTING) {
+                       daughterParser_.endElementProcess(line, buf);
+               }
+               buf.append(END_TAG + "\n");
+               return remain_;
+       }
+
+       @Override
+       public boolean isBlockEnd() {
+               return isBlockEnd_;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBodyBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiBodyBlockParser.java
new file mode 100644 (file)
index 0000000..e061fa3
--- /dev/null
@@ -0,0 +1,213 @@
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import java.io.BufferedReader;
+import java.util.ArrayList;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiBodyBlockParser {
+       /** body要素開始タグ 文字列 */
+       private final String START_TAG = "<body>";
+       
+       /** body要素終了タグ 文字列 */
+       private final String END_TAG = "</body>";
+
+       /** Page titleのparse結果 */
+       private String titleHtml_;
+
+       /** BlockParserクリエイター */
+       WikiBlockParserCreator blockParserCreator_;
+
+       /** Pageの先頭行 */
+       private String firstLine_ = null;
+
+       /**
+        * Wikiマークアップで許可するHTML要素のリスト
+        */
+       private static final ArrayList<String> acceptElementList_ = new ArrayList<String>() {
+               private static final long serialVersionUID = 1L;
+               { add(WikiCodeBlockParser.NOTATION_REGEX_LINEHEAD); }
+               { add(WikiCodeBlockParser.NOTATION_REGEX_LINETAIL);}
+               { add(WikiPreBlockParser.NOTATION_REGEX_LINEHEAD); }
+               { add(WikiPreBlockParser.NOTATION_REGEX_LINETAIL);}
+       };
+
+       /** プリプロセッサ状態enum */
+       enum PreprocessStatus {
+               INIT,
+               OPEN,
+               CLOSE;
+       };
+
+       /** parse状態enum */
+       enum ParseStatus {
+               INIT,
+               OPEN,
+               CLOSE;
+       };
+
+       /**
+        * コンストラクタ
+        * @param wikiRepository
+        */
+       public WikiBodyBlockParser(WikiEngine wikiEngine) {
+               blockParserCreator_ = new WikiBlockParserCreator(wikiEngine);
+       }
+
+       /**
+        * Pageタイトルparse処理
+        * @param title
+        */
+       public void parsePageTitle(String title) {
+               titleHtml_ = "<h1>" + title + "</h1>\n";
+       } 
+       
+       public String parse(BufferedReader reader) throws Exception {
+               StringBuffer buf = new StringBuffer();
+
+               startElementProcess(buf);
+               buf.append(titleHtml_);
+               
+               String bodyBlock = parseCore(reader);
+
+               buf.append(blockParserCreator_.getTOC(firstLine_));
+               buf.append(bodyBlock);
+               endElementProcess(buf);
+               
+               return buf.toString();
+       }
+
+       /**
+        * Wikiマークアップで許可するHTML要素以外を無効化する
+        * @param line
+        * @return
+        */
+       private String parsePreprocess(String line) {
+               StringBuffer buf           = new StringBuffer("");
+               StringBuffer tagBuf        = null;
+               char[]       lineCharArray = line.toCharArray();
+
+               PreprocessStatus status    = PreprocessStatus.INIT;
+               for(int count = 0; count < lineCharArray.length; count++) {
+                       if(status == PreprocessStatus.INIT) {
+                               if(lineCharArray[count] == '<') {
+                                       status = PreprocessStatus.OPEN;
+                                       tagBuf = new StringBuffer();
+                                       tagBuf.append(lineCharArray[count]);
+                               }
+                               else {
+                                       buf.append(lineCharArray[count]);
+                               }
+                       }
+                       else if(status == PreprocessStatus.OPEN) {
+                               tagBuf.append(lineCharArray[count]);
+                               if(lineCharArray[count] == '>') {                                       
+                                       String tag = tagBuf.toString();
+                                       for(String accept: acceptElementList_) {
+                                               if(tag.toLowerCase().matches(accept)) {
+                                                       buf.append(tag);
+                                                       tagBuf = null;
+                                               }
+                                       }
+
+                                       if(tagBuf != null) {
+                                               /*
+                                                * acceptリストにないタグパターンの場合
+                                                */
+                                               buf.append(tag.replaceAll("<", "&lt;")
+                                                               .replaceAll(">", "&gt;"));
+                                               tagBuf = null;
+                                       }
+                                       status = PreprocessStatus.INIT;
+                               }
+                       }
+                       else {
+                               buf.append(lineCharArray[count]);
+                       }
+               }
+               
+               if(status == PreprocessStatus.OPEN) {
+                       String tag = tagBuf.toString();
+                       buf.append(tag.replaceAll("<", "&lt;"));
+               }
+
+               return buf.toString();
+       }
+       
+       /**
+        * parseコア処理
+        * @param reader
+        * @return htmlコンテンツ文字列
+        * @throws Exception
+        */
+       private String parseCore(BufferedReader reader) throws Exception {
+               StringBuffer buf    = new StringBuffer("");
+               StringBuffer paragraphBuf = null;
+               String       line   = null;
+               ParseStatus  status = ParseStatus.INIT;
+
+               WikiBlockParser        parser             = null;
+       
+               while((line = reader.readLine()) != null) {
+                       if(firstLine_ == null) {
+                               firstLine_ = line;
+                               if(firstLine_.equals("{{#TOC}}") == true) {
+                                       continue;
+                               } 
+                       }
+                       
+                       /*
+                        * XSS殺し
+                        */
+                       String processingline = parsePreprocess(line);
+                       
+                       do {
+                               if(status != ParseStatus.OPEN) {
+                                       status       = ParseStatus.OPEN;
+                                       paragraphBuf = new StringBuffer();
+                               }
+       
+                               if(parser == null) {
+                                       parser         = blockParserCreator_.create(processingline);
+                                       processingline = parser.startElementProcess(processingline, paragraphBuf);
+                               }
+
+                               processingline = parser.parse(processingline, paragraphBuf);
+       
+                               if(parser.isBlockEnd() == true) {
+                                       processingline = parser.endElementProcess(processingline, paragraphBuf);
+                                       parser = null;
+                                       
+                                       if(line.isEmpty() == true) {
+                                               buf.append("<p>\n");
+                                               buf.append(paragraphBuf + "\n");
+                                               buf.append("</p>\n");
+
+                                               status       = ParseStatus.CLOSE;
+                                               paragraphBuf = null;                                            
+                                       }
+                               }
+                       } while(processingline.isEmpty() != true);                      
+               }
+
+               if(status == ParseStatus.OPEN) {
+                       if(parser != null) {
+                               parser.endElementProcess(line, paragraphBuf);
+                       }
+                       buf.append("<p>\n");
+                       buf.append(paragraphBuf + "\n");
+                       buf.append("</p>\n");
+                       status = ParseStatus.CLOSE;
+               }
+
+               return buf.toString();
+       }
+       
+       public void startElementProcess(StringBuffer buf) {
+               buf.append(START_TAG + "\n");
+       }
+
+       public void endElementProcess(StringBuffer buf) {
+               buf.append(END_TAG + "\n");
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiCodeBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiCodeBlockParser.java
new file mode 100644 (file)
index 0000000..b810466
--- /dev/null
@@ -0,0 +1,159 @@
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+/**
+ * 
+ *
+ */
+public class WikiCodeBlockParser extends WikiBlockParserBase {
+       /** WIKI記法の正規表現文字列 行頭パターン */
+       public static final String NOTATION_REGEX_LINEHEAD = "<code[ \t]*>" + (".*");
+
+       /** WIKI記法の正規表現文字列 行末パターン */
+       public static final String NOTATION_REGEX_LINETAIL = "<*/[ \t]*code>" + ".*";
+       
+       /** WIKI記法の正規表現文字列 */
+       public static final String NOTATION_REGEX = ".*" + NOTATION_REGEX_LINEHEAD
+                       + ".*";
+
+       /** 
+        *  コンストラクタ
+        * @param file
+        */
+       public WikiCodeBlockParser(WikiEngine wikiEngine) {
+               this(wikiEngine, null, Status.INIT);
+       }
+
+       /**
+        * ネスト要素処理用コンストラクタ
+        * @param motherParser ネスト元要素parser
+        * @param file
+        * @param status
+        */
+       public WikiCodeBlockParser(WikiEngine wikiEngine, WikiBlockParser motherParser, Status status) {
+               super(wikiEngine);
+               motherParser_  = motherParser;
+               status_        = status;
+               initialStatus_ = status;
+       }
+       
+       @Override
+       public String startElementProcess(String line, StringBuffer buf) {
+               char[] charLine = line.toCharArray();
+               String previous = "";
+               String main     = "";
+
+               for(count_ = 0; count_ < charLine.length; count_++) {
+                       if(charLine[count_] == '<') {
+                               String now     = line.substring(count_);
+
+                               if(now.matches(WikiCodeBlockParser.NOTATION_REGEX_LINEHEAD) == true) {
+                                       previous = line.substring(0, line.indexOf(now));
+                                       main     = now;
+                                       break;
+                               }
+                       }
+               }
+               
+               if(previous.isEmpty() != true) {
+                       buf.append(inlineParse(previous));
+               }
+               
+               return main;
+       }
+
+       @Override
+       public String parse(String line, StringBuffer buf) throws Exception {
+               char[] charLine = line.toCharArray();
+
+               for(count_ = 0; count_ < charLine.length; count_++) {
+                       if(status_ == Status.NESTING) {
+                               String nestpart = new String(line.substring(count_));
+                               daughterParser_.parse(nestpart, buf);
+                               count_ += daughterParser_.getCount();
+
+                               if(daughterParser_.isBlockEnd() == true) {
+                                       daughterParser_.endElementProcess(null, buf);
+                                       status_        = Status.OPEN;
+                                       daughterParser_ = null;
+                               }
+                               continue;
+                       }
+
+                       if(charLine[count_] == '<') {
+                               String now      = line.substring(count_);
+                               String nowLower = now.toLowerCase();
+                               String tagpart  = now.substring(0, now.indexOf(">") + ">".length());
+
+                               if(nowLower.matches(WikiCodeBlockParser.NOTATION_REGEX_LINEHEAD) == true) {
+                                       count_ += tagpart.length() - 1;
+
+                                       if(status_ != Status.INIT) {
+                                               tagpart = tagpart.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
+                                       }
+                                       startDaughterParse(new WikiBlockParserCreator.Creator() {
+                                               @Override
+                                               public WikiCodeBlockParser create(WikiEngine wikiEngine) {
+                                                       return new WikiCodeBlockParser(wikiEngine, WikiCodeBlockParser.this, Status.OPEN);
+                                               }
+                                       });
+                                       buf.append(tagpart);
+                               }
+                               else if(nowLower.matches(NOTATION_REGEX_LINETAIL)) {
+                                       if(status_ == Status.NESTING) {
+                                               daughterParser_.parse(now, buf);
+                                               count_ += daughterParser_.getCount() - 1;
+
+                                               if(daughterParser_.isBlockEnd() == true) {
+                                                       status_        = Status.OPEN;
+                                                       daughterParser_ = null;
+                                               }
+                                       }
+                                       else {
+                                               remain_  = now.substring(now.indexOf(">") + ">".length());
+                                               count_  += tagpart.length() - 1;
+
+                                               if(initialStatus_ == Status.OPEN) {
+                                                       /*
+                                                        * nest要素のparserとしてインスタンス生成された場合、 
+                                                        */
+                                                       motherParser_.daughterElementCloseHelper(tagpart);
+                                               }
+                                               buf.append(tagpart);
+                                               isBlockEnd_ = true;
+                                               break;
+                                       }
+                               }
+                               else {
+                                       count_  += tagpart.length() - 1;
+                                       buf.append(tagpart.replaceAll("<", "&lt;").replaceAll(">", "&gt;"));
+                               }
+                       }
+                       else if(status_ == Status.OPEN) {
+                               buf.append(charLine[count_]);                           
+                       }
+               }
+               
+               if(initialStatus_ == Status.INIT) {
+                       buf.append("\n");
+               }
+
+               return "";
+       }
+
+       @Override
+       public String endElementProcess(String line, StringBuffer buf) {
+               return remain_;
+       }
+
+       @Override
+       public boolean isBlockEnd() {
+               return isBlockEnd_;
+       }
+       
+       @Override
+       public String daughterElementCloseHelper(String tagPart) {
+               return tagPart.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
+       }
+}
\ No newline at end of file
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiDefaultBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiDefaultBlockParser.java
new file mode 100644 (file)
index 0000000..9483ef0
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * 
+ */
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+/**
+ * Default block parser.
+ *
+ */
+public class WikiDefaultBlockParser extends WikiBlockParserBase {
+       /** 
+        *  コンストラクタ
+        * @param wikiRepository
+        */
+       public WikiDefaultBlockParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+       }       
+
+       @Override
+       public String startElementProcess(String line, StringBuffer buf) {
+               return line;
+       }
+
+       @Override
+       public String parse(String line, StringBuffer buf) throws Exception {
+               buf.append("<div>");
+               buf.append(inlineParse(line));
+               buf.append("</div>\n");
+               return "";
+       }
+
+       @Override
+       public String endElementProcess(String line, StringBuffer buf) {
+               return "";
+       }
+
+
+       @Override
+       public boolean isBlockEnd() {
+               return true;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiHnBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiHnBlockParser.java
new file mode 100644 (file)
index 0000000..3cd461d
--- /dev/null
@@ -0,0 +1,77 @@
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiHnBlockParser extends WikiBlockParserBase {
+       private static final String START_TAG = "<div><h%d ";
+
+       private static final String END_TAG = "</h%d></div>\n";
+       
+       /** WIKI記法の正規表現文字列 行頭パターン */
+       private static final String NOTATION_REGEX_LINEHEAD = "^==+";
+
+       /** WIKI記法の正規表現文字列 行末パターン */
+       private static final String NOTATION_REGEX_LINETAIL = "==+$";
+       
+       /** WIKI記法の正規表現文字列 */
+       public static final String NOTATION_REGEX = NOTATION_REGEX_LINEHEAD
+                       + "..*"
+                       + NOTATION_REGEX_LINETAIL;
+
+       /** 最大ヘッダレベル */
+       public static final int HEADERLEVEL_MAX = 6;
+
+       /** ヘッダレベル */
+       private int headerLevel_;
+
+       /** TOC(目次)構築クラス */
+       private WikiTOCBuilder wikiTOCBuilder_; 
+
+       /** 
+        *  コンストラクタ
+        */
+       public WikiHnBlockParser(WikiEngine wikiEngine, WikiTOCBuilder wikiTOCBuilder) {
+               super(wikiEngine);
+               wikiTOCBuilder_ = wikiTOCBuilder;
+       }
+
+       @Override
+       public String startElementProcess(String line, StringBuffer buf) {
+               int    startCount    = countToken(line, '=');
+               int    lastCount     = 0;
+               char[] lineCharArray = line.toCharArray();
+
+               for(lastCount = 0; lastCount < line.length(); lastCount++) {
+                       if(lineCharArray[lineCharArray.length - lastCount - 1] != '=') {
+                               break;
+                       }
+               }
+
+               headerLevel_ = Math.min(Math.min(startCount, lastCount), HEADERLEVEL_MAX); 
+               
+               buf.append(String.format(START_TAG, headerLevel_));
+               
+               StringBuffer replaceString = new StringBuffer();
+               for(int count = 0; count < headerLevel_; count++) {
+                       replaceString.append("=");
+               }
+
+               String headline = line.replaceFirst("^" + replaceString, "")
+                                                       .replaceFirst(replaceString + "$", "").trim();
+               buf.append("id=\"" + headline + "\">");
+               wikiTOCBuilder_.add(headline, headerLevel_);
+
+               return headline;
+       }
+
+       @Override
+       public String endElementProcess(String line, StringBuffer buf) {
+               buf.append(String.format(END_TAG, headerLevel_));
+               return "";
+       }
+
+       @Override
+       public boolean isBlockEnd() {
+               return true;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiHrBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiHrBlockParser.java
new file mode 100644 (file)
index 0000000..5295b06
--- /dev/null
@@ -0,0 +1,43 @@
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiHrBlockParser extends WikiBlockParserBase {
+       private static final String START_TAG = "<hr>";
+
+       private static final String END_TAG = "";
+       
+       /** WIKI記法の正規表現文字列 行頭パターン */
+       private static final String NOTATION_REGEX_LINEHEAD = "^----";
+
+       /** WIKI記法の正規表現文字列 行末パターン */
+       private static final String NOTATION_REGEX_LINETAIL = "$";
+       
+       /** WIKI記法の正規表現文字列 */
+       public static final String NOTATION_REGEX = NOTATION_REGEX_LINEHEAD
+                       + NOTATION_REGEX_LINETAIL;
+
+       /** 
+        *  コンストラクタ
+        */
+       public WikiHrBlockParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+       }
+
+       @Override
+       public String startElementProcess(String line, StringBuffer buf) {
+               buf.append(START_TAG);
+               return line.replaceFirst(NOTATION_REGEX_LINEHEAD, "");
+       }
+
+       @Override
+       public String endElementProcess(String line, StringBuffer buf) {
+               buf.append(END_TAG);
+               return "";
+       }
+
+       @Override
+       public boolean isBlockEnd() {
+               return true;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiOrderedListBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiOrderedListBlockParser.java
new file mode 100644 (file)
index 0000000..aa2eb1f
--- /dev/null
@@ -0,0 +1,120 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Ordered list block parser.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+/**
+ * 番号付きリストのマークアップを解析し、HTML形式に変換する。
+ *
+ */
+public class WikiOrderedListBlockParser extends WikiBlockParserBase {
+       private static final String START_TAG = "<div><ol>\n";
+
+       private static final String END_TAG = "</ol></div>\n";
+       
+       /** WIKI記法の正規表現文字列 行頭パターン */
+       private static final String NOTATION_REGEX_LINEHEAD = "^[ \t]*"
+                                                                                                                       + "#+"
+                                                                                                                       + " +[^#]";
+
+       /** WIKI記法の正規表現文字列 行末パターン */
+       private static final String NOTATION_REGEX_LINETAIL = "";
+       
+       /** WIKI記法の正規表現文字列 */
+       public static final String NOTATION_REGEX = NOTATION_REGEX_LINEHEAD
+                       + "..*"
+                       + NOTATION_REGEX_LINETAIL;
+
+       /**     ブロック終了状態 */
+       private boolean isBlockEnd_ = false;
+
+       /** 処理終了後の残り文字列 */
+       private String  remain_;
+       
+       /** 
+        *  コンストラクタ
+        */
+       public WikiOrderedListBlockParser(WikiEngine wikiEngine) {
+               this(wikiEngine, Status.INIT);
+       }
+
+       /** 
+        *  コンストラクタ
+        */
+       public WikiOrderedListBlockParser(WikiEngine wikiEngine, Status status) {
+               super(wikiEngine);
+               status_ = status;
+       }
+       
+       @Override
+       public String startElementProcess(String line, StringBuffer buf) {
+               status_ = Status.OPEN;
+               buf.append(START_TAG);
+               return line;
+       }
+
+       @Override
+       public String parse(String line, StringBuffer buf) throws Exception {
+               if(line.matches(NOTATION_REGEX) == true) {
+                       String token      = line.substring(line.indexOf("#"));
+                       int    countToken = countToken(token, '#');
+                       if(countToken > 1) {
+                               /*
+                                * '#'を一つ減らして子parserへ渡す。
+                                */
+                               String daughterPart = token.substring(1);
+                               
+                               if(status_ == Status.OPEN) {
+                                       startDaughterParse(new WikiBlockParserCreator.Creator() {
+                                               @Override
+                                               public WikiOrderedListBlockParser create(WikiEngine wikiEngine) {
+                                                       return new WikiOrderedListBlockParser(wikiEngine, Status.OPEN);
+                                               }
+                                       });
+                                       
+                                       daughterParser_.startElementProcess(daughterPart, buf);
+                               }
+                               daughterParser_.parse(daughterPart, buf);
+                       }
+                       else {
+                               if(status_ == Status.NESTING) {
+                                       /*
+                                        * トークンが1つでネスト処理中の場合、
+                                        * ネスト処理を終了する。
+                                        */
+                                       daughterParser_.endElementProcess(line, buf);
+                                       daughterParser_ = null;
+                                       status_ = Status.OPEN;
+                               }
+                               super.parse(line, buf);
+                               remain_ = "";                           
+                       }
+               }
+               else {
+                       isBlockEnd_ = true;
+                       remain_     = line;
+               }
+
+               return "";
+       }
+
+       @Override
+       public String endElementProcess(String line, StringBuffer buf) {
+               if(status_ == Status.NESTING) {
+                       daughterParser_.endElementProcess(line, buf);
+               }
+               buf.append(END_TAG + "\n");
+               return remain_;
+       }
+
+       @Override
+       public boolean isBlockEnd() {
+               return isBlockEnd_;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiPreBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiPreBlockParser.java
new file mode 100644 (file)
index 0000000..84de8e4
--- /dev/null
@@ -0,0 +1,160 @@
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiPreBlockParser extends WikiBlockParserBase {
+       /** WIKI記法の正規表現文字列 行頭パターン */
+       public static final String NOTATION_REGEX_LINEHEAD = "<pre[ \t]*>" + (".*");
+
+       /** WIKI記法の正規表現文字列 行末パターン */
+       public static final String NOTATION_REGEX_LINETAIL = "<*/[ \t]*pre>" + ".*";
+       
+       /** WIKI記法の正規表現文字列 */
+       public static final String NOTATION_REGEX = ".*" + NOTATION_REGEX_LINEHEAD
+                       + ".*";
+
+       /** 
+        *  コンストラクタ
+        */
+       public WikiPreBlockParser(WikiEngine wikiEngine) {
+               this(wikiEngine, Status.INIT);
+       }
+
+       /** 
+        *  コンストラクタ
+        */
+       public WikiPreBlockParser(WikiEngine wikiEngine, Status status) {
+               super(wikiEngine);
+               status_        = status;
+               initialStatus_ = status;
+       }
+       
+       @Override
+       public String startElementProcess(String line, StringBuffer buf) {
+               char[] charLine = line.toCharArray();
+               String previous = "";
+               String main     = "";
+
+               for(count_ = 0; count_ < charLine.length; count_++) {
+                       if(charLine[count_] == '<') {
+                               String now     = line.substring(count_);
+
+                               if(now.matches(WikiPreBlockParser.NOTATION_REGEX_LINEHEAD) == true) {
+                                       previous = line.substring(0, line.indexOf(now));
+                                       main     = now;
+                                       break;
+                               }
+                       }
+               }
+               
+               if(previous.isEmpty() != true) {
+                       buf.append(inlineParse(previous));
+               }
+               
+               return main;
+       }
+
+       @Override
+       public String parse(String line, StringBuffer buf) throws Exception {
+               char[] charLine = line.toCharArray();
+
+               for(count_ = 0; count_ < charLine.length; count_++) {
+                       if(status_ == Status.NESTING) {
+                               String nestpart = new String(line.substring(count_));
+                               daughterParser_.parse(nestpart, buf);
+                               count_ += daughterParser_.getCount();
+
+                               if(daughterParser_.isBlockEnd() == true) {
+                                       daughterParser_.endElementProcess(null, buf);
+                                       status_        = Status.OPEN;
+                                       daughterParser_ = null;
+                               }
+                               continue;
+                       }
+
+                       if(charLine[count_] == '<') {
+                               String now      = line.substring(count_);
+                               String nowLower = now.toLowerCase();
+                               String tagpart  = now.substring(0, now.indexOf(">") + ">".length());
+
+                               if(nowLower.matches(WikiPreBlockParser.NOTATION_REGEX_LINEHEAD) == true) {
+                                       /*
+                                        * <pre>要素がネストしている場合
+                                        */
+                                       count_ += tagpart.length() - 1;
+
+                                       startDaughterParse(new WikiBlockParserCreator.Creator() {
+                                               @Override
+                                               public WikiPreBlockParser create(WikiEngine wikiEngine) {
+                                                       return new WikiPreBlockParser(wikiEngine, Status.OPEN);
+                                               }
+                                       });
+                                       buf.append(tagpart);
+                               }
+                               else if(nowLower.matches(WikiCodeBlockParser.NOTATION_REGEX_LINEHEAD) == true) {
+                                       /*
+                                        * <code>要素がネストしている場合
+                                        */
+                                       count_ += tagpart.length() - 1;
+
+                                       startDaughterParse(new WikiBlockParserCreator.Creator() {
+                                               @Override
+                                               public WikiCodeBlockParser create(WikiEngine wikiEngine) {
+                                                       return new WikiCodeBlockParser(wikiEngine, WikiPreBlockParser.this, Status.OPEN);
+                                               }
+                                       });
+                                       buf.append(tagpart);
+                               }
+                               else if((nowLower.matches(WikiPreBlockParser.NOTATION_REGEX_LINETAIL) == true)
+                                       || (nowLower.matches(WikiCodeBlockParser.NOTATION_REGEX_LINETAIL) == true)) {
+                                       if(status_ == Status.NESTING) {
+                                               daughterParser_.parse(now, buf);
+                                               count_ += daughterParser_.getCount() - 1;
+
+                                               if(daughterParser_.isBlockEnd() == true) {
+                                                       status_        = Status.OPEN;
+                                                       daughterParser_ = null;
+                                               }
+                                       }
+                                       else {
+                                               remain_  = now.substring(now.indexOf(">") + ">".length());
+                                               count_  += tagpart.length() - 1;
+                                               buf.append(tagpart);
+                                               isBlockEnd_ = true;
+                                               break;
+                                       }
+                               }
+                               else {
+                                       count_  += tagpart.length() - 1;
+                                       buf.append(tagpart.replaceAll("<", "&lt;").replaceAll(">", "&gt;"));
+                               }
+                       }
+                       else if(status_ == Status.OPEN) {
+                               buf.append(charLine[count_]);                           
+                       }
+               }
+               
+               if(initialStatus_ == Status.INIT) {
+                       buf.append("\n");
+               }
+
+               return "";
+       }
+
+       @Override
+       public String endElementProcess(String line, StringBuffer buf) {
+               return remain_;
+       }
+
+       @Override
+       public boolean isBlockEnd() {
+               return isBlockEnd_;
+       }
+
+       @Override
+       public String daughterElementCloseHelper(String tagPart) {
+               return (motherParser_ != null)
+                               ? motherParser_.daughterElementCloseHelper(tagPart)
+                               : tagPart;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiTOCBuilder.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiTOCBuilder.java
new file mode 100644 (file)
index 0000000..9bffa73
--- /dev/null
@@ -0,0 +1,125 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * TOC(Table Of Contents) Builder.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+
+import java.util.ArrayList;
+import java.util.ResourceBundle;
+
+/**
+ * WikiTOCBuilder
+ *
+ */
+public class WikiTOCBuilder {
+       private static final String MACRO_INSERTTOC = "{{#TOC}}";
+       
+       /**
+        * Headline(見出し)リストのノード
+        */
+       class HeadlineNode {
+               /** Headline(見出し)名 */
+               String id_;
+
+               /** Headlineレベル */
+               int    headLineLevel_;
+
+               /**
+                * Constractor
+                * @param id
+                * @param level
+                */
+               HeadlineNode(String id, int level) {
+                       id_            = id;
+                       headLineLevel_ = level;
+               }
+       }
+
+       /** page内の見出しのリスト */
+       private ArrayList<HeadlineNode> headlineList_ = new ArrayList<HeadlineNode>();
+
+       /**
+        * headlineListにエントリーを追加する。
+        * @param id
+        * @param level
+        */
+       public void add(String id, int level) {
+               headlineList_.add(new HeadlineNode(id, level));
+       }
+
+       /**
+        * TOC(目次)を構築する
+        * @param line
+        * @return 構築した目次
+        */
+       public String buildTOC(String line) {
+               StringBuffer   buf    = new StringBuffer("");
+               ResourceBundle bundle = ResourceBundle.getBundle("com.wiki.standalone.moxkiriya.resources.moxkiriya");
+               
+               if( (line != null)
+                && (line.startsWith(MACRO_INSERTTOC) == true)) {
+                       if(false) {
+                               /*
+                                * クリックに反応しないので、[show]/[hide]一時無効
+                                */
+                               buf.append(       "<div class=\"tocbox\">\n"
+                                                       + "<input type=\"checkbox\" id=\"toc\">\n"
+                                                       + "<label for=\"toc\">"
+                                                               + bundle.getString("key.Contents")
+                                                       + "</label>\n"
+                                                       + "<div class=\"hidden_show\">\n");
+                               buf.append(buildTOCList());
+                               buf.append(   "</div>\n"
+                                                       + "</div>");
+                       }
+                       else {
+                               buf.append("<div class=\"tocbox\">\n"
+                                                       + "<div class=\"title\">"
+                                                       + bundle.getString("key.Contents")
+                                                       + "</div>\n");
+                               buf.append(buildTOCList());
+                               buf.append(       "</div>\n");
+                       }
+               }
+
+               return buf.toString();
+       }
+       
+       /**
+        * TOC(目次)リストを構築する。
+        * @return 構築した目次リスト
+        */
+       private String buildTOCList() {
+               int          depth = 0;
+               StringBuffer buf   = new StringBuffer("<ul>\n");
+
+               for(HeadlineNode node: headlineList_) {
+                       if(node.headLineLevel_ - 2 < depth) {
+                               while(node.headLineLevel_ - 2 < depth) {
+                                       depth--;
+                                       buf.append("</ul>\n");
+                               }
+                       }
+                       else if(node.headLineLevel_ - 2 > depth) {
+                               while(node.headLineLevel_ - 2 > depth) {
+                                       depth++;
+                                       buf.append("<ul>\n");
+                               }
+                               
+                       }
+
+                       buf.append(       "<li><a href=\"#"
+                                       + node.id_
+                                       + "\")>"
+                                       + node.id_
+                                       + "</a></li>\n");
+               }
+               buf.append("</ul>\n");
+               
+               return buf.toString();
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiTableBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiTableBlockParser.java
new file mode 100644 (file)
index 0000000..ad1bd4b
--- /dev/null
@@ -0,0 +1,149 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * '<table>' Blocklevel element parser, processor.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import java.util.LinkedHashMap;
+import java.util.regex.Pattern;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiTableBlockParser extends WikiBlockParserBase {
+       /** startタグ */
+       private static final String START_TAG = "<div><table";
+
+       /** endタグ*/
+       private static final String END_TAG = "</table></div>\n";
+
+       /** WIKI記法の正規表現文字列 行頭パターン */
+       private static final String NOTATION_REGEX_LINEHEAD = "^[ \t]*"
+                                                                                                               + Pattern.quote("{|");
+
+       /** WIKI記法の正規表現文字列 行末パターン */
+       private static final String NOTATION_REGEX_LINETAIL = "^[ \t]*"
+                                                                                                               + Pattern.quote("|}");
+       
+       /** WIKI記法の正規表現文字列 */
+       public static final String NOTATION_REGEX = NOTATION_REGEX_LINEHEAD + ".*";
+
+       /** CSSセレクターマップ */
+       private static final LinkedHashMap<String, String> selectorMap_ = new LinkedHashMap<String, String>() {
+               private static final long serialVersionUID = 1L;
+               { put("#", "id="); }
+               { put(".", "class=");}
+       };
+
+       /** table 1行分の文字列を蓄積するバッファ */
+       private StringBuffer rowBuf_;
+       
+       /** Daughterブロックパーサクリエイター */
+       private final WikiBlockParserCreator creator_ = new WikiBlockParserCreator(wikiEngine_) {
+               @Override
+               public WikiBlockParser create(String line) {
+                       return new WikiTableRowBlockParser(wikiEngine_);
+               }
+       };
+
+       /**
+        * コンストラクタ
+        * @param wikiRepository
+        */
+       public WikiTableBlockParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+               status_ = Status.INIT;
+       }
+       
+       @Override
+       public String startElementProcess(String line, StringBuffer buf) {
+               buf.append(START_TAG);
+
+               String style = line.replaceFirst(NOTATION_REGEX_LINEHEAD, "").trim();
+               String selector = "";
+
+               if(style.isEmpty() != true) {
+                       /*
+                        * 表開始マークアップ後の文字列のスタイルシートのセレクタ形式か判定する
+                        */
+                       for(String key: selectorMap_.keySet()) {
+                               if(style.startsWith(key) == true) {
+                                       selector = selectorMap_.get(key);
+                                       style    = style.substring(style.indexOf(key) + key.length());
+                                       break;
+                               }
+                       }
+       
+                       if(selector.isEmpty() != true) {
+                               buf.append(" ");
+                               buf.append(selector);
+                               buf.append("\"" + style + "\"");
+                       }
+               }
+               buf.append(">\n");
+
+               return "";
+       }
+
+       @Override
+       public String parse(String line, StringBuffer buf) throws Exception {
+               if(line.matches(NOTATION_REGEX_LINETAIL+ ".*") == true) {
+                       isBlockEnd_ = true;
+                       remain_     = line.replaceFirst(NOTATION_REGEX_LINETAIL, "");
+                       line        = "";
+               }
+               else {
+                       if(rowBuf_ == null) {
+                               rowBuf_ = new StringBuffer();
+                       }
+                       
+                       if(status_ == Status.INIT) {
+                               status_ = Status.OPEN;
+                       }
+                       else if(status_ == Status.OPEN) {
+                               startDaughterParse(creator_, line);
+                               line = daughterParser_.startElementProcess(line, rowBuf_);                                      
+                       }
+                       else if(status_ == Status.NESTING) {
+                               line = daughterParser_.parse(line, rowBuf_);
+                               if(daughterParser_.isBlockEnd() == true) {
+                                       line = daughterParser_.endElementProcess(line, rowBuf_);
+                                       status_ = Status.OPEN;
+                               }                                       
+                       }
+               }
+
+               if(line.startsWith("|-") == true) {
+                       flushRowBuf(buf);
+                       line    = "";
+               }
+               return line;
+       }
+
+       @Override
+       public String endElementProcess(String line, StringBuffer buf) {
+               if(status_ == Status.NESTING) {
+                       daughterParser_.endElementProcess(line, rowBuf_);
+                       status_ = Status.OPEN;
+               }
+               flushRowBuf(buf);
+               buf.append(END_TAG + "\n");
+               return remain_;
+       }
+
+       /**
+        * 表の行終端や表終端マークアップに到達したときに1行分の文字列をbufに書き込む
+        * @param buf
+        */
+       private void flushRowBuf(StringBuffer buf) {
+               if( (rowBuf_ != null)
+                && (rowBuf_.length() > 0)) {
+                       buf.append("<tr>\n");
+                       buf.append(rowBuf_);
+                       buf.append("</tr>\n");
+                       rowBuf_ = null;
+               }
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiTableRowBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiTableRowBlockParser.java
new file mode 100644 (file)
index 0000000..d4f4f1d
--- /dev/null
@@ -0,0 +1,190 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Table row Blocklevel element parser, processor.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import java.util.LinkedHashMap;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiTableRowBlockParser extends WikiBlockParserBase {
+       /** startタグ(th) */
+       private static final String START_TH_TAG = "<th";
+
+       /** endタグ(th) */
+       private static final String END_TH_TAG = "</th>\n";
+
+       /** startタグ(td) */
+       private static final String START_TD_TAG = "<td";
+
+       /** endタグ(td) */
+       private static final String END_TD_TAG = "</td>\n";
+
+       /** WIKI記法の正規表現文字列 行頭パターン */
+       private static final String NOTATION_REGEX_LINEHEAD = "^[ \t]*[!|]";
+
+       /** WIKI記法の正規表現文字列 */
+       public static final String NOTATION_REGEX = NOTATION_REGEX_LINEHEAD + ".*";
+
+       /**
+        * 開始タグと終了タグのペア
+        */
+       static class TagPair {
+               /** 開始タグ */
+               String startTag_;
+               
+               /** 終了タグ */
+               String endTag_;
+
+               /**
+                * コンストラクタ
+                * @param startTag
+                * @param endTag
+                */
+               TagPair(String startTag, String endTag) {
+                       startTag_ = startTag;
+                       endTag_   = endTag;
+               }
+       }
+
+       /** 開始文字と開始/終了タグのマップ */
+       private static final LinkedHashMap<String, TagPair> tagPairHashMap_ = new LinkedHashMap<String, TagPair>() {
+               private static final long serialVersionUID = 1L;
+               { put("!", new TagPair(START_TH_TAG, END_TH_TAG)); }
+               { put("|", new TagPair(START_TD_TAG, END_TD_TAG)); }
+       };
+
+       /** 開始/終了タグのペア */
+       private TagPair  tagpair_;
+
+       /** CSSセレクターマップ */
+       private static final LinkedHashMap<String, String> selectorMap_
+               = new LinkedHashMap<String, String>() {
+               private static final long serialVersionUID = 1L;
+               { put("colspan=", ""); }
+               { put("rowspan=", ""); }
+               { put("scope=", ""); }
+               { put("style=", ""); }
+       };
+
+       /** Daughterブロックパーサクリエイター */
+       private WikiBlockParserCreator creator_;
+
+       private StringBuffer rowBuf_;
+       /**
+        * コンストラクタ
+        * @param wikiRepository
+        */
+       public WikiTableRowBlockParser(WikiEngine wikiEngine) {
+               this(wikiEngine, Status.INIT);
+       }
+
+       /**
+        * コンストラクタ
+        * @param wikiRepository
+        * @param status
+        */
+       public WikiTableRowBlockParser(WikiEngine wikiEngine, Status status) {
+               super(wikiEngine);
+               status_  = status;
+               creator_ = new WikiBlockParserCreator(wikiEngine);
+               rowBuf_  = new StringBuffer("");
+       }
+       
+       @Override
+       public String startElementProcess(String line, StringBuffer buf) {
+               status_ = Status.OPEN;
+
+               String trimedLine  = line.trim();
+               String firstLetter = trimedLine.substring(0, 1);
+               
+               tagpair_           = tagPairHashMap_.get(firstLetter);
+               buf.append(tagpair_.startTag_ + " ");
+               trimedLine         = trimedLine.substring(1);
+
+               StringBuffer cellBuf       = new StringBuffer("");
+               boolean      selectorFound = false;
+               int          count;
+               for(count = 0; count < trimedLine.length(); count++) {
+                       char letter = trimedLine.charAt(count);
+
+                       if(letter == '|') {
+                               break;
+                       }
+
+                       cellBuf.append(letter);
+
+                       if(selectorFound != true) {
+                               for(String key: selectorMap_.keySet()) {
+                                       if(cellBuf.toString().equals(key) == true) {
+                                               selectorFound = true;
+                                               buf.append(key);
+                                               break;
+                                       }
+                               }
+                       }
+                       else {
+                               buf.append(letter);
+                       }
+               }
+               
+               buf.append(">\n");
+
+               if(selectorFound == true) {
+                       trimedLine = trimedLine.substring(count + 1);                   
+               }
+
+               return trimedLine;
+       }
+
+       @Override
+       public String parse(String line, StringBuffer buf) throws Exception {
+               if( (line.startsWith("|") == true)
+                || (line.startsWith("!") == true)) {
+                       isBlockEnd_ = true;
+                       remain_     = line;
+                       line        = "";
+               }
+               else {
+                       if(status_ != Status.NESTING) {
+                               startDaughterParse(creator_, line);
+                               line = daughterParser_.startElementProcess(line, rowBuf_);
+                       }
+                       
+                       line = daughterParser_.parse(line, rowBuf_);
+                       if(daughterParser_.isBlockEnd() == true) {
+                               line = daughterParser_.endElementProcess(line, rowBuf_);
+                               status_ = Status.OPEN;
+                       }
+               }
+
+               return line;
+       }
+
+       @Override
+       public String endElementProcess(String line, StringBuffer buf) {
+               if(status_ == Status.NESTING) {
+                       daughterParser_.endElementProcess(line, rowBuf_);
+                       status_ = Status.OPEN;
+               }
+               flushRowBuf(buf);
+               buf.append(tagpair_.endTag_);
+               return remain_;
+       }
+
+       /**
+        * 表の行終端や表終端マークアップに到達したときに1行分の文字列をbufに書き込む
+        * @param buf
+        */
+       private void flushRowBuf(StringBuffer buf) {
+               if( (rowBuf_ != null)
+                && (rowBuf_.length() > 0)) {
+                       buf.append(rowBuf_);
+                       rowBuf_ = null;
+               }
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiUnorderedListBlockParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/blockparser/WikiUnorderedListBlockParser.java
new file mode 100644 (file)
index 0000000..cfbc072
--- /dev/null
@@ -0,0 +1,122 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Unordered list block parser.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.parser.blockparser;
+
+import java.util.regex.Pattern;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+/**
+ * 番号なしリストのマークアップを解析し、HTML形式に変換する。
+ *
+ */
+public class WikiUnorderedListBlockParser extends WikiBlockParserBase {
+       private static final String START_TAG = "<div><ul>\n";
+
+       private static final String END_TAG = "</ul></div>\n";
+       
+       /** WIKI記法の正規表現文字列 行頭パターン */
+       private static final String NOTATION_REGEX_LINEHEAD = "^[ \t]*"
+                                                                                                                       + Pattern.quote("*")
+                                                                                                                       + "+ +[^*]";
+
+       /** WIKI記法の正規表現文字列 行末パターン */
+       private static final String NOTATION_REGEX_LINETAIL = "";
+       
+       /** WIKI記法の正規表現文字列 */
+       public static final String NOTATION_REGEX = NOTATION_REGEX_LINEHEAD
+                       + "..*"
+                       + NOTATION_REGEX_LINETAIL;
+
+       /**     ブロック終了状態 */
+       private boolean isBlockEnd_ = false;
+
+       /** 処理終了後の残り文字列 */
+       private String  remain_;
+       
+       /** 
+        *  コンストラクタ
+        */
+       public WikiUnorderedListBlockParser(WikiEngine wikiEngine) {
+               this(wikiEngine, Status.INIT);
+       }
+
+       /** 
+        *  コンストラクタ
+        */
+       public WikiUnorderedListBlockParser(WikiEngine wikiEngine, Status status) {
+               super(wikiEngine);
+               status_ = status;
+       }
+       
+       @Override
+       public String startElementProcess(String line, StringBuffer buf) {
+               status_ = Status.OPEN;
+               buf.append(START_TAG);
+               return line;
+       }
+
+       @Override
+       public String parse(String line, StringBuffer buf) throws Exception {
+               if(line.matches(NOTATION_REGEX) == true) {
+                       String token      = line.substring(line.indexOf("*"));
+                       int    countToken = countToken(token, '*');
+                       if(countToken > 1) {
+                               /*
+                                * '#'を一つ減らして子parserへ渡す。
+                                */
+                               String daughterPart = token.substring(1);
+                               
+                               if(status_ == Status.OPEN) {
+                                       startDaughterParse(new WikiBlockParserCreator.Creator() {
+                                               @Override
+                                               public WikiUnorderedListBlockParser create(WikiEngine wikiEngine) {
+                                                       return new WikiUnorderedListBlockParser(wikiEngine, Status.OPEN);
+                                               }
+                                       });
+                                       
+                                       daughterParser_.startElementProcess(daughterPart, buf);
+                               }
+                               daughterParser_.parse(daughterPart, buf);
+                       }
+                       else {
+                               if(status_ == Status.NESTING) {
+                                       /*
+                                        * トークンが1つでネスト処理中の場合、
+                                        * ネスト処理を終了する。
+                                        */
+                                       daughterParser_.endElementProcess(line, buf);
+                                       daughterParser_ = null;
+                                       status_ = Status.OPEN;
+                               }
+                               super.parse(line, buf);
+                               remain_ = "";                           
+                       }
+               }
+               else {
+                       isBlockEnd_ = true;
+                       remain_     = line;
+               }
+
+               return "";
+       }
+
+       @Override
+       public String endElementProcess(String line, StringBuffer buf) {
+               if(status_ == Status.NESTING) {
+                       daughterParser_.endElementProcess(line, buf);
+               }
+               buf.append(END_TAG + "\n");
+               return remain_;
+       }
+
+       @Override
+       public boolean isBlockEnd() {
+               return isBlockEnd_;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiBoldInlineParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiBoldInlineParser.java
new file mode 100644 (file)
index 0000000..bfc4f5d
--- /dev/null
@@ -0,0 +1,81 @@
+package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiBoldInlineParser extends WikiInlineParserBase {
+       /** WIKIトークン */
+       public static final String WIKI_TOKEN    = "'''";
+
+       /** WIKI記法の正規表現文字列 先頭頭パターン */
+       public static final String PATTERN_START = "'''[^']";
+
+       /** WIKI記法の正規表現文字列 末尾パターン */
+       public static final String PATTERN_END = "[^']'''";
+
+       /** WIKI記法の正規表現文字列 末尾パターン */
+       public static final String PATTERN_ITALIC_END = WikiItalicInlineParser.PATTERN_END;
+
+       /** 開始タグ */
+       private static final String START_TAG = "<span id=\"bold\">\n";
+
+       /** 終了タグ */
+       private static final String END_TAG = "</span>\n";
+       
+       /**
+        * コンストラクタ
+        */
+       public WikiBoldInlineParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+       }
+
+       /**
+        * lineとWiki記法をマッチングする
+        * @param line
+        * @return マッチング結果
+        */
+       public static boolean matches(String line) {
+               boolean isMatch = false;
+               
+               Matcher startMatcher
+                       = Pattern.compile(WikiBoldInlineParser.PATTERN_START)
+                                       .matcher(line);
+               
+               if(startMatcher.find() == true) {
+                       isMatch = true;
+               }
+               
+               return isMatch;
+       }
+
+       @Override
+       public void startElementProcess(StringBuffer buf) {
+               buf.append(START_TAG);
+       }
+
+       @Override
+       public void endElementProcess(StringBuffer buf) {
+               buf.append(END_TAG);
+       }
+
+       @Override
+       public String deleteWikiToken(String line) {
+               String deleteTop = line.replaceFirst(WIKI_TOKEN, "");
+               if(deleteTop.contains(WIKI_TOKEN) == true) {
+                       deleteTop = deleteTop.substring(0, deleteTop.lastIndexOf(WIKI_TOKEN));
+               }
+               return deleteTop;
+       }
+
+       @Override
+       public String getStartPattern() {
+               return PATTERN_START;
+       }
+
+       @Override
+       public String getEndPattern() {
+               return PATTERN_END;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiDefaultInlineParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiDefaultInlineParser.java
new file mode 100644 (file)
index 0000000..6833395
--- /dev/null
@@ -0,0 +1,45 @@
+package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiDefaultInlineParser extends WikiInlineParserBase {    
+       /**
+        * コンストラクタ
+        */
+       public WikiDefaultInlineParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+       }
+       
+       @Override
+       public String parse(String line) {
+               StringBuffer buf    = new StringBuffer();
+               String       rest   = line;
+               
+               buf.append(rest);
+               
+               return buf.toString();
+       }
+               
+       @Override
+       public void startElementProcess(StringBuffer buf) {
+       }
+
+       @Override
+       public void endElementProcess(StringBuffer buf) {
+       }
+
+       @Override
+       public String getStartPattern() {
+               return "";
+       }
+
+       @Override
+       public String getEndPattern() {
+               return "";
+       }
+
+       @Override
+       public String deleteWikiToken(String line) {
+               return line;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiExternalLinkInlineParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiExternalLinkInlineParser.java
new file mode 100644 (file)
index 0000000..f56efa6
--- /dev/null
@@ -0,0 +1,245 @@
+package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.wiki.standalone.moxkiriya.SettingManager;
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiExternalLinkInlineParser extends WikiInlineParserBase {
+       /** WIKI開始トークン */
+       public static final String WIKI_TOKEN_START = "[";
+
+       /** WIKI開始トークン */
+       public static final String WIKI_TOKEN_END   = "]";
+
+       /** WIKI記法の正規表現文字列 先頭頭パターン */
+       public static final String PATTERN_START = Pattern.quote(WIKI_TOKEN_START)
+                                                                                               + "[^"
+                                                                                               + Pattern.quote("[")
+                                                                                               + "]";
+
+       /** WIKI記法の正規表現文字列 末尾パターン */
+       public static final String PATTERN_END = "[^]]"
+                                                                                               + Pattern.quote(WIKI_TOKEN_END);
+
+       /** startタグ */
+       private static final String START_TAG = "<a href=";
+
+       /** endタグ */
+       private static final String END_TAG = "</a>\n";
+
+       /** icon startタグ*/
+       private static final String START_ICON_TAG = "<img src=";
+
+       /** icon endタグ */
+       private static final String END_ICON_TAG = "</img>";
+
+       /** external link icon画像名 */
+       private static final String EXTERNAL_LINK_ICON = "icon\\Icon_External_Link.png";
+       
+       /** Link先のURL */
+       private String url_;
+       
+       /** Link先のtextNode */
+       private String textNode_;
+
+       /**
+        * スキーマリスト
+        */
+       private static final ArrayList<String> schemeList = new ArrayList<String>() {
+               private static final long serialVersionUID = 1L;
+               { add("http://"); }
+               { add("https://"); }
+               { add("file://"); }
+       };
+       
+       /**
+        * コンストラクタ
+        */
+       public WikiExternalLinkInlineParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+       }
+
+       /**
+        * lineとWiki記法をマッチングする
+        * @param line
+        * @return マッチング結果
+        */
+       public static boolean matches(String line) {
+               boolean isMatch = false;
+               
+               Matcher startMatcher
+                       = Pattern.compile(WikiExternalLinkInlineParser.PATTERN_START).matcher(line);
+
+               if(startMatcher.find() == true) {
+                       /*
+                        * PATTERN_STARTの開始位置を取得
+                        */                                             
+                       int     startIndex = startMatcher.start();
+
+                       /*
+                        * PATTERN_ENDの開始位置を取得
+                        */
+                       String   startString = line.substring(startIndex + 1);
+                       Matcher  endMatcher  = Pattern.compile(WikiExternalLinkInlineParser.PATTERN_END).matcher(startString);
+                       
+                       if(endMatcher.find() == true) {
+                               isMatch = isSchemeString(startString);
+                       }
+               }
+               
+               return isMatch;
+       }
+
+       @Override
+       public String[] devideLine(String line) {
+               int      depth         = 0;
+               char[]   charArrayLine = line.toCharArray();
+               int      startIndex    = -1;
+               int      endIndex      = -1;
+               int      lastIndex     = -1;
+               boolean  withinElem    = false;
+               
+               for(int count = 0; count < charArrayLine.length; count++) {
+                       if(charArrayLine[count] == '>') {
+                               withinElem = false;
+                               continue;
+                       } else if(charArrayLine[count] == '<') {
+                               withinElem = true;
+                       }
+                       
+                       if(withinElem == true) {
+                               /*
+                                * HTML要素内をスキップ
+                                */
+                               continue;
+                       }
+                       
+                       if(charArrayLine[count] == '[') {
+                               String startString = line.substring(count + 1);
+                               if(isSchemeString(startString) == true) {
+                                       if(startIndex != -1) {
+                                               /*
+                                                * 次の外部リンクの開始の場合、
+                                                */
+                                               endIndex = lastIndex;
+                                               break;
+                                       }
+                                       else if(depth == 0) {
+                                               startIndex = count;
+                                       }
+                               }
+                               else if(startString.startsWith("[")) {
+                                       /*
+                                        * 内部リンクの開始に到達した場合、
+                                        */
+                                       endIndex = lastIndex;
+                                       break;                                  
+                               }
+                               depth++;
+                       }
+                       else if(charArrayLine[count] == ']') {
+                               lastIndex = count;
+                               if(depth > 0) {
+                                       depth--;
+                                       
+                                       if(depth == 0) {
+                                               endIndex = count;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+
+               if(endIndex == -1) {
+                       endIndex = (lastIndex == -1) ? line.length() - 1 : lastIndex;
+               }
+
+               String split0 = line.substring(0, startIndex);
+               String split1 = line.substring(startIndex, endIndex + 1);
+               String split2 = line.substring(endIndex + 1);
+
+               return new String[] {split0, split1, split2};
+       }       
+
+       @Override
+       public String deleteWikiToken(String line) {
+        String deleteTop = line.replaceFirst(Pattern.quote(WIKI_TOKEN_START), "");
+        String text      = deleteTop.substring(0, deleteTop.lastIndexOf(WIKI_TOKEN_END));
+
+        if(text.contains("|") == true) {
+                url_      = text.substring(0, text.indexOf("|"));
+                textNode_ = text.substring(text.indexOf("|") + "|".length());
+        }
+        else {
+                url_      = text;
+                textNode_ = text;
+        }
+        return textNode_.replaceAll(Pattern.quote("["), "&#91;")
+                       .replaceAll(Pattern.quote("]"), "&#93;");
+       }
+
+       @Override
+       public void startElementProcess(StringBuffer buf) {
+               buf.append(START_TAG);
+               buf.append("\"");
+               buf.append(url_);
+               buf.append("\">");
+       }
+
+       @Override
+       public void textNodeProcess(StringBuffer buf, String textNode) {
+               buf.append(textNode);
+       }
+       
+       @Override
+       public String getStartPattern() {
+               return PATTERN_START;
+       }
+
+       @Override
+       public void endElementProcess(StringBuffer buf) {
+               try {
+                       buf.append(START_ICON_TAG);
+                       
+                       SettingManager settingMgr = SettingManager.getInstance();
+                       String         Approot    = settingMgr.get(SettingManager.SETINGKEY_MOXKIRIYAROOT);
+                       String         iconPath   = Approot + "\\" + EXTERNAL_LINK_ICON;
+                       URL            url        = new File(iconPath).toURI().toURL();
+                       buf.append("\"" + url.toString() + "\">");
+       
+                       buf.append(END_ICON_TAG);
+                       buf.append(END_TAG);
+               } catch (MalformedURLException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @Override
+       public String getEndPattern() {
+               return PATTERN_END;
+       }
+
+       /**
+        * lineがscheme文字列で始まるか判定する。
+        * @param line
+        * @return 判定結果
+        */
+       private static boolean isSchemeString(String line) {
+               boolean result = false;
+
+               for(String scheme: schemeList) {
+                       if(line.startsWith(scheme) == true) {
+                               result = true;
+                               break;
+                       }
+               }
+               
+               return result;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInlineParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInlineParser.java
new file mode 100644 (file)
index 0000000..ea81c9f
--- /dev/null
@@ -0,0 +1,17 @@
+package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+public interface WikiInlineParser {
+       /**
+        * WikiのSyntaxを解析し、HTML形式の文字列に変換する。
+        * @param line
+        * @return 変換結果
+        */
+       public String parse(String line);
+
+       /**
+        * lineをkey前、key、key後に分割する。
+        * @param line
+        * @return 分割した文字列配列
+        */
+       public String[] devideLine(String line);
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInlineParserBase.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInlineParserBase.java
new file mode 100644 (file)
index 0000000..4491be6
--- /dev/null
@@ -0,0 +1,131 @@
+package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public abstract class WikiInlineParserBase implements WikiInlineParser {
+       /** Wiki Engine */
+       protected WikiEngine wikiEngine_;
+
+       /**
+        * Constructor.
+        * @param wikiRepository
+        */
+       public WikiInlineParserBase(WikiEngine wikiEngine) {
+               wikiEngine_ = wikiEngine;
+       }
+       
+       @Override
+       public String parse(String line) {
+               String  htmlString = line;
+               
+               if (line.isEmpty() != true
+                && line.equals("{{#TOC}}") != true) {
+                       WikiInlineParserCreator creator = new WikiInlineParserCreator(wikiEngine_);
+                       WikiInlineParser        parser;
+
+                       /*
+                        * 外側のWikiトークンをHTMLに変換する。
+                        */
+                       StringBuffer buf   = new StringBuffer("");
+                       String[]     split = devideLine(line);
+                       buf.append(split[0]);
+
+                       /* 
+                        * 処理したトークンより内側のトークンをHTMLに変換する(もしあれば)。
+                        */
+                       String textNode = deleteWikiToken(split[1]);
+                       parser          = creator.create(textNode);
+                       textNode        = parser.parse(textNode);
+
+                       StringBuffer mainBuf    = new StringBuffer();
+                       startElementProcess(mainBuf);
+                       textNodeProcess(mainBuf, textNode);
+                       endElementProcess(mainBuf);
+
+                       buf.append(mainBuf.toString());
+                       htmlString = buf.append(split[2]).toString();
+
+                       /*
+                        * 処理したWikiトークンより外側のトークンを処理する。
+                        */
+                       parser = creator.create(htmlString);
+
+                       StringBuffer buf2 = new StringBuffer("");
+
+                       buf2.append(parser.parse(htmlString));
+                       htmlString = buf2.toString();
+               }
+
+               return htmlString;
+       }
+
+       /**
+        * Wikiトークンを削除する。
+        * @param line
+        * @return 削除後の文字列
+        */
+       abstract public String deleteWikiToken(String line);
+
+       /**
+        * 要素開始を処理する。
+        * @param buf
+        */
+       abstract public void startElementProcess(StringBuffer buf);
+
+       /**
+        * テキストノードを処理する。
+        * @param buf
+        * @param textNode
+        */
+       public void textNodeProcess(StringBuffer buf, String textNode) {
+               buf.append(textNode);
+       }
+       
+       /**
+        * 要素終了を処理する。
+        * @param buf
+        */
+       abstract public void endElementProcess(StringBuffer buf);
+
+       /**
+        * Wiki記法の開始パターンを取得する
+        * @return Wiki記法の開始パターン
+        */
+       abstract public String getStartPattern();
+
+       /**
+        * Wiki記法の終了パターンを取得する
+        * @return Wiki記法の終了パターン
+        */
+       abstract public String getEndPattern();
+       
+       @Override
+       public String[] devideLine(String line) {
+               String   matchString  = null;
+               String[] result       = null;
+
+               Matcher  startMatcher = Pattern.compile(getStartPattern()).matcher(line);
+
+               if(startMatcher.find() == true) {
+                       String   startSub   = line.substring(startMatcher.start());
+                       Matcher  endMatcher = Pattern.compile(getEndPattern()).matcher(startSub);
+
+                       if(endMatcher.find() == true) {
+                               matchString = startSub.substring(0, endMatcher.end());
+                       }
+                       else {
+                               matchString = startSub;
+                       }
+               }
+
+               if(matchString != null) {
+                       String[] split = line.split(Pattern.quote(matchString), 2);
+                       result = new String[] {split[0], matchString, split[1]};
+               }
+
+               return result;
+       }       
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInlineParserCreator.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInlineParserCreator.java
new file mode 100644 (file)
index 0000000..a52eefa
--- /dev/null
@@ -0,0 +1,198 @@
+package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+import java.util.ArrayList;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+/**
+ * WikiInlineParserインスタンスを生成する。
+ * @author Ryuhei Terada
+ *
+ */
+public class WikiInlineParserCreator {
+       /** WikiInlineParser Creator Table */
+       private ArrayList<Creator> creatorList_;
+
+       /** Wiki Eepository */
+       private WikiEngine wikiEngine_;
+
+       /** 
+        * CreatorテーブルのノードInterface
+        */
+       public interface Creator {
+               /**
+                * Wiki記法とパターンマッチングする。
+                * @param line
+                * @return マッチング結果
+                */
+               public boolean matches(String line);
+               
+               /**
+                * InlineParser生成処理
+                * @param wikiRepository
+                * @return InlineParser
+                */
+               public WikiInlineParser create(WikiEngine wikiEngine);
+       };
+
+       /** default WikiInlineParser Creator Table */
+       private final static ArrayList<Creator> defaultCreatorList_ = new ArrayList<Creator>() {
+               private static final long serialVersionUID = 1L;
+               {
+                       /* WikiInternalLinkInlineParser creator. */
+                       add(new Creator() {
+                               @Override
+                               public boolean matches(String line) {
+                                       return WikiInternalLinkInlineParser.matches(line);
+                               }
+
+                               @Override 
+                               public WikiInlineParser create(WikiEngine wikiEngine) {
+                                       return new WikiInternalLinkInlineParser(wikiEngine);
+                               }
+                       } );
+
+                       /* WikiExternalLinkInlineParser creator. */
+                       add(new Creator() {
+                               @Override
+                               public boolean matches(String line) {
+                                       return WikiExternalLinkInlineParser.matches(line);
+                               }
+
+                               @Override
+                               public WikiInlineParser create(WikiEngine wikiEngine) {
+                                       return new WikiExternalLinkInlineParser(wikiEngine);
+                               }
+                       } );
+
+                       /* WikiBoldInlineParser creator. */
+                       add(new Creator() {
+                               @Override
+                               public boolean matches(String line) {
+                                       return WikiBoldInlineParser.matches(line.toLowerCase());
+                               }
+
+                               @Override 
+                               public WikiInlineParser create(WikiEngine wikiEngine) {
+                                       return new WikiBoldInlineParser(wikiEngine);
+                               }
+                       } );
+
+                       /* WikiItalicInlineParser creator. */
+                       add(new Creator() {
+                               @Override
+                               public boolean matches(String line) {
+                                       return WikiItalicInlineParser.matches(line);
+                               }
+
+                               @Override 
+                               public WikiInlineParser create(WikiEngine wikiEngine) {
+                                       return new WikiItalicInlineParser(wikiEngine);
+                               }
+                       } );
+
+                       /* WikiUnderlineInlineParser creator. */
+                       add(new Creator() {
+                               @Override
+                               public boolean matches(String line) {
+                                       return WikiUnderlineInlineParser.matches(line);
+                               }
+
+                               @Override 
+                               public WikiInlineParser create(WikiEngine wikiEngine) {
+                                       return new WikiUnderlineInlineParser(wikiEngine);
+                               }
+                       } );
+
+                       /* WikiLineThroughInlineParser creator. */
+                       add(new Creator() {
+                               @Override
+                               public boolean matches(String line) {
+                                       return WikiLineThroughInlineParser.matches(line);
+                               }
+
+                               @Override 
+                               public WikiInlineParser create(WikiEngine wikiEngine) {
+                                       return new WikiLineThroughInlineParser(wikiEngine);
+                               }
+                       } );
+
+                       /* WikiUnorderedListItemInlineParser creator. */
+                       add(new Creator() {
+                               @Override
+                               public boolean matches(String line) {
+                                       return WikiUnorderedListItemInlineParser.matches(line);
+                               }
+
+                               @Override 
+                               public WikiInlineParser create(WikiEngine wikiEngine) {
+                                       return new WikiUnorderedListItemInlineParser(wikiEngine);
+                               }
+                       } );
+                       /* WikiOrderedListItemInlineParser creator. */
+                       add(new Creator() {
+                               @Override
+                               public boolean matches(String line) {
+                                       return WikiOrderedListItemInlineParser.matches(line);
+                               }
+
+                               @Override 
+                               public WikiInlineParser create(WikiEngine wikiEngine) {
+                                       return new WikiOrderedListItemInlineParser(wikiEngine);
+                               }
+                       } );
+               }
+       };
+
+       /**
+        * コンストラクタ
+        */
+       public WikiInlineParserCreator(WikiEngine wikiEngine) {
+               this(defaultCreatorList_, wikiEngine);
+       }
+
+       /**
+        * コンストラクタ
+        * @param creatorList
+        */
+       public WikiInlineParserCreator(ArrayList<Creator> creatorList, WikiEngine wikiEngine) {
+               creatorList_    = creatorList;
+               wikiEngine_ = wikiEngine;
+       }
+       
+       /**
+        * lineのSyntaxにマッチするWikiInlineParserのインスタンスを生成する。
+        * @param line
+        * @param file
+        * @return WikiInlineParser
+        */
+       public WikiInlineParser create(String line) {
+               WikiInlineParser parser      = null;
+               StringBuffer     withoutElem = new StringBuffer("");
+
+               if( (line.isEmpty() != true)
+                && (line.contains("<") == true)
+                && (line.contains(">") == true)) {
+                       withoutElem.append(line.substring(0, line.indexOf("<")));
+                       withoutElem.append(line.substring(line.lastIndexOf(">") + ">".length()));
+               }
+               else {
+                       withoutElem.append(line);
+               }
+
+               if(withoutElem.toString().isEmpty() != true) {
+                       for(Creator creator: creatorList_) {
+                               if(creator.matches(withoutElem.toString()) == true) {
+                                       parser = creator.create(wikiEngine_);
+                                       break;
+                               }
+                       }               
+               }
+               
+               if(parser == null) {
+                       parser = new WikiDefaultInlineParser(wikiEngine_);
+               }
+               
+               return parser;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInternalLinkInlineParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiInternalLinkInlineParser.java
new file mode 100644 (file)
index 0000000..44ef52e
--- /dev/null
@@ -0,0 +1,449 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * Wiki Internallink inline parser 
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+
+import org.apache.jackrabbit.util.Base64;
+
+import com.wiki.standalone.moxkiriya.PageData;
+import com.wiki.standalone.moxkiriya.WikiEngine;
+import com.wiki.standalone.moxkiriya.WikiRepository;
+import com.wiki.standalone.moxkiriya.util.FileTypeDeterminator;
+
+/**
+ * Wiki internal inline parser.
+ * Transform [[linkTarget|Title]] to <a href="linkTarget">Title</a>
+ */
+public class WikiInternalLinkInlineParser extends WikiInlineParserBase {
+       /** WIKI開始トークン */
+       public static final String WIKI_TOKEN_START = "[[";
+
+       /** WIKI開始トークン */
+       public static final String WIKI_TOKEN_END   = "]]";
+
+       /** WIKI記法の正規表現文字列 先頭頭パターン */
+       public static final String PATTERN_START = Pattern.quote(WIKI_TOKEN_START)
+                                                                                               + "[^"
+                                                                                               + Pattern.quote("[")
+                                                                                               + "]";
+
+       /** WIKI記法の正規表現文字列 末尾パターン */
+       public static final String PATTERN_END = "[^]]"
+                                                                                               + Pattern.quote(WIKI_TOKEN_END);
+
+       /** アンカー開始タグ */
+       private static final String START_TAG = "<a href=";
+
+       /** アンカー終了タグ */
+       private static final String END_TAG = "</a>\n";
+
+       /** jcr_uuid 独自属性 */
+       public static final String ATTRIBUTE_JCR_UUID = WikiEngine.ATTRIBUTE_JCR_UUID;
+
+       /** img開始タグ */
+       private static final String IMAGE_START_TAG = "<img src=";
+
+       /** img終了タグ */
+       private static final String IMAGE_END_TAG = "</img>";
+
+       /** ページ名接頭辞 "File:" */
+       private static final String PAGENAME_PREFIX_FILE = WikiEngine.NAMESPACE_FILE + ":";
+
+       /** ページ名接頭辞 ":File:" */
+       private static final String PAGENAME_PREFIX_COLONFILE = ":" + WikiEngine.NAMESPACE_FILE + ":";
+
+       /** ページ名接頭辞 "Category:" */
+       private static final String PAGENAME_PREFIX_CATEGORY = WikiEngine.NAMESPACE_CATEGORY + ":";
+
+       /** ページ名接頭辞 ":Category:" */
+       private static final String PAGENAME_PREFIX_COLONCATEGORY = ":" + WikiEngine.NAMESPACE_CATEGORY + ":";
+
+       /** ページタイトルマクロ "#title" */
+       private static final String PAGENAME_HASH_TITLE = "#title";
+
+       /** 存在しないファイルのスタイルクラス */
+       private static final String STYLE_CLASS_NOEXIST = "class=\"noexist\"";
+       
+       /** リンク先のページ名 */
+       private String pagename_;
+       
+       /** リンク先ファイルのフルパス */
+       private String linkpath_;
+
+       /** リンクモード */
+       private enum LinkMode {
+               NONE,
+               INNERLINK,
+               IMAGERENDER,
+               ATTACHEDFILELINK
+       };
+       
+       /** リンクモード */
+       private LinkMode linkMode;
+
+       /**
+        * テキストノード処理クラス
+        */
+       private interface TextNodeProcessor {
+               /**
+                * テキストノードを処理する
+                * @param buf
+                * @param textNode
+                */
+               void textNodeProcess(StringBuffer buf, String textNode);
+       };
+
+       private final LinkedHashMap<LinkMode, TextNodeProcessor> textNodeProcessorMap = new LinkedHashMap<LinkMode, TextNodeProcessor>() {
+               private static final long serialVersionUID = 1L;
+               {
+                       put(LinkMode.NONE, new TextNodeProcessor() {
+                               @Override
+                               public void textNodeProcess(StringBuffer buf, String textNode) {
+                                       
+                               }
+                       });
+               }
+               {
+                       put(LinkMode.INNERLINK, new TextNodeProcessor() {
+                               @Override
+                               public void textNodeProcess(StringBuffer buf, String textNode) {
+                                       if(linkpath_.isEmpty() != true) {
+                                               if( (textNode.startsWith(PAGENAME_PREFIX_COLONFILE) == true)
+                                                || (textNode.startsWith(PAGENAME_PREFIX_COLONCATEGORY) == true)) {
+                                                       textNode = textNode.replaceFirst(Pattern.quote(":"), "");
+                                               }
+
+                                               buf.append(textNode);
+                                       }
+                               }
+                       });                     
+               }
+               {
+                       put(LinkMode.IMAGERENDER, new TextNodeProcessor() {
+                               @Override
+                               public void textNodeProcess(StringBuffer buf, String textNode) {
+                                       try {
+                                               String       mediaType = null;
+                                               StringBuffer databuf   = new StringBuffer("");
+
+                                               HashMap<String, PageData> pageDataMap = wikiEngine_.queryPageTitle(linkpath_);
+                                               PageData.FileData fileData = null;
+                                               PageData          pageData = null;
+
+                                               if(pageDataMap.isEmpty() != true) {
+                                                       /*
+                                                        * File名前空間のpageは重複しないため、最初に見つかったnodeを対象にする
+                                                        */
+                                                       pageData = pageDataMap.values().iterator().next();
+                                                       fileData = pageData.getFileData();
+                                               }
+
+                                               if(fileData == null) {
+                                                       /*
+                                                        * 表示/編集中のページデータを取得する
+                                                        */
+                                                       HashMap<String, PageData> nowPageDataMap = wikiEngine_.getPageDataMap();
+                                                       PageData nowPageData = nowPageDataMap.values().iterator().next();
+                                                       if(nowPageData.getNamespace().equals(WikiRepository.PROPERTY_FILE) == true) {
+                                                               String title = nowPageData.getTitle();
+                                                               if(linkpath_.equals(WikiRepository.PROPERTY_FILE + ":" + title) == true) {
+                                                                       /*
+                                                                        * parse中のページのtitleとリンク対象のページが同一の場合、
+                                                                        * PageData内のFileを設定する。
+                                                                        * File:タイトルを新規編集中でAttach file textboxにパス名が入力されているとき用の処理
+                                                                        */
+                                                                       fileData = nowPageData.getFileData();
+                                                               }
+                                                       }
+                                               }
+                                               
+                                               if(fileData != null) {
+                                                       mediaType   = fileData.getMimeType();
+
+                                                       InputStream inputStream = fileData.getInputStream();
+                                                       ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+                                                       if(mediaType.startsWith("image/") == true) {
+                                                               Base64.encode(inputStream, outputStream);
+                                                               databuf.append(outputStream.toString());
+                                                       }
+
+                                                       buf.append(IMAGE_START_TAG);
+                                                       if(databuf.length() > 0) {
+                                                               buf.append("\"data:");
+                                                               buf.append(mediaType + ";base64,");
+                                                               buf.append(databuf);
+                                                               buf.append("\"");
+                                                       }
+                                                       buf.append(" alt=\"");
+                                                       buf.append(textNode);
+                                                       buf.append("\"");
+                                                       buf.append(" title=\"");
+                                                       buf.append(textNode);
+                                                       buf.append("\" >");
+                                                       buf.append(IMAGE_END_TAG);
+                                               }
+                                               else {
+                                                       buf.append(textNode);
+                                               }
+                                       } catch (Exception e) {
+                                               e.printStackTrace();
+                                       }
+                               }
+                       });                     
+               }
+               {
+                       put(LinkMode.ATTACHEDFILELINK, new TextNodeProcessor() {
+                               @Override
+                               public void textNodeProcess(StringBuffer buf, String textNode) {
+                                       String basename = linkpath_.substring(linkpath_.lastIndexOf("\\") + "\\".length());
+                                       buf.append(basename);
+                               }
+                       });                     
+               }
+       };
+       
+       /**
+        * コンストラクタ
+        * @param wikiRepository
+        */
+       public WikiInternalLinkInlineParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+       }
+
+       /**
+        * lineとWiki記法をマッチングする
+        * @param line
+        * @return マッチング結果
+        */
+       public static boolean matches(String line) {
+               boolean isMatch = false;
+               
+               Matcher startMatcher
+                       = Pattern.compile(WikiInternalLinkInlineParser.PATTERN_START)
+                                       .matcher(line);
+               
+               if(startMatcher.find() == true) {
+                       /*
+                        * PATTERN_STARTの開始位置を取得
+                        */                                             
+                       int     startIndex = startMatcher.start();
+                       
+                       /*
+                        * PATTERN_ENDの開始位置を取得
+                        */
+                       String   subline             = line.substring(startIndex);
+                       Matcher  endMatcher = Pattern.compile(WikiInternalLinkInlineParser.PATTERN_END)
+                                               .matcher(subline);
+                       
+                       if(endMatcher.find() == true) {
+                               isMatch = true;
+                       }
+               }
+               
+               return isMatch;
+       }
+
+       @Override
+       public String[] devideLine(String line) {
+               char[]   charArrayLine = line.toCharArray();
+               int      startIndex    = -1;
+               int      endIndex      = -1;
+               boolean  withinElem    = false;
+               
+               for(int count = 0; count < charArrayLine.length; count++) {
+                       if(charArrayLine[count] == '>') {
+                               withinElem = false;
+                               continue;
+                       } else if(charArrayLine[count] == '<') {
+                               withinElem = true;
+                       }
+                       
+                       if(withinElem == true) {
+                               /*
+                                * HTML要素内をスキップ
+                                */
+                               continue;
+                       }
+
+                       if(charArrayLine[count] == '[') {
+                               String startString = line.substring(count);
+                               if(startString.startsWith(WIKI_TOKEN_START) == true) {
+                                       startIndex = count;
+                               }
+                       }
+                       else if(charArrayLine[count] == ']') {
+                               if(startIndex != -1) {
+                                       String endString = line.substring(count);
+                                       if(endString.startsWith(WIKI_TOKEN_END) == true) {
+                                               endIndex = count;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               
+               String split0 = line.substring(0, startIndex);
+               String split1 = line.substring(startIndex, endIndex + 2);
+               String split2 = line.substring(endIndex + 2);
+               
+               return new String[] {split0.replaceAll(Pattern.quote("["), "&#91;")
+                                                               .replaceAll(Pattern.quote("]"), "&#93;"),
+                                                        split1,
+                                                        split2};
+       }       
+
+       @Override
+       public String deleteWikiToken(String line) {
+               String deleteTop   = line.replaceFirst(Pattern.quote(WIKI_TOKEN_START), "");
+               String deleteToken = deleteTop.substring(0, deleteTop.lastIndexOf(WIKI_TOKEN_END));
+               String textNode    = deleteToken;
+
+               if(deleteToken.contains("|") == true) {
+                       pagename_ = deleteToken.substring(0, deleteToken.indexOf("|"));
+                       textNode  = deleteToken.substring(deleteToken.indexOf("|") + "|".length());
+
+                       if(textNode.equals(PAGENAME_HASH_TITLE) == true) {
+                               textNode = pagename_.substring(pagename_.lastIndexOf(":") + ":".length());
+                       }
+               }
+               else {
+                       pagename_ = deleteToken;
+               }
+               
+               return textNode;
+       }
+
+       @Override
+       public void startElementProcess(StringBuffer buf) {
+               try {
+                       linkpath_ = buildLinkpathFromPagename(pagename_);
+
+                       if(linkpath_.isEmpty() != true) {
+                               buf.append(START_TAG);
+                               buf.append("\"");
+                               buf.append(linkpath_ + "\" ");
+       
+                               HashMap<String, PageData> pageDataMap = wikiEngine_.queryPageTitle(linkpath_);                  
+                               if(pageDataMap.size() == 0) {
+                                       buf.append(STYLE_CLASS_NOEXIST);
+                               }
+                               else if(pageDataMap.size() == 1) {
+                                       Set<String> key      = pageDataMap.keySet();
+                                       PageData    pageData = pageDataMap.get(key.iterator().next());
+                                       Node        node     = pageData.getNode();
+                                       buf.append(" " + ATTRIBUTE_JCR_UUID + "=\"");
+                                       buf.append(node.getProperty(Property.JCR_UUID).getString());
+                                       buf.append("\"");
+                               }
+                               buf.append(">");
+                       }
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       @Override
+       public void textNodeProcess(StringBuffer buf, String textNode) {
+               textNodeProcessorMap.get(linkMode).textNodeProcess(buf, textNode);
+       }
+       
+       @Override
+       public String getStartPattern() {
+               return PATTERN_START;
+       }
+
+       @Override
+       public void endElementProcess(StringBuffer buf) {
+               if(linkpath_.isEmpty() != true) {
+                       buf.append(END_TAG);
+               }
+               linkMode = LinkMode.NONE;
+       }
+
+       @Override
+       public String getEndPattern() {
+               return PATTERN_END;
+       }
+
+       /**
+        * pagenameからLinkパスを構築する
+        * @param pagename
+        * @return Linkパス
+        * @throws Exception
+        */
+       private String buildLinkpathFromPagename(String pagename) throws Exception {
+               String linkpath = null;
+
+               if(pagename.startsWith(PAGENAME_PREFIX_FILE) == true) {
+                       if(FileTypeDeterminator.isImageFile(pagename) == true) {
+                               linkMode = LinkMode.IMAGERENDER;
+                               linkpath = buildImageLinkpath(pagename);
+                       }
+                       else {
+                               linkMode = LinkMode.ATTACHEDFILELINK;
+                               linkpath = buildAttachLinkpath(pagename);
+                       }
+               }
+               else if(pagename.startsWith(PAGENAME_PREFIX_CATEGORY) == true) {
+                       linkMode = LinkMode.INNERLINK;
+                       linkpath = "";
+               }
+               else {
+                       linkMode = LinkMode.INNERLINK;
+                       linkpath = buildInternalLinkpath(pagename);
+               }
+               
+               return linkpath;
+       }
+
+       /**
+        * イメージリンクパスを構築する。
+        * @param pagename
+        * @return イメージリンクパス
+        */
+       private String buildAttachLinkpath(String pagename) {
+               /*
+                * 先頭の":"を削除
+                */
+               return pagename.substring(1);
+       }
+
+       /**
+        * イメージリンクパスを構築する。
+        * @param pagename
+        * @return イメージリンクパス
+        */
+       private String buildImageLinkpath(String pagename) {
+               return pagename;
+       }
+
+       /**
+        * 内部リンクパスを構築する
+        * @param pagename
+        * @return 内部リンクパス
+        * @throws Exception
+        */
+       private String buildInternalLinkpath(String pagename) throws Exception {
+               if( (pagename.startsWith(PAGENAME_PREFIX_COLONFILE) == true)
+                || (pagename.startsWith(PAGENAME_PREFIX_COLONCATEGORY) == true)) {
+                       pagename = pagename.replaceFirst(Pattern.quote(":"), "");
+               }
+               
+               return pagename;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiItalicInlineParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiItalicInlineParser.java
new file mode 100644 (file)
index 0000000..2010102
--- /dev/null
@@ -0,0 +1,78 @@
+package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiItalicInlineParser extends WikiInlineParserBase {
+       /** WIKIトークン */
+       public static final String WIKI_TOKEN        = "''";
+
+       /** WIKI記法の正規表現文字列 先頭頭パターン */
+       public static final String PATTERN_START = "''[^']";
+
+       /** WIKI記法の正規表現文字列 末尾パターン */
+       public static final String PATTERN_END = "[^']''";
+
+       /** 開始タグ */
+       private static final String START_TAG = "<span id=\"italic\">\n";
+
+       /** 終了タグ */
+       private static final String END_TAG = "</span>\n";
+       
+       /**
+        * コンストラクタ
+        */
+       public WikiItalicInlineParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+       }
+
+       /**
+        * lineとWiki記法をマッチングする。
+        * @param line
+        * @return マッチング結果
+        */
+       public static boolean matches(String line) {
+               boolean isMatch = false;
+               
+               Matcher startMatcher
+                       = Pattern.compile(WikiItalicInlineParser.PATTERN_START)
+                                       .matcher(line);
+               
+               if(startMatcher.find() == true) {
+                       isMatch = true;
+               }
+               
+               return isMatch;
+       }
+
+       @Override
+       public void startElementProcess(StringBuffer buf) {
+               buf.append(START_TAG);
+       }
+
+       @Override
+       public void endElementProcess(StringBuffer buf) {
+               buf.append(END_TAG);
+       }
+
+       @Override
+       public String deleteWikiToken(String line) {
+               String deleteTop = line.replaceFirst(WIKI_TOKEN, "");
+               if(deleteTop.contains(WIKI_TOKEN) == true) {
+                       deleteTop = deleteTop.substring(0, deleteTop.lastIndexOf(WIKI_TOKEN));
+               }
+               return deleteTop;
+       }
+
+       @Override
+       public String getStartPattern() {
+               return PATTERN_START;
+       }
+
+       @Override
+       public String getEndPattern() {
+               return PATTERN_END;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiLineThroughInlineParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiLineThroughInlineParser.java
new file mode 100644 (file)
index 0000000..cb59494
--- /dev/null
@@ -0,0 +1,89 @@
+package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiLineThroughInlineParser extends WikiInlineParserBase {
+       /** WIKIトークン */
+       public static final String WIKI_TOKEN        = "--";
+
+       /** WIKI記法の正規表現文字列 先頭頭パターン */
+       public static final String PATTERN_START = "--[^-]";
+
+       /** WIKI記法の正規表現文字列 末尾パターン */
+       public static final String PATTERN_END = "[^-]--";
+
+       /** 開始タグ */
+       private static final String START_TAG = "<span id=\"linethrough\">\n";
+
+       /** 終了タグ */
+       private static final String END_TAG = "</span>\n";
+
+       /**
+        * コンストラクタ
+        */
+       public WikiLineThroughInlineParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+       }
+
+       /**
+        * lineとWiki記法をマッチングする
+        * @param line
+        * @return マッチング結果
+        */
+       public static boolean matches(String line) {
+               boolean isMatch = false;
+               
+               Matcher startMatcher
+                       = Pattern.compile(WikiLineThroughInlineParser.PATTERN_START)
+                                       .matcher(line);
+               
+               if(startMatcher.find() == true) {
+                       /*
+                        * PATTERN_STARTの開始位置を取得
+                        */                                             
+                       int     startIndex = startMatcher.start();
+                       
+                       /*
+                        * PATTERN_ENDの開始位置を取得
+                        */
+                       String   subline             = line.substring(startIndex);
+                       Matcher  underlineEndMatcher = Pattern.compile(WikiLineThroughInlineParser.PATTERN_END)
+                                       .matcher(subline);
+                       
+                       if(underlineEndMatcher.find() == true) {
+                               isMatch = true;
+                       }
+               }
+               
+               return isMatch;
+       }
+
+       @Override
+       public String deleteWikiToken(String line) {
+               String deleteTop = line.replaceFirst(WIKI_TOKEN, "");
+               return deleteTop.substring(0, deleteTop.lastIndexOf(WIKI_TOKEN));
+       }
+
+       @Override
+       public void startElementProcess(StringBuffer buf) {
+               buf.append(START_TAG);
+       }
+
+       @Override
+       public void endElementProcess(StringBuffer buf) {
+               buf.append(END_TAG);
+       }
+
+       @Override
+       public String getStartPattern() {
+               return PATTERN_START;
+       }
+
+       @Override
+       public String getEndPattern() {
+               return PATTERN_END;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiOrderedListItemInlineParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiOrderedListItemInlineParser.java
new file mode 100644 (file)
index 0000000..c51d5a2
--- /dev/null
@@ -0,0 +1,67 @@
+package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiOrderedListItemInlineParser extends WikiInlineParserBase {
+       /** WIKIトークン */
+       public static final String WIKI_TOKEN    = "# ";
+
+       /** WIKI記法の正規表現文字列 先頭頭パターン */
+       public static final String PATTERN_START = "^[ \t]*# ";
+
+       /** WIKI記法の正規表現文字列 末尾パターン */
+       public static final String PATTERN_END = "$";
+
+       /** 開始タグ */
+       private static final String START_TAG = "<li>";
+
+       /** 終了タグ */
+       private static final String END_TAG   = "</li>\n";
+       
+       /**
+        * コンストラクタ
+        */
+       public WikiOrderedListItemInlineParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+       }
+
+       /**
+        * lineとWiki記法をマッチングする
+        * @param line
+        * @return マッチング結果
+        */
+       public static boolean matches(String line) {
+               Matcher startMatcher
+                       = Pattern.compile(WikiOrderedListItemInlineParser.PATTERN_START).matcher(line);
+
+               return startMatcher.find();
+       }
+
+       @Override
+       public void startElementProcess(StringBuffer buf) {
+               buf.append(START_TAG);
+       }
+
+       @Override
+       public void endElementProcess(StringBuffer buf) {
+               buf.append(END_TAG);
+       }
+
+       @Override
+       public String deleteWikiToken(String line) {
+               return line.replaceFirst(WIKI_TOKEN, "");
+       }
+
+       @Override
+       public String getStartPattern() {
+               return PATTERN_START;
+       }
+
+       @Override
+       public String getEndPattern() {
+               return PATTERN_END;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiUnderlineInlineParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiUnderlineInlineParser.java
new file mode 100644 (file)
index 0000000..ed2b653
--- /dev/null
@@ -0,0 +1,89 @@
+package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiUnderlineInlineParser extends WikiInlineParserBase {
+       /** WIKIトークン */
+       public static final String WIKI_TOKEN        = "__";
+
+       /** WIKI記法の正規表現文字列 先頭頭パターン */
+       public static final String PATTERN_START = "__[^_]";
+
+       /** WIKI記法の正規表現文字列 末尾パターン */
+       public static final String PATTERN_END = "[^_]__";
+
+       /** 開始タグ */
+       private static final String START_TAG = "<span id=\"underline\">\n";
+
+       /** 終了タグ */
+       private static final String END_TAG = "</span>\n";
+
+       /**
+        * コンストラクタ
+        */
+       public WikiUnderlineInlineParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+       }
+
+       /**
+        * lineとWiki記法をマッチングする
+        * @param line
+        * @return マッチング結果
+        */
+       public static boolean matches(String line) {
+               boolean isMatch = false;
+               
+               Matcher startMatcher
+                       = Pattern.compile(WikiUnderlineInlineParser.PATTERN_START)
+                                       .matcher(line);
+               
+               if(startMatcher.find() == true) {
+                       /*
+                        * PATTERN_STARTの開始位置を取得
+                        */                                             
+                       int     startIndex = startMatcher.start();
+                       
+                       /*
+                        * PATTERN_ENDの開始位置を取得
+                        */
+                       String   subline             = line.substring(startIndex);
+                       Matcher  underlineEndMatcher = Pattern.compile(WikiUnderlineInlineParser.PATTERN_END)
+                                       .matcher(subline);
+                       
+                       if(underlineEndMatcher.find() == true) {
+                               isMatch = true;
+                       }
+               }
+               
+               return isMatch;
+       }
+
+       @Override
+       public String deleteWikiToken(String line) {
+               String deleteTop = line.replaceFirst(WIKI_TOKEN, "");
+               return deleteTop.substring(0, deleteTop.lastIndexOf(WIKI_TOKEN));
+       }
+
+       @Override
+       public void startElementProcess(StringBuffer buf) {
+               buf.append(START_TAG);
+       }
+
+       @Override
+       public void endElementProcess(StringBuffer buf) {
+               buf.append(END_TAG);
+       }
+
+       @Override
+       public String getStartPattern() {
+               return PATTERN_START;
+       }
+
+       @Override
+       public String getEndPattern() {
+               return PATTERN_END;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiUnorderedListItemInlineParser.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/parser/inlineparser/WikiUnorderedListItemInlineParser.java
new file mode 100644 (file)
index 0000000..6b2b76f
--- /dev/null
@@ -0,0 +1,69 @@
+package com.wiki.standalone.moxkiriya.parser.inlineparser;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.wiki.standalone.moxkiriya.WikiEngine;
+
+public class WikiUnorderedListItemInlineParser extends WikiInlineParserBase {
+       /** WIKIトークン */
+       public static final String WIKI_TOKEN    = Pattern.quote("* ");
+
+       /** WIKI記法の正規表現文字列 先頭頭パターン */
+       public static final String PATTERN_START = "^[ \t]*"
+                                                                                                       + Pattern.quote("*")
+                                                                                                       + " ";
+
+       /** WIKI記法の正規表現文字列 末尾パターン */
+       public static final String PATTERN_END = "$";
+
+       /** 開始タグ */
+       private static final String START_TAG = "<li>";
+
+       /** 終了タグ */
+       private static final String END_TAG   = "</li>\n";
+       
+       /**
+        * コンストラクタ
+        */
+       public WikiUnorderedListItemInlineParser(WikiEngine wikiEngine) {
+               super(wikiEngine);
+       }
+
+       /**
+        * lineとWiki記法をマッチングする
+        * @param line
+        * @return マッチング結果
+        */
+       public static boolean matches(String line) {
+               Matcher startMatcher
+                       = Pattern.compile(WikiUnorderedListItemInlineParser.PATTERN_START).matcher(line);
+
+               return startMatcher.find();
+       }
+
+       @Override
+       public void startElementProcess(StringBuffer buf) {
+               buf.append(START_TAG);
+       }
+
+       @Override
+       public void endElementProcess(StringBuffer buf) {
+               buf.append(END_TAG);
+       }
+
+       @Override
+       public String deleteWikiToken(String line) {
+               return line.replaceFirst(WIKI_TOKEN, "");
+       }
+
+       @Override
+       public String getStartPattern() {
+               return PATTERN_START;
+       }
+
+       @Override
+       public String getEndPattern() {
+               return PATTERN_END;
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/defaultstylesheet.css b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/defaultstylesheet.css
new file mode 100644 (file)
index 0000000..890b5b2
--- /dev/null
@@ -0,0 +1,167 @@
+body {
+       font-family: 'メイリオ','Meiryo','sans-serif';
+}
+
+h1 {
+       padding: 0.25em;
+       color: #494949;
+       border-bottom: solid 3px #d7d7d7;
+}
+
+h2 {
+       padding: 0.25em;
+       color: #494949;
+       border-bottom: solid 3px #d7d7d7;
+}
+
+h3 {
+       padding: 0.25em;
+       color: #494949;
+       border-bottom: solid 1px #d7d7d7;
+}
+
+pre {
+       font-style: monospace;
+       font-size: 16px;
+       padding: 0.5em;
+       margin: 1em;
+       border: solid 1px #c0c0c0;
+       background: #f0f0f0;
+}
+
+code {
+       font-size: 16;
+       padding: 0.5em;
+       margin: 1em;
+}
+
+table {
+       border-collapse: collapse;
+       border: solid 1px #c0c0c0;
+}
+
+table th {
+       background: #f0f0f0;
+       border: solid 1px #c0c0c0;
+       padding-left: 1em;
+       padding-right: 1em;
+       padding-top: 0.5em;
+       padding-bottom: 0.5em;  
+}
+
+table td {
+       border: solid 1px #c0c0c0;
+       padding-left: 1em;
+       padding-right: 1em;
+       padding-top: 0.5em;
+       padding-bottom: 0.5em;  
+}
+
+a.noexist {
+       color: #ff8c00;
+}
+
+blockquote.quotation {
+       margin: 0.2em 0.5em;
+       border-style: solid;
+       border-width: 0 0 0 2px;
+       padding-left: 0.5em;
+       border-color: red;
+}
+
+.quotation blockquote.quotation {
+       border-color: blue;
+}
+
+.quotation .quotation blockquote.quotation {
+       border-color: green;
+}
+
+.quotation .quotation .quotation blockquote.quotation {
+       border-color: red;
+}
+
+.quotation .quotation .quotation .quotation blockquote.quotation {
+       border-color: blue;
+}
+
+.quotation .quotation .quotation .quotation .quotation blockquote.quotation {
+       border-color: green;
+}
+
+.tocbox {
+    margin: 0em 0;
+    padding-top: 0px;
+    padding-bottom: 5px;
+    padding-left: 10px;
+    border-style: solid;
+    border-color: #c0c0c0;
+       border-width: 1px 1px 1px 1px;
+       border-radius: 10px 10px 10px 10px;
+       background: #efefef;
+       max-width: 600px;
+}
+
+.tocbox .title {
+       padding-top: 10px;
+       padding-left: 10px;
+       font-weight: bold;
+       font-size: 120%;
+}
+
+.tocbox label {
+       padding: 0px;
+       font-weight: bold;
+       background: #efefef;
+       cursor :pointer;
+       transition: .5s;
+}
+
+.tocbox label:after {
+       display: inline-block;
+       content: '[show]';
+       padding-right: 5px;
+       transition: 0.2s;
+}
+
+.tocbox label:hover {
+}
+
+.tocbox input:checked ~ label:after {
+       content: '[hide]';
+       -ms-transform: rotate(360deg);
+       -webkit-transform: rotate(360deg);
+       transform: rotate(360deg);
+       color: #668ad8;
+}
+
+.tocbox input {
+       display: none;
+       height: auto;
+       opacity: 1;
+       background: #efefef;
+}
+
+.tocbox .hidden_show {
+       height: 0;
+       padding: 0;
+       overflow: hidden;
+       opacity: 0;
+       transition: 0.8s;
+}
+
+.tocbox input:checked ~ .hidden_show {
+       padding: 3px 0;
+       height: auto;
+       opacity: 1;
+       background: #efefef;
+}
+
+div.categorylist {
+       background: #f0f0f0;
+       border: solid 1px #c0c0c0;
+       padding-left: 1em;
+       padding-right: 1em;
+       padding-top: 0.5em;
+       padding-bottom: 0.5em;          
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/fixedstylesheet.css b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/fixedstylesheet.css
new file mode 100644 (file)
index 0000000..889449c
--- /dev/null
@@ -0,0 +1,30 @@
+#bold {
+       font-weight: bold;
+}
+
+#italic {
+       font-style: italic;
+}
+
+#underline {
+       text-decoration: underline;
+}
+
+#linethrough {
+       text-decoration: line-through;
+}
+
+table.transparent {
+       border-collapse: collapse;
+       border: solid 0px;
+}
+
+table.transparent th, table.transparent td {
+       background: #ffffff;
+       border: solid 0px #000000;
+       padding-left: 1em;
+       padding-right: 1em;
+       padding-top: 0.5em;
+       padding-bottom: 0.5em;  
+}
+
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/icon/Icon_External_Link.png b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/icon/Icon_External_Link.png
new file mode 100644 (file)
index 0000000..16f9b92
Binary files /dev/null and b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/icon/Icon_External_Link.png differ
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_alert.png b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_alert.png
new file mode 100644 (file)
index 0000000..2ffac2b
Binary files /dev/null and b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_alert.png differ
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_confirm.png b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_confirm.png
new file mode 100644 (file)
index 0000000..66adcb6
Binary files /dev/null and b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_confirm.png differ
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_error.png b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_error.png
new file mode 100644 (file)
index 0000000..56ef806
Binary files /dev/null and b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_error.png differ
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_info.jpg b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_info.jpg
new file mode 100644 (file)
index 0000000..1c34202
Binary files /dev/null and b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/icon_info.jpg differ
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/image_processing.gif b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/image_processing.gif
new file mode 100644 (file)
index 0000000..aeb1017
Binary files /dev/null and b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/image/image_processing.gif differ
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/moxkiriya.properties b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/moxkiriya.properties
new file mode 100644 (file)
index 0000000..8c4906a
--- /dev/null
@@ -0,0 +1,129 @@
+@charset "UTF-8"
+key.Application.Title: MoxkiWiki - Moxkiriya Stand-Alone Wiki
+key.PreviewWindow.Title: Preview editing content.
+
+key.MainPage: MainPage
+key.Search.Result: Search result
+
+key.Message.found.pages: The following page was found.
+
+key.Contents: Contents
+
+key.Checkbox.Select.all: Select all
+
+key.Button.OK: OK
+key.Button.Cancel: Cancel
+key.Button.Save: Save
+key.Button.Search: Search
+key.Button.Close: Close
+key.Button.Upload: Upload
+key.Button.DeleteCheckedFiles: Delete checked files
+key.Button.Add.Category: Add new category
+key.Button.Delete.Pages: Delete selected pages
+key.Button.Add.Party: Add new party
+key.Button.Preview: Preview
+key.Button.Restore.Version: Restore this version
+
+key.Menu.File: File
+key.Menu.Edit: Edit
+key.Menu.Help: Help
+
+key.MenuItem.New: New
+key.MenuItem.Import: Import
+key.MenuItem.Export: Export
+key.MenuItem.Exit: Exit
+key.MenuItem.Select.Party: Select a party
+key.MenuItem.About.Moxkiriya: About Moxkiriya.
+
+key.TextField.Search_Wiki: Search Wiki
+key.Hyperlink.Reading: Reading
+key.Hyperlink.Pagelist: Page list
+key.Hyperlink.Edit: Edit
+key.Hyperlink.Main: Main
+key.Hyperlink.History: History
+key.Hyperlink.EditAttachFiles: Edit Attach Files 
+
+key.Config.Setting.Dialog.Message: Moxkiriya Configuration settings.
+key.Config.Setting.Party.name: Party name:
+key.Config.Setting.Party.textField.prompt: Input a party name
+key.Config.Setting.Party.Default.check: Default party:
+key.Config.Setting.Approot: Approot:
+key.Config.Setting.Approot.textField.prompt: Choose Approot path.
+key.Config.Setting.Cluster.setting: Cluster setting:
+key.Config.Setting.DBServer.URL: Database server URL:
+key.Config.Setting.DBServer.URL.textField.prompt: Input Database server URL.
+key.Config.Setting.DBServer.port: Database server port number:
+key.Config.Setting.DBServer.port.textField.prompt: Input Database server port number.
+key.Config.Setting.DBServer.JDBC.Driver: JDBC Driver:
+key.Config.Setting.DBServer.JDBC.Driver.textField.prompt: Input JDBC Driver.
+
+key.Config.Select.Party.Dialog.Message: Select a party.
+key.Config.Select.Party.Select: Select
+key.Config.Select.Party.name: Party name
+key.Config.Select.Party.Default: Default
+
+key.History.Breadcrumbs.List: List
+key.History.Breadcrumbs.Separator: >
+key.History.Breadcrumbs.Content: Content
+key.History.Content.Title: Title
+
+key.Edit.Label.Category: Category:
+key.Edit.Label.Title: Title(MANDATORY):
+key.Edit.Label.Summary: Summary:
+key.Edit.Label.Contents: Contents:
+key.Edit.Label.AttachFile: Attach file: 
+key.Edit.TextField.InputPathname: - Input pathname - 
+key.Edit.ComboBox.Category.PromptText: - Select a category. -
+key.Edit.ComboBox.Category.Item.None: None
+
+key.PageList.Label.Namespace: Namespace:
+key.PageList.Label.Redraw: Redraw
+key.Table.Row.Select: Sel
+key.Table.Row.Title: Title
+key.Table.Row.Content: Content
+key.Table.Row.Date: Date
+key.Table.Row.Refs: Refs
+
+
+key.webView.Hyperlink.Reload: Reload
+
+key.Dialog.Message.Cancel.Editing: Cancel editing?
+key.Dialog.Detail.Cancel.Editing: Discard the editing content when you cancel editing.
+
+key.Dialog.Message.Empty.Title: Title is empty.
+key.Dialog.Detail.Input.Title: Please input title.
+
+key.Dialog.Import.Result.Title: Import result.
+key.Dialog.Detail.Import.Success: Succeeded to import.\nExit application to refresh a repository.
+key.Dialog.Detail.Import.Failure: Failed to import.
+
+key.Dialog.Export.Result.Title: Export result.
+key.Dialog.Detail.Export.Success: Succeeded to Export.
+key.Dialog.Detail.Export.Failure: Failed to Export.
+
+key.ImportDialog.Title: Select an import file
+key.ExportDialog.Title: Select an export file
+
+key.EditAttachedFileDialog.Title: Edit attach files.
+key.EditAttachedFileDialog.Button.DeleteCheckedFiles: Delete checked files
+key.EditAttachedFileDialog.Addfiles.DialogTitle: Select attach files.
+key.EditAttachedFileDialog.Current.contents: Current contents:
+
+key.AddCategoryDialog.Label.Select.parent: Select a parent category.
+key.AddCategoryDialog.TextField.Prompt.input.new.category.name: - Input new category name. -
+key.AddCategoryDialg.Button.OK:OK
+key.AddCategoryDialg.Button.Cancel:Cancel
+
+key.search.result.PageTitle: Search results
+key.search.result.SearchKey: Search key:
+key.search.result.message.nopage: There was no pages that hit the search.
+
+key.About.Moxkiriya: About Moxkiriya.
+key.About.Moxkiriya.Copyright: Copyright 2018 Ryuhei Terada All rights reserved.
+key.About.Moxkiriya.License: This software is licensed by GPL version 3.0.
+key.About.Moxkiriya.System.requirement: System requirement.
+key.About.Moxkiriya.System.requirement.Java: Java version 1.7.0 or later.
+key.About.Moxkiriya.Other.info: Other infomation.
+key.About.Moxkiriya.Powered.Apache.Lucene: This software uses Apache Jackrabbit.
+key.About.Moxkiriya.Lucene.license: Apache Jackrabbit is licensed by Apache license version 2.0.
+
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/repository_cluster_derby.xml b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/repository_cluster_derby.xml
new file mode 100644 (file)
index 0000000..112c337
--- /dev/null
@@ -0,0 +1,192 @@
+<?xml version="1.0"?>\r
+<!--\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+-->\r
+\r
+<!DOCTYPE Repository\r
+          PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 2.0//EN"\r
+          "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">\r
+\r
+<!-- Example Repository Configuration File\r
+     Used by\r
+     - org.apache.jackrabbit.core.config.RepositoryConfigTest.java\r
+     -\r
+-->\r
+<Repository>\r
+    <!--\r
+        virtual file system where the repository stores global state\r
+        (e.g. registered namespaces, custom node types, etc.)\r
+    -->\r
+    <!--\r
+    <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">\r
+        <param name="path" value="${rep.home}/repository"/>\r
+    </FileSystem>\r
+    -->\r
+    <FileSystem class="org.apache.jackrabbit.core.fs.db.DerbyFileSystem">\r
+        <param name="url" value="jdbc:derby:${rep.home}/db;create=true"/>\r
+        <param name="schemaObjectPrefix" value="rep_"/>\r
+    </FileSystem>   \r
+    <!--\r
+        data store configuration\r
+    -->\r
+    <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">\r
+        <param name="path" value="${wiki.root}/${party.name}/datastore"/>\r
+        <param name="minRecordLength" value="1024"/>\r
+    </DataStore>\r
+\r
+    <!--\r
+        security configuration\r
+    -->\r
+    <Security appName="Jackrabbit">\r
+        <!--\r
+            security manager:\r
+            class: FQN of class implementing the JackrabbitSecurityManager interface\r
+        -->\r
+        <SecurityManager class="org.apache.jackrabbit.core.DefaultSecurityManager" workspaceName="security">\r
+            <!--\r
+            workspace access:\r
+            class: FQN of class implementing the WorkspaceAccessManager interface\r
+            -->\r
+            <!-- <WorkspaceAccessManager class="..."/> -->\r
+            <WorkspaceAccessManager class="org.apache.jackrabbit.core.security.simple.SimpleWorkspaceAccessManager" />\r
+            <!-- <param name="config" value="${rep.home}/security.xml"/> -->\r
+        </SecurityManager>\r
+\r
+        <!--\r
+            access manager:\r
+            class: FQN of class implementing the AccessManager interface\r
+        -->\r
+       <!--\r
+        <AccessManager class="org.apache.jackrabbit.core.security.DefaultAccessManager">\r
+       -->\r
+        <AccessManager class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager">\r
+            <!-- <param name="config" value="${rep.home}/access.xml"/> -->\r
+        </AccessManager>\r
+\r
+               <!--\r
+        <LoginModule class="org.apache.jackrabbit.core.security.authentication.DefaultLoginModule">\r
+               -->\r
+               <LoginModule class="com.sun.security.auth.module.NTLoginModule">\r
+           <!-- \r
+              anonymous user name ('anonymous' is the default value)\r
+            -->\r
+        </LoginModule>\r
+    </Security>\r
+\r
+    <!--\r
+        location of workspaces root directory and name of default workspace\r
+    -->\r
+    <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default"/>\r
+    <!--\r
+        workspace configuration template:\r
+        used to create the initial workspace if there's no workspace yet\r
+    -->\r
+    <Workspace name="${wsp.name}">\r
+        <!--\r
+            virtual file system of the workspace:\r
+            class: FQN of class implementing the FileSystem interface\r
+        -->\r
+        <!-- \r
+        <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">\r
+            <param name="path" value="${wsp.home}"/>\r
+        </FileSystem>\r
+        -->\r
+        <FileSystem class="org.apache.jackrabbit.core.fs.db.DerbyFileSystem">\r
+            <param name="url" value="jdbc:derby:${wsp.home}/db;create=true"/>\r
+            <param name="schemaObjectPrefix" value="wsp_"/>\r
+        </FileSystem>\r
+        <!--\r
+            persistence manager of the workspace:\r
+            class: FQN of class implementing the PersistenceManager interface\r
+        -->\r
+        <PersistenceManager class="org.apache.jackrabbit.core.persistence.pool.DerbyPersistenceManager">\r
+               <!--\r
+            <param name="url" value="jdbc:derby://192.168.123.25:1527/moxkiriyadb/workspace/db;create=true"/>\r
+            <param name="driver" value="org.apache.derby.jdbc.ClientDriver"/>\r
+            -->\r
+            <param name="url" value="${dbserver.url}:${dbserver.port}/moxkiriyadb/${party.name}/workspace/db;create=true"/>\r
+            <param name="driver" value="${jdbc.driver}"/>\r
+            <param name="schemaObjectPrefix" value="${wsp.name}_"/>\r
+            <param name="externalBLOBs" value="true"/>\r
+        </PersistenceManager>\r
+        <!--\r
+            Search index and the file system it uses.\r
+            class: FQN of class implementing the QueryHandler interface\r
+        -->\r
+        <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">\r
+            <param name="path" value="${wsp.home}/index"/>\r
+            <param name="supportHighlighting" value="true"/>\r
+        </SearchIndex>\r
+    </Workspace>\r
+\r
+    <!--\r
+        Configures the versioning\r
+    -->\r
+    <Versioning rootPath="${rep.home}/version">\r
+        <!--\r
+            Configures the filesystem to use for versioning for the respective\r
+            persistence manager\r
+        -->\r
+        <!--\r
+        <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">\r
+            <param name="path" value="${rep.home}/version" />\r
+        </FileSystem>\r
+        -->\r
+        <FileSystem class="org.apache.jackrabbit.core.fs.db.DerbyFileSystem">\r
+            <param name="url" value="jdbc:derby:${rep.home}/version/db;create=true"/>\r
+            <param name="schemaObjectPrefix" value="version_"/>\r
+        </FileSystem>\r
+        <!--\r
+            Configures the persistence manager to be used for persisting version state.\r
+            Please note that the current versioning implementation is based on\r
+            a 'normal' persistence manager, but this could change in future\r
+            implementations.\r
+        -->\r
+        <PersistenceManager class="org.apache.jackrabbit.core.persistence.pool.DerbyPersistenceManager">\r
+            <param name="url" value="${dbserver.url}:${dbserver.port}/moxkiriyadb/${party.name}/version/db;create=true"/>\r
+            <param name="driver" value="${jdbc.driver}"/>\r
+            <param name="schemaObjectPrefix" value="version_"/>\r
+            <param name="externalBLOBs" value="true"/>\r
+        </PersistenceManager>\r
+    </Versioning>\r
+\r
+    <!--\r
+        Search index for content that is shared repository wide\r
+        (/jcr:system tree, contains mainly versions)\r
+    -->\r
+    <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">\r
+        <param name="path" value="${rep.home}/repository/index"/>\r
+        <param name="supportHighlighting" value="true"/>\r
+    </SearchIndex>\r
+\r
+    <!--\r
+        Run with a cluster journal\r
+    -->\r
+    <Cluster id="${cluster.id}">\r
+       <!-- \r
+        <Journal class="org.apache.jackrabbit.core.journal.FileJournal">\r
+            <param name="revision" value="${rep.home}/revision.log" />\r
+            <param name="directory" value="${wiki.root}/${party.name}/journal" />\r
+        </Journal>\r
+        -->\r
+        <Journal class="org.apache.jackrabbit.core.journal.DatabaseJournal">\r
+               <param name="revision" value="${rep.home}/revision.log" />\r
+            <param name="driver" value="${jdbc.driver}" />\r
+            <param name="url" value="${dbserver.url}:${dbserver.port}/moxkiriyadb/${party.name}/journal/db;create=true"/>\r
+                       <param name="databaseType" value="derby"/>\r
+        </Journal>\r
+    </Cluster>\r
+</Repository>
\ No newline at end of file
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/repository_local.xml b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/repository_local.xml
new file mode 100644 (file)
index 0000000..2e5cabb
--- /dev/null
@@ -0,0 +1,159 @@
+<?xml version="1.0"?>\r
+<!--\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+-->\r
+\r
+<!DOCTYPE Repository\r
+          PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 2.0//EN"\r
+          "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">\r
+\r
+<!-- Example Repository Configuration File\r
+     Used by\r
+     - org.apache.jackrabbit.core.config.RepositoryConfigTest.java\r
+     -\r
+-->\r
+<Repository>\r
+    <!--\r
+        virtual file system where the repository stores global state\r
+        (e.g. registered namespaces, custom node types, etc.)\r
+    -->\r
+    <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">\r
+        <param name="path" value="${rep.home}/repository"/>\r
+    </FileSystem>\r
+\r
+    <!--\r
+        data store configuration\r
+    -->\r
+    <DataStore class="org.apache.jackrabbit.core.data.FileDataStore"/>\r
+\r
+    <!--\r
+        security configuration\r
+    -->\r
+    <Security appName="Jackrabbit">\r
+        <!--\r
+            security manager:\r
+            class: FQN of class implementing the JackrabbitSecurityManager interface\r
+        -->\r
+        <SecurityManager class="org.apache.jackrabbit.core.DefaultSecurityManager" workspaceName="security">\r
+            <!--\r
+            workspace access:\r
+            class: FQN of class implementing the WorkspaceAccessManager interface\r
+            -->\r
+            <!-- <WorkspaceAccessManager class="..."/> -->\r
+            <WorkspaceAccessManager class="org.apache.jackrabbit.core.security.simple.SimpleWorkspaceAccessManager" />\r
+            <!-- <param name="config" value="${rep.home}/security.xml"/> -->\r
+        </SecurityManager>\r
+\r
+        <!--\r
+            access manager:\r
+            class: FQN of class implementing the AccessManager interface\r
+        -->\r
+       <!--\r
+        <AccessManager class="org.apache.jackrabbit.core.security.DefaultAccessManager">\r
+       -->\r
+        <AccessManager class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager">\r
+            <!-- <param name="config" value="${rep.home}/access.xml"/> -->\r
+        </AccessManager>\r
+\r
+        <LoginModule class="org.apache.jackrabbit.core.security.authentication.DefaultLoginModule">\r
+           <!-- \r
+              anonymous user name ('anonymous' is the default value)\r
+            -->\r
+           <param name="anonymousId" value="anonymous"/>\r
+           <!--\r
+              administrator user id (default value if param is missing is 'admin')\r
+            -->\r
+           <param name="adminId" value="admin"/>\r
+        </LoginModule>\r
+    </Security>\r
+\r
+    <!--\r
+        location of workspaces root directory and name of default workspace\r
+    -->\r
+    <Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default"/>\r
+    <!--\r
+        workspace configuration template:\r
+        used to create the initial workspace if there's no workspace yet\r
+    -->\r
+    <Workspace name="${wsp.name}">\r
+        <!--\r
+            virtual file system of the workspace:\r
+            class: FQN of class implementing the FileSystem interface\r
+        -->\r
+        <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">\r
+            <param name="path" value="${wsp.home}"/>\r
+        </FileSystem>\r
+        <!--\r
+            persistence manager of the workspace:\r
+            class: FQN of class implementing the PersistenceManager interface\r
+        -->\r
+        <PersistenceManager class="org.apache.jackrabbit.core.persistence.pool.DerbyPersistenceManager">\r
+          <param name="url" value="jdbc:derby:${wsp.home}/db;create=true"/>\r
+          <param name="schemaObjectPrefix" value="${wsp.name}_"/>\r
+        </PersistenceManager>\r
+        <!--\r
+            Search index and the file system it uses.\r
+            class: FQN of class implementing the QueryHandler interface\r
+        -->\r
+        <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">\r
+            <param name="path" value="${wsp.home}/index"/>\r
+            <param name="supportHighlighting" value="true"/>\r
+        </SearchIndex>\r
+    </Workspace>\r
+\r
+    <!--\r
+        Configures the versioning\r
+    -->\r
+    <Versioning rootPath="${rep.home}/version">\r
+        <!--\r
+            Configures the filesystem to use for versioning for the respective\r
+            persistence manager\r
+        -->\r
+        <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">\r
+            <param name="path" value="${rep.home}/version" />\r
+        </FileSystem>\r
+\r
+        <!--\r
+            Configures the persistence manager to be used for persisting version state.\r
+            Please note that the current versioning implementation is based on\r
+            a 'normal' persistence manager, but this could change in future\r
+            implementations.\r
+        -->\r
+        <!--\r
+        <PersistenceManager class="org.apache.jackrabbit.core.persistence.pool.DerbyPersistenceManager">\r
+          <param name="url" value="jdbc:derby:${rep.home}/version/db;create=true"/>\r
+          <param name="schemaObjectPrefix" value="version_"/>\r
+        </PersistenceManager>\r
+        -->\r
+        <PersistenceManager class="org.apache.jackrabbit.core.state.xml.XMLPersistenceManager" />\r
+    </Versioning>\r
+\r
+    <!--\r
+        Search index for content that is shared repository wide\r
+        (/jcr:system tree, contains mainly versions)\r
+    -->\r
+    <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">\r
+        <param name="path" value="${rep.home}/repository/index"/>\r
+        <param name="supportHighlighting" value="true"/>\r
+    </SearchIndex>\r
+\r
+    <!--\r
+        Run with a cluster journal\r
+    -->\r
+    <Cluster id="node1">\r
+        <Journal class="org.apache.jackrabbit.core.journal.MemoryJournal"/>\r
+    </Cluster>\r
+</Repository>\r
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/templateHtmlHead.txt b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/resources/templateHtmlHead.txt
new file mode 100644 (file)
index 0000000..afc66ff
--- /dev/null
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<html>
+<head>
+       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/util/DefaultProgramExecutor.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/util/DefaultProgramExecutor.java
new file mode 100644 (file)
index 0000000..e6f1d8d
--- /dev/null
@@ -0,0 +1,24 @@
+package com.wiki.standalone.moxkiriya.util;
+
+import java.awt.Desktop;
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+public class DefaultProgramExecutor {
+       public static void execute(String path) {
+               Desktop desktop = Desktop.getDesktop();
+
+               try {
+                       desktop.open(new File(path));
+               } catch(Exception e) {
+                       try {
+                               desktop.browse(new java.net.URI("file://" + path));
+                       } catch (IOException e1) {
+                               e1.printStackTrace();
+                       } catch (URISyntaxException e1) {
+                               e1.printStackTrace();
+                       }
+               }
+       }
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/util/FileIO.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/util/FileIO.java
new file mode 100644 (file)
index 0000000..5439b7d
--- /dev/null
@@ -0,0 +1,143 @@
+/**
+ * Moxkiriya standalone Wiki.
+ * File IO utility.
+ * 
+ * @author Ryuhei Terada
+ * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
+ */
+package com.wiki.standalone.moxkiriya.util;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.StringReader;
+
+/**
+ * ファイル IO utilityクラス
+ *
+ */
+public class FileIO {
+       /**
+        * バッファreaderを生成する。文字セットは"UTF-8"を指定する。
+        * @param stringReader
+        * @return 生成したバッファreader
+        * @throws Exception
+        */
+       public static BufferedReader bufferedReader(StringReader stringReader)
+                       throws Exception {
+               return new BufferedReader(stringReader);
+       }
+
+       /**
+        * バッファreaderを生成する。文字セットは"UTF-8"を指定する。
+        * @param pathname
+        * @return 生成したバッファreader
+        * @throws Exception
+        */
+       public static BufferedReader bufferedReader(String pathname)
+                       throws Exception {
+               return bufferedReader(pathname, "UTF-8");
+       }
+
+       /**
+        * charsetNameで指定された文字セットのバッファreaderを生成する
+        * @param pathname
+        * @param charsetName
+        * @return 生成したバッファreader
+        * @throws Exception
+        */
+       public static BufferedReader bufferedReader(String pathname, String charsetName)
+                       throws Exception {
+               return bufferedReader(new File(pathname), charsetName);
+       }
+
+       /**
+        * バッファreaderを生成する。文字セットは"UTF-8"を指定する。
+        * @param file
+        * @return 生成したバッファreader
+        * @throws Exception
+        */
+       public static BufferedReader bufferedReader(File file)
+                       throws Exception {
+               return bufferedReader(file, "UTF-8");
+       }
+
+       /**
+        * charsetNameで指定された文字セットのバッファreaderを生成する。
+        * @param file
+        * @param charsetName
+        * @return 生成したバッファreader
+        * @throws Exception
+        */
+       public static BufferedReader bufferedReader(File file, String charsetName)
+                       throws Exception {
+               BufferedReader    reader = null;
+               if(file.exists() == true) {
+                       FileInputStream   inputStream   = new FileInputStream(file);
+                       InputStreamReader streamReader  = new InputStreamReader(inputStream, charsetName);
+                       reader = new BufferedReader(streamReader);
+               }
+               
+               return reader;
+       }
+
+       /**
+        * バッファwriterを生成する。文字セットは"UTF-8"を指定する。
+        * @param pathname
+        * @return 生成したバッファwriter
+        * @throws Exception
+        */
+       public static BufferedWriter bufferedWriter(String pathname)
+                       throws Exception {
+               return bufferedWriter(pathname, "UTF-8");
+       }
+
+       /**
+        * charsetNameで指定された文字セットのバッファwriterを生成する
+        * @param pathname
+        * @param charsetName
+        * @return 生成したバッファwriter
+        * @throws Exception
+        */
+       public static BufferedWriter bufferedWriter(String pathname, String charsetName)
+                       throws Exception {
+               return bufferedWriter(new File(pathname), charsetName);
+       }
+
+       /**
+        * バッファwriterを生成する。文字セットは"UTF-8"を指定する。
+        * @param file
+        * @return 生成したバッファwriter
+        * @throws Exception
+        */
+       public static BufferedWriter bufferedWriter(File file)
+                       throws Exception {
+               return bufferedWriter(file, "UTF-8");
+       }
+
+       /**
+        * charsetNameで指定された文字セットのバッファwriterを生成する。
+        * @param file
+        * @param charsetName
+        * @return 生成したバッファwriter
+        * @throws Exception
+        */
+       public static BufferedWriter bufferedWriter(File file, String charsetName)
+                       throws Exception {
+               BufferedWriter    writer = null;
+               if(file.exists() != true) {
+                       file.createNewFile();
+               }
+
+               FileOutputStream  outputStream  = new FileOutputStream(file);
+               OutputStreamWriter streamReader = new OutputStreamWriter(outputStream, charsetName);
+               writer = new BufferedWriter(streamReader);
+               
+               return writer;
+       }
+
+}
diff --git a/Moxkiriya7/src/com/wiki/standalone/moxkiriya/util/FileTypeDeterminator.java b/Moxkiriya7/src/com/wiki/standalone/moxkiriya/util/FileTypeDeterminator.java
new file mode 100644 (file)
index 0000000..f0aeb59
--- /dev/null
@@ -0,0 +1,40 @@
+package com.wiki.standalone.moxkiriya.util;
+
+import java.util.ArrayList;
+
+/**
+ * File種別を判定する。
+ */
+public class FileTypeDeterminator {
+       /**
+        * 画像ファイルと判定する拡張子のリスト
+        */
+       private final static ArrayList<String> imageExtensionList = new ArrayList<String>() {
+               private static final long serialVersionUID = 1L;
+               { add(".jpg"); }
+               { add(".png"); }
+               { add(".gif"); }
+       };
+       
+       /**
+        * ファイルが画像ファイルか判定する。
+        * @param filename
+        * @return 画像ファイルかどうか
+        */
+       public static boolean isImageFile(String filename) {
+               boolean isImage   = false;
+               
+               if(filename.contains(".") == true) {
+                       String  extension = filename.substring(filename.lastIndexOf("."));
+       
+                       for(String key: imageExtensionList) {
+                               if(extension.equalsIgnoreCase(key) == true) {
+                                       isImage = true;
+                                       break;
+                               }
+                       }
+               }
+
+               return isImage;
+       }
+}