├── .gitignore ├── .gitlab-ci.yml ├── LICENSE ├── README.md ├── argon.iws ├── build.gradle ├── build_release.bat ├── catalog.xml ├── extension.xml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── plugin.dtd ├── plugin.xml ├── settings.gradle └── src ├── main ├── java │ └── de │ │ └── axxepta │ │ └── oxygen │ │ ├── actions │ │ ├── AddDatabaseAction.java │ │ ├── AddNewFileAction.java │ │ ├── BaseXRunQueryAction.java │ │ ├── CheckInAction.java │ │ ├── CheckOutAction.java │ │ ├── CheckOutListSelectionAction.java │ │ ├── CheckedOutFilesAction.java │ │ ├── CloseDialogAction.java │ │ ├── CompareVersionsAction.java │ │ ├── DeleteAction.java │ │ ├── ExportAction.java │ │ ├── FileNameFieldListener.java │ │ ├── NewDirectoryAction.java │ │ ├── NewFileListCellRenderer.java │ │ ├── NewVersionAction.java │ │ ├── OpenFileAction.java │ │ ├── OpenListSelectionAction.java │ │ ├── RefreshTreeAction.java │ │ ├── RenameAction.java │ │ ├── ReplyAuthorCommentAction.java │ │ ├── RollbackVersionAction.java │ │ ├── SaveFileToArgonAction.java │ │ ├── SearchInFilesAction.java │ │ ├── SearchInPathAction.java │ │ └── StoreSnippetSelectionAction.java │ │ ├── api │ │ ├── ArgonConst.java │ │ ├── ArgonEntity.java │ │ ├── ArgonWordConnection.java │ │ ├── BaseXClient.java │ │ ├── BaseXConnectionWrapper.java │ │ ├── BaseXQueryException.java │ │ ├── BaseXResource.java │ │ ├── BaseXSource.java │ │ ├── BaseXType.java │ │ ├── BasexConnection.java │ │ ├── Connection.java │ │ ├── ConnectionUtils.java │ │ ├── MetaInfoDefinition.java │ │ ├── MsgTopic.java │ │ ├── Resource.java │ │ ├── RestConnection.java │ │ ├── TopicHolder.java │ │ └── event │ │ │ ├── ChangedEditorStatusEvent.java │ │ │ ├── ChangedServerStatusEvent.java │ │ │ ├── ConsoleNotifiedEvent.java │ │ │ ├── DeleteFileEvent.java │ │ │ ├── ListDirEvent.java │ │ │ ├── NewDirEvent.java │ │ │ ├── SaveFileEvent.java │ │ │ ├── TemplateUpdateRequestedEvent.java │ │ │ └── TreeNodeRequestedEvent.java │ │ ├── core │ │ ├── ClassFactory.java │ │ ├── ObserverInterface.java │ │ └── SubjectInterface.java │ │ ├── customprotocol │ │ ├── ArgonChooserDialog.java │ │ ├── ArgonChooserListCellRenderer.java │ │ ├── ArgonChooserListModel.java │ │ ├── ArgonEditorsWatchMap.java │ │ ├── ArgonInputURLChooserCustomizer.java │ │ ├── ArgonProcessor.java │ │ ├── ArgonProtocolHandler.java │ │ ├── BaseXByteArrayOutputStream.java │ │ ├── CustomProtocolChooserExtension.java │ │ ├── CustomProtocolURLHandlerExtension.java │ │ └── CustomProtocolURLUtils.java │ │ ├── tree │ │ ├── ArgonPopupMenu.java │ │ ├── ArgonTree.java │ │ ├── ArgonTreeCellRenderer.java │ │ ├── ArgonTreeNode.java │ │ ├── ArgonTreeTransferHandler.java │ │ ├── ArgonTreeTransferable.java │ │ ├── TreeListener.java │ │ ├── TreePane.java │ │ └── TreeUtils.java │ │ ├── utils │ │ ├── ConnectionWrapper.java │ │ ├── DialogTools.java │ │ ├── FileUtils.java │ │ ├── IOUtils.java │ │ ├── ImageUtils.java │ │ ├── Lang.java │ │ ├── NoDatabaseConnectionException.java │ │ ├── StringUtils.java │ │ ├── URLUtils.java │ │ ├── WorkspaceUtils.java │ │ └── XMLUtils.java │ │ ├── versioncontrol │ │ ├── DateTableCellRenderer.java │ │ ├── VersionControlListSelectionListener.java │ │ ├── VersionHistoryEntry.java │ │ ├── VersionHistoryPanel.java │ │ ├── VersionHistoryTableModel.java │ │ └── VersionHistoryUpdater.java │ │ └── workspace │ │ ├── ArgonEditorChangeListener.java │ │ ├── ArgonEditorListener.java │ │ ├── ArgonOptionListener.java │ │ ├── ArgonOptionPage.java │ │ ├── ArgonToolbarComponentCustomizer.java │ │ ├── ArgonValidationProblemsFilter.java │ │ ├── ArgonWorkspaceAccessPluginExtension.java │ │ ├── DitaMapManagerChangeListener.java │ │ └── WorkspaceAccessPlugin.java ├── resources │ ├── Argon_de_DE.properties │ ├── Argon_en_GB.properties │ ├── api │ │ ├── MetaTemplate.xml │ │ ├── checked-out-files.xq │ │ ├── create-database.xq │ │ ├── delete-database.xq │ │ ├── delete-repo.xq │ │ ├── delete-restxq.xq │ │ ├── drop-database.xq │ │ ├── exists-database.xq │ │ ├── exists-repo.xq │ │ ├── exists-restxq.xq │ │ ├── find-database.xq │ │ ├── get-database.xq │ │ ├── get-history.xq │ │ ├── get-repo.xq │ │ ├── get-restxq.xq │ │ ├── init.xq │ │ ├── list-database.xq │ │ ├── list-repo.xq │ │ ├── list-restxq.xq │ │ ├── listall-database.xq │ │ ├── listall-repo.xq │ │ ├── listall-restxq.xq │ │ ├── lock.xq │ │ ├── locked.xq │ │ ├── lockedByUser.xq │ │ ├── newdir-repo.xq │ │ ├── newdir-restxq.xq │ │ ├── no-lock-set.xq │ │ ├── parse-repo.xq │ │ ├── parse-restxq.xq │ │ ├── parse.xq │ │ ├── put-database.xq │ │ ├── put-repo.xq │ │ ├── put-restxq.xq │ │ ├── rename-database.xq │ │ ├── rename-repo.xq │ │ ├── rename-restxq.xq │ │ ├── search-attributes.xq │ │ ├── search-attrvalues.xq │ │ ├── search-database.xq │ │ ├── search-elements.xq │ │ ├── search-repo.xq │ │ ├── search-restxq.xq │ │ ├── search-text.xq │ │ ├── unlock.xq │ │ └── users.xq │ ├── i18n │ │ └── translation.xml │ ├── images │ │ ├── AddDb.png │ │ ├── AddDb16.png │ │ ├── AddDir.png │ │ ├── AddFile16.gif │ │ ├── AddFile16.png │ │ ├── BaseX24.png │ │ ├── BaseX24add.png │ │ ├── BaseX_16_tr.png │ │ ├── BaseXadd.png │ │ ├── BaseXlocked.png │ │ ├── DBHttp16.png │ │ ├── DbCatalog16.gif │ │ ├── DbCatalog16.png │ │ ├── DbCatalogF16.png │ │ ├── DbCatalogP16.png │ │ ├── DbCatalogS16.png │ │ ├── DbCatalogShared16.png │ │ ├── DbCatalogT16.png │ │ ├── DbCatalogTeam16.png │ │ ├── DbConnection16.gif │ │ ├── DbFolder16.png │ │ ├── Export16.png │ │ ├── FolderClosed16.png │ │ ├── IncVersion.png │ │ ├── IncVersion16.png │ │ ├── InsertTemplate16.png │ │ ├── OpenURL16.gif │ │ ├── Oxygen16.png │ │ ├── Refresh16.png │ │ ├── Remove16.png │ │ ├── Rename16.png │ │ ├── ReplyComment.png │ │ ├── RunQuery.png │ │ ├── SearchInFiles16.png │ │ ├── SearchInPath16.png │ │ ├── UpdateSingleDocument16.png │ │ ├── VerHistory.png │ │ ├── browseCMS.png │ │ ├── file16.png │ │ ├── snippet.png │ │ ├── txt16.png │ │ ├── unlock.png │ │ └── xml16.png │ └── log4j2.xml └── webapp │ └── WEB-INF │ └── web.xml └── test └── java └── de └── axxepta └── oxygen ├── api └── ArgonRestConnectionTest.java └── customprotocol ├── ArgonChooserDialogTest.java └── CustomProtocolURLUtilsTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | #built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Windows thumbnail db 19 | Thumbs.db 20 | 21 | # OSX files 22 | .DS_Store 23 | 24 | # Eclipse project files 25 | .classpath 26 | .project 27 | 28 | # Android Studio 29 | .idea 30 | #.idea/workspace.xml - remove # and delete .idea if it better suit your needs. 31 | .gradle 32 | build/ 33 | *.iml 34 | 35 | *.pydevproject 36 | .metadata 37 | .gradle 38 | bin/ 39 | tmp/ 40 | *.tmp 41 | *.bak 42 | *.swp 43 | *~.nib 44 | local.properties 45 | .settings/ 46 | .loadpath 47 | 48 | # Eclipse Core 49 | .project 50 | 51 | # External tool builders 52 | .externalToolBuilders/ 53 | 54 | # Locally stored "Eclipse launch configurations" 55 | *.launch 56 | 57 | # CDT-specific 58 | .cproject 59 | 60 | # JDT-specific (Eclipse Java Development Tools) 61 | .classpath 62 | 63 | # Java annotation processor (APT) 64 | .factorypath 65 | 66 | # PDT-specific 67 | .buildpath 68 | 69 | # sbteclipse plugin 70 | .target 71 | 72 | # TeXlipse plugin 73 | .texlipse 74 | /*.ipr 75 | /work_resources 76 | /src/main/java/de/axxepta/oxygen/actions/MetaBuild.java 77 | out 78 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: mohamnag/gradle 2 | 3 | stages: 4 | - test 5 | - deploy 6 | 7 | gradlebuild: 8 | stage: test 9 | script: 10 | - gradle -q build 11 | except: 12 | - /^release-.*$/ # use regexp ;-) 13 | tags: 14 | - docker 15 | 16 | releasebuild: 17 | stage: test 18 | script: 19 | - gradle -q build 20 | - mkdir -p Argon 21 | - cp -r build/libs Argon/ 22 | - cp -r build/resources Argon/ 23 | - cp build/resources/main/plugin.xml Argon/ 24 | - apt-get update 25 | - apt-get install -y --no-install-recommends zip 26 | - zip -r -1 Argon Argon && curl -T Argon.zip ftp://basex.io/Argon.zip --user $CREDENTIALS 27 | 28 | only: 29 | - /^release-.*$/ # use regexp ;-) 30 | tags: 31 | - docker 32 | # artifacts: 33 | # paths: 34 | # - Argon 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 axxepta solutions GmbH 4 | Copyright (c) 2017 Jarno Elovirta 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Argon Author Oxygen Plugin 2 | 3 | Plugin to Oxygen XML editor to add support for BaseX DB. 4 | 5 | ## License 6 | 7 | Argon Author is licensed for use under [The MIT License][1]. 8 | 9 | [1]: https://opensource.org/licenses/MIT 10 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply plugin: 'maven' 3 | 4 | sourceCompatibility = '1.8' 5 | targetCompatibility = '1.8' 6 | 7 | group = 'de.axxepta.argon' 8 | version = '0.1.1' 9 | 10 | repositories { 11 | mavenCentral() 12 | maven { 13 | url 'http://files.basex.org/maven' 14 | } 15 | maven { 16 | url 'http://oxygenxml.com/maven' 17 | } 18 | flatDir { 19 | dirs 'libs' 20 | } 21 | } 22 | 23 | //configurations { 24 | // releaseJars 25 | //} 26 | 27 | dependencies { 28 | //providedCompile 'javax.servlet:servlet-api:2.5' 29 | //runtime 'javax.servlet:jstl:1.1.2' 30 | compile fileTree(dir: 'libs', include: ['*.jar']) 31 | compile 'com.jidesoft:jide-oss:3.6.7' 32 | compile 'com.sun.jersey:jersey-client:1.9' 33 | compile 'org.basex:basex:8.5.3' 34 | compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.2' 35 | compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.2' 36 | compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.2' 37 | compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.2' 38 | //compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.9.2' 39 | compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3' 40 | compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.3' 41 | compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.3' 42 | compile group: 'com.google.guava', name: 'guava', version: '23.4-jre' 43 | compile group: 'com.oxygenxml', name: 'oxygen', version: '19.1.0.1' 44 | compile group: 'com.oxygenxml', name: 'oxygen-sdk', version: '19.1.0.1' 45 | 46 | testCompile group: 'junit', name: 'junit', version: '4.12' 47 | // releaseJars 'com.sun.jersey:jersey-client:1.9' 48 | // releaseJars 'com.jidesoft:jide-oss:3.6.7' 49 | // releaseJars 'org.basex:basex:8.5.3' 50 | // releaseJars 'org.apache.logging.log4j:log4j-api:2.3' 51 | // releaseJars 'org.apache.logging.log4j:log4j-core:2.3' 52 | } 53 | 54 | //task copyToLib( type: Copy ) { 55 | // into "$buildDir/libs/lib" 56 | // from configurations.releaseJars 57 | //} 58 | 59 | //jar { 60 | // dependsOn copyToLib 61 | //} 62 | 63 | task dist(type: Zip, dependsOn: jar) { 64 | from (configurations.runtime.allArtifacts.files) { 65 | into "lib" 66 | } 67 | from (configurations.runtime) { 68 | into "lib" 69 | exclude "oxygen-*.jar" 70 | } 71 | from (".") { 72 | include "LICENSE" 73 | include "extension.xml" 74 | include "plugin.xml" 75 | include "catalog.xml" 76 | } 77 | from ("src/main/resources") { 78 | include "images/**" 79 | } 80 | from ("src/main/resources") { 81 | include "i18n/**" 82 | } 83 | archiveName "${project.name}-${project.version}.zip" 84 | } 85 | -------------------------------------------------------------------------------- /build_release.bat: -------------------------------------------------------------------------------- 1 | set versionnumber=10 2 | copy extension.xml build\release 3 | copy plugin.xml build\release\project-argon 4 | del build\release\project-argon\libs\argon*.jar 5 | xcopy build\libs build\release\project-argon\libs\ /Y/S/I 6 | xcopy build\resources\main build\release\project-argon\resources /Y/S/I 7 | cd build\release 8 | jar cvf Argon-0.0.%versionnumber%.jar project-argon 9 | cd ..\.. -------------------------------------------------------------------------------- /catalog.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /extension.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 0.1.0 8 | 17.0+ 9 | plugin 10 | Jarno Elovirta 11 | Kuhnuri Author 12 | 13 | 14 | 15 | Kuhnuri Author plugin 16 | 17 | 18 |
19 |

This plugin provides integration of the open source database system BaseX into the <oXygen/> workspace. 20 | Databases can be browsed in a tree view and BaseX can be used as version control system.

21 |

For more details see http://www.argon-author.com 24 |

25 |
26 | 27 | 28 |
29 | 52 |
53 |
54 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Apr 02 17:01:42 CEST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-all.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /plugin.dtd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'author' 2 | 3 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/AddDatabaseAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.api.BaseXSource; 4 | import de.axxepta.oxygen.utils.ConnectionWrapper; 5 | import de.axxepta.oxygen.utils.DialogTools; 6 | import de.axxepta.oxygen.utils.Lang; 7 | import org.apache.logging.log4j.LogManager; 8 | import org.apache.logging.log4j.Logger; 9 | import ro.sync.ecss.extensions.api.component.AuthorComponentFactory; 10 | import ro.sync.exml.workspace.api.PluginWorkspaceProvider; 11 | 12 | import javax.swing.*; 13 | import java.awt.*; 14 | import java.awt.event.ActionEvent; 15 | import java.awt.event.KeyEvent; 16 | import java.io.IOException; 17 | 18 | /** 19 | * @author Markus on 04.11.2015. 20 | */ 21 | public class AddDatabaseAction extends AbstractAction { 22 | 23 | private static final Logger logger = LogManager.getLogger(AddDatabaseAction.class); 24 | 25 | private JDialog addDbDialog; 26 | private JTextField newDbNameTextField; 27 | 28 | public AddDatabaseAction(String name, Icon icon) { 29 | super(name, icon); 30 | } 31 | 32 | public AddDatabaseAction() { 33 | super(); 34 | } 35 | 36 | @Override 37 | public void actionPerformed(ActionEvent e) { 38 | JFrame parentFrame = (JFrame) ((new AuthorComponentFactory()).getWorkspaceUtilities().getParentFrame()); 39 | 40 | addDbDialog = DialogTools.getOxygenDialog(parentFrame, Lang.get(Lang.Keys.cm_adddb)); 41 | 42 | JPanel content = new JPanel(new BorderLayout(10, 10)); 43 | 44 | AddDbAction addDB = new AddDbAction(Lang.get(Lang.Keys.cm_addsimple)); 45 | 46 | newDbNameTextField = new JTextField(); 47 | newDbNameTextField.getDocument().addDocumentListener(new FileNameFieldListener(newDbNameTextField, true)); 48 | content.add(newDbNameTextField, BorderLayout.NORTH); 49 | 50 | newDbNameTextField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "confirm"); 51 | newDbNameTextField.getActionMap().put("confirm", addDB); 52 | 53 | JPanel btnPanel = new JPanel(); 54 | JButton addBtn = new JButton(addDB); 55 | btnPanel.add(addBtn, BorderLayout.WEST); 56 | JButton cancelBtn = new JButton(new CloseDialogAction(Lang.get(Lang.Keys.cm_cancel), addDbDialog)); 57 | btnPanel.add(cancelBtn, BorderLayout.EAST); 58 | content.add(btnPanel, BorderLayout.SOUTH); 59 | 60 | DialogTools.wrapAndShow(addDbDialog, content, parentFrame); 61 | } 62 | 63 | private class AddDbAction extends AbstractAction { 64 | 65 | AddDbAction(String name) { 66 | super(name); 67 | } 68 | 69 | @Override 70 | public void actionPerformed(ActionEvent e) { 71 | String db = newDbNameTextField.getText(); 72 | try { // not the nice way, but catch exception with no database error message 73 | ConnectionWrapper.list(BaseXSource.DATABASE, db); 74 | PluginWorkspaceProvider.getPluginWorkspace().showErrorMessage(Lang.get(Lang.Keys.msg_dbexists1) + "\n " + 75 | Lang.get(Lang.Keys.msg_dbexists2)); 76 | } catch (IOException ie) { 77 | try { 78 | ConnectionWrapper.create(db); 79 | } catch (IOException ex) { 80 | PluginWorkspaceProvider.getPluginWorkspace().showErrorMessage(Lang.get(Lang.Keys.warn_failednewdb) + 81 | " " + ex.getMessage()); 82 | logger.debug(ex.getMessage()); 83 | } 84 | } 85 | addDbDialog.dispose(); 86 | } 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/CheckInAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.api.BaseXConnectionWrapper; 4 | import de.axxepta.oxygen.api.BaseXSource; 5 | import de.axxepta.oxygen.api.Connection; 6 | import de.axxepta.oxygen.customprotocol.ArgonEditorsWatchMap; 7 | import de.axxepta.oxygen.customprotocol.CustomProtocolURLUtils; 8 | import de.axxepta.oxygen.tree.TreeListener; 9 | import de.axxepta.oxygen.tree.TreeUtils; 10 | import org.apache.logging.log4j.LogManager; 11 | import org.apache.logging.log4j.Logger; 12 | import ro.sync.exml.workspace.api.PluginWorkspaceProvider; 13 | import ro.sync.exml.workspace.api.editor.WSEditor; 14 | 15 | import javax.swing.*; 16 | import java.awt.event.ActionEvent; 17 | import java.io.IOException; 18 | import java.net.MalformedURLException; 19 | import java.net.URL; 20 | 21 | import static ro.sync.exml.workspace.api.PluginWorkspace.MAIN_EDITING_AREA; 22 | 23 | 24 | /** 25 | * @author Markus on 07.06.2016 26 | */ 27 | public class CheckInAction extends AbstractAction { 28 | 29 | private static final Logger logger = LogManager.getLogger(CheckInAction.class); 30 | 31 | private final TreeListener treeListener; 32 | private URL urlString = null; 33 | 34 | public CheckInAction(String name, Icon icon, String urlString, TreeListener treeListener) { 35 | super(name, icon); 36 | 37 | try { 38 | this.urlString = urlString != null ? new URL(urlString) : null; 39 | } catch (MalformedURLException e) { 40 | logger.error(e.getMessage()); 41 | throw new IllegalArgumentException(e.getMessage(), e); 42 | } 43 | this.treeListener = treeListener; 44 | } 45 | 46 | public CheckInAction(String name, Icon icon, TreeListener treeListener) { 47 | this(name, icon, null, treeListener); 48 | } 49 | 50 | public CheckInAction(String name, Icon icon, String urlString) { 51 | this(name, icon, urlString, null); 52 | } 53 | 54 | public CheckInAction(String name, Icon icon) { 55 | this(name, icon, null, null); 56 | } 57 | 58 | @Override 59 | public void actionPerformed(ActionEvent e) { 60 | if (this.urlString != null) { 61 | checkIn(this.urlString); 62 | } else if (treeListener == null) { 63 | final URL url = PluginWorkspaceProvider.getPluginWorkspace(). 64 | getCurrentEditorAccess(MAIN_EDITING_AREA).getEditorLocation(); 65 | checkIn(url); 66 | } else if (!treeListener.getNode().getAllowsChildren()) { 67 | final String urlString = TreeUtils.urlStringFromTreePath(treeListener.getPath()); 68 | try { 69 | checkIn(new URL(urlString)); 70 | } catch (MalformedURLException ex) { 71 | throw new IllegalArgumentException(ex); 72 | } 73 | } 74 | } 75 | 76 | static void checkIn(URL url) { 77 | final BaseXSource source = CustomProtocolURLUtils.sourceFromURL(url); 78 | final String path = CustomProtocolURLUtils.pathFromURL(url); 79 | try (Connection connection = BaseXConnectionWrapper.getConnection()) { 80 | if (connection.lockedByUser(source, path)) { 81 | ArgonEditorsWatchMap.getInstance().setAskedForCheckIn(url, true); 82 | if (false) { 83 | final WSEditor editorAccess = PluginWorkspaceProvider.getPluginWorkspace(). 84 | getEditorAccess(url, MAIN_EDITING_AREA); 85 | if (editorAccess != null) { 86 | editorAccess.close(true); 87 | } 88 | } 89 | connection.unlock(source, path); 90 | } 91 | } catch (IOException ex) { 92 | logger.debug(ex); 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/CheckOutAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.api.BaseXConnectionWrapper; 4 | import de.axxepta.oxygen.api.Connection; 5 | import de.axxepta.oxygen.customprotocol.ArgonEditorsWatchMap; 6 | import de.axxepta.oxygen.customprotocol.CustomProtocolURLUtils; 7 | import de.axxepta.oxygen.tree.TreeListener; 8 | import de.axxepta.oxygen.tree.TreeUtils; 9 | import de.axxepta.oxygen.utils.WorkspaceUtils; 10 | import org.apache.logging.log4j.LogManager; 11 | import org.apache.logging.log4j.Logger; 12 | import ro.sync.exml.workspace.api.PluginWorkspaceProvider; 13 | 14 | import javax.swing.*; 15 | import java.awt.event.ActionEvent; 16 | import java.io.IOException; 17 | import java.net.URL; 18 | 19 | import static ro.sync.exml.workspace.api.PluginWorkspace.MAIN_EDITING_AREA; 20 | 21 | /** 22 | * @author Markus on 07.07.2016. 23 | */ 24 | public class CheckOutAction extends AbstractAction { 25 | 26 | private static final Logger logger = LogManager.getLogger(CheckOutAction.class); 27 | 28 | private final TreeListener treeListener; 29 | private String urlString = null; 30 | 31 | public CheckOutAction(String name, Icon icon, String urlString, TreeListener treeListener) { 32 | super(name, icon); 33 | this.urlString = urlString; 34 | this.treeListener = treeListener; 35 | } 36 | 37 | public CheckOutAction(String name, Icon icon, TreeListener treeListener) { 38 | this(name, icon, null, treeListener); 39 | // super(name, icon); 40 | // this.treeListener = treeListener; 41 | } 42 | 43 | public CheckOutAction(String name, Icon icon) { 44 | this(name, icon, null, null); 45 | // super(name, icon); 46 | // treeListener = null; 47 | } 48 | 49 | public CheckOutAction(String name, Icon icon, String urlString) { 50 | this(name, icon, urlString, null); 51 | // super(name, icon); 52 | // treeListener = null; 53 | // this.urlString = urlString; 54 | } 55 | 56 | @Override 57 | public void actionPerformed(ActionEvent e) { 58 | if (this.urlString != null) { 59 | checkOut(this.urlString); 60 | } else if (treeListener == null) { 61 | final URL url = PluginWorkspaceProvider.getPluginWorkspace(). 62 | getCurrentEditorAccess(MAIN_EDITING_AREA).getEditorLocation(); 63 | checkOut(url.toString()); 64 | } else if (!treeListener.getNode().getAllowsChildren()) { 65 | final String urlString = TreeUtils.urlStringFromTreePath(treeListener.getPath()); 66 | checkOut(urlString); 67 | } 68 | } 69 | 70 | // @SuppressWarnings("all") 71 | public static void checkOut(String urlString) { 72 | try (Connection connection = BaseXConnectionWrapper.getConnection()) { 73 | connection.lock(CustomProtocolURLUtils.sourceFromURLString(urlString), 74 | CustomProtocolURLUtils.pathFromURLString(urlString)); 75 | ArgonEditorsWatchMap.getInstance().addURL(new URL(urlString), true); 76 | } catch (IOException ex) { 77 | logger.debug(ex); 78 | } 79 | WorkspaceUtils.openURLString(urlString); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/CheckOutListSelectionAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.tree.TreeUtils; 4 | 5 | import javax.swing.*; 6 | import java.awt.event.ActionEvent; 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * @author Markus on 11.07.2016. 11 | */ 12 | 13 | // made public for access via AspectJ 14 | //@SuppressWarnings("all") 15 | public class CheckOutListSelectionAction extends AbstractAction { 16 | 17 | private final JList results; 18 | private final JDialog resultsDialog; 19 | 20 | public CheckOutListSelectionAction(String name, JList results, JDialog resultsDialog) { 21 | super(name); 22 | this.results = results; 23 | this.resultsDialog = resultsDialog; 24 | } 25 | 26 | @Override 27 | public void actionPerformed(ActionEvent e) { 28 | final ArrayList selectedResources = new ArrayList<>(results.getSelectedValuesList()); 29 | 30 | for (Object resource : selectedResources) { 31 | final String db_path = TreeUtils.urlStringFromTreeString(resource.toString()); 32 | CheckOutAction.checkOut(db_path); 33 | } 34 | resultsDialog.dispose(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/CheckedOutFilesAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.api.*; 4 | import de.axxepta.oxygen.utils.DialogTools; 5 | import de.axxepta.oxygen.utils.Lang; 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | import ro.sync.ecss.extensions.api.component.AuthorComponentFactory; 9 | 10 | import javax.swing.*; 11 | import java.awt.*; 12 | import java.awt.event.ActionEvent; 13 | import java.awt.event.KeyEvent; 14 | import java.io.IOException; 15 | import java.net.MalformedURLException; 16 | import java.net.URL; 17 | import java.util.Collections; 18 | import java.util.List; 19 | 20 | /** 21 | * @author Markus on 11.07.2016. 22 | */ 23 | public class CheckedOutFilesAction extends AbstractAction { 24 | 25 | private static final Logger logger = LogManager.getLogger(CheckedOutFilesAction.class); 26 | 27 | public CheckedOutFilesAction() { 28 | super(); 29 | } 30 | 31 | @Override 32 | public void actionPerformed(ActionEvent e) { 33 | List files = getCheckedOutFiles(); 34 | if (files.size() > 0) { 35 | showDialog(files); 36 | } 37 | } 38 | 39 | private void showDialog(List files) { 40 | JFrame parentFrame = (JFrame) ((new AuthorComponentFactory()).getWorkspaceUtilities().getParentFrame()); 41 | 42 | final ResourceListModel listModel = new ResourceListModel(files); 43 | final JList resultList = new JList(listModel); 44 | 45 | final JDialog resultsDialog = DialogTools.getOxygenDialog(parentFrame, Lang.get(Lang.Keys.dlg_checkedout)); 46 | 47 | AbstractAction checkInAction = new AbstractAction(Lang.get(Lang.Keys.cm_checkinselected)) { 48 | @Override 49 | public void actionPerformed(ActionEvent e) { 50 | for (int fileIndex : resultList.getSelectedIndices()) { 51 | try { 52 | URL url = new URL((String) listModel.getElementAt(fileIndex)); 53 | CheckInAction.checkIn(url); 54 | } catch (MalformedURLException mue) { 55 | logger.debug("Failed to get URL from selected item. ", mue.getMessage()); 56 | } 57 | } 58 | resultsDialog.dispose(); 59 | } 60 | }; 61 | 62 | JPanel content = SearchInPathAction.createSelectionListPanel(Lang.get(Lang.Keys.lbl_filestocheck), resultList); 63 | resultList.setSelectionInterval(0, resultList.getModel().getSize() - 1); 64 | resultList.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "confirm"); 65 | resultList.getActionMap().put("confirm", checkInAction); 66 | 67 | JPanel buttonsPanel = new JPanel(); 68 | JButton checkInButton = new JButton(checkInAction); 69 | buttonsPanel.add(checkInButton); 70 | JButton exitButton = new JButton(new CloseDialogAction(Lang.get(Lang.Keys.cm_exit), resultsDialog)); 71 | buttonsPanel.add(exitButton); 72 | content.add(buttonsPanel, BorderLayout.SOUTH); 73 | 74 | DialogTools.wrapAndShow(resultsDialog, content, parentFrame, 500, 300); 75 | } 76 | 77 | private static List getCheckedOutFiles() { 78 | // final List fileList = new ArrayList<>(); 79 | // String checkedOut; 80 | try (Connection connection = BaseXConnectionWrapper.getConnection()) { 81 | // FIXME this should just get a list of all checked-out files 82 | // checkedOut = connection.xquery(ConnectionUtils.getQuery("checked-out-files")); 83 | return Collections.emptyList(); 84 | } catch (IOException ioe) { 85 | logger.debug("Failed to get list of checked out files. ", ioe.getMessage()); 86 | return Collections.emptyList(); 87 | } 88 | // if (!checkedOut.equals("")) { 89 | // final String[] results = checkedOut.split("\r?\n"); 90 | // for (int r = 0, rl = results.length; r < rl; r += 2) { 91 | // fileList.add(new BaseXResource(results[r + 1], BaseXType.RESOURCE, BaseXSource.get(results[r]))); 92 | // } 93 | // } 94 | // return fileList; 95 | } 96 | 97 | 98 | private class ResourceListModel extends AbstractListModel { 99 | 100 | private final List data; 101 | 102 | ResourceListModel(List data) { 103 | this.data = data; 104 | } 105 | 106 | @Override 107 | public int getSize() { 108 | return data.size(); 109 | } 110 | 111 | @Override 112 | public Object getElementAt(int index) { 113 | return data.get(index).getURLString(); 114 | } 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/CloseDialogAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import javax.swing.*; 4 | import java.awt.event.ActionEvent; 5 | 6 | /** 7 | * @author by Markus on 21.10.2015. 8 | */ 9 | @SuppressWarnings("all") 10 | public class CloseDialogAction extends AbstractAction { 11 | 12 | private JDialog dialog; 13 | 14 | public CloseDialogAction(String name, JDialog dialog) { 15 | super(name); 16 | this.dialog = dialog; 17 | } 18 | 19 | @Override 20 | public void actionPerformed(ActionEvent e) { 21 | dialog.dispose(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/DeleteAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.api.BaseXConnectionWrapper; 4 | import de.axxepta.oxygen.api.BaseXSource; 5 | import de.axxepta.oxygen.api.Connection; 6 | import de.axxepta.oxygen.tree.ArgonTree; 7 | import de.axxepta.oxygen.tree.TreeUtils; 8 | import de.axxepta.oxygen.utils.ConnectionWrapper; 9 | import de.axxepta.oxygen.utils.Lang; 10 | import ro.sync.exml.workspace.api.PluginWorkspace; 11 | import ro.sync.exml.workspace.api.PluginWorkspaceProvider; 12 | 13 | import javax.swing.*; 14 | import javax.swing.tree.DefaultMutableTreeNode; 15 | import javax.swing.tree.DefaultTreeModel; 16 | import javax.swing.tree.TreeModel; 17 | import javax.swing.tree.TreePath; 18 | import java.awt.event.ActionEvent; 19 | 20 | /** 21 | * @author Markus on 24.10.2015. 22 | */ 23 | public class DeleteAction extends AbstractAction { 24 | 25 | private final ArgonTree tree; 26 | private final TreeModel treeModel; 27 | 28 | public DeleteAction(String name, Icon icon, ArgonTree tree) { 29 | super(name, icon); 30 | this.tree = tree; 31 | this.treeModel = tree.getModel(); 32 | } 33 | 34 | public DeleteAction(ArgonTree tree) { 35 | super(); 36 | this.tree = tree; 37 | this.treeModel = tree.getModel(); 38 | } 39 | 40 | @Override 41 | public void actionPerformed(ActionEvent e) { 42 | TreePath[] paths = tree.getSelectionPaths(); 43 | PluginWorkspace pluginWorkspace = PluginWorkspaceProvider.getPluginWorkspace(); 44 | if (paths != null) { 45 | for (TreePath path : paths) { 46 | BaseXSource source = TreeUtils.sourceFromTreePath(path); 47 | String db_path = TreeUtils.resourceFromTreePath(path); 48 | if ((source != null) && (!db_path.equals(""))) { 49 | 50 | if (!ConnectionWrapper.pathContainsLockedResource(source, db_path)) { 51 | 52 | int dialogResult = pluginWorkspace.showConfirmDialog( 53 | Lang.get(Lang.Keys.dlg_delete), 54 | Lang.get(Lang.Keys.lbl_delete) + "\n" + TreeUtils.urlStringFromTreePath(path), 55 | new String[]{Lang.get(Lang.Keys.cm_yes), Lang.get(Lang.Keys.cm_no)}, 56 | new int[]{0, 1}, 0); 57 | if (dialogResult == 0) { 58 | if (TreeUtils.isDB(path)) { 59 | try (Connection connection = BaseXConnectionWrapper.getConnection()) { 60 | connection.drop(db_path); 61 | ((DefaultTreeModel) treeModel).removeNodeFromParent((DefaultMutableTreeNode) path.getLastPathComponent()); 62 | } catch (Exception er) { 63 | pluginWorkspace.showErrorMessage(Lang.get(Lang.Keys.warn_faileddeletedb) + " " + er.getMessage()); 64 | } 65 | } else if (TreeUtils.isDir(path) || TreeUtils.isFile(path)) { 66 | deleteFile(source, db_path, path); 67 | } 68 | } 69 | 70 | } else { 71 | pluginWorkspace.showInformationMessage(Lang.get(Lang.Keys.msg_checkpriordelete)); 72 | } 73 | } 74 | } 75 | } 76 | } 77 | 78 | private void deleteFile(BaseXSource source, String db_path, TreePath path) { 79 | try (Connection connection = BaseXConnectionWrapper.getConnection()) { 80 | connection.delete(source, db_path); 81 | ((DefaultTreeModel) treeModel).removeNodeFromParent((DefaultMutableTreeNode) path.getLastPathComponent()); 82 | } catch (Exception er) { 83 | PluginWorkspaceProvider.getPluginWorkspace().showInformationMessage(Lang.get(Lang.Keys.warn_faileddelete) + 84 | " " + er.getMessage()); 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/FileNameFieldListener.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import javax.swing.*; 4 | import javax.swing.event.DocumentEvent; 5 | import javax.swing.event.DocumentListener; 6 | 7 | /** 8 | * @author Markus on 02.11.2015. 9 | */ 10 | public class FileNameFieldListener implements DocumentListener { 11 | 12 | private final static String FILE_NAME_CHAR_WITH_EXTENSION = "\\w|_|-|\\."; 13 | private final static String FILE_NAME_CHARS_WITH_EXTENSION = "(\\w|_|-|\\.)*"; 14 | private final static String FILE_NAME_CHAR_WITHOUT_EXTENSION = "\\w|_|-"; 15 | public final static String FILE_NAME_CHARS_WITHOUT_EXTENSION = "(\\w|_|-)*"; 16 | 17 | private boolean textFieldResetInProgress; 18 | private final JTextField textField; 19 | private final String fileNameChar; 20 | private final String fileNameChars; 21 | 22 | public FileNameFieldListener(JTextField textField, boolean withExtension) { 23 | this.textField = textField; 24 | if (withExtension) { 25 | fileNameChar = FILE_NAME_CHAR_WITH_EXTENSION; 26 | fileNameChars = FILE_NAME_CHARS_WITH_EXTENSION; 27 | } else { 28 | fileNameChar = FILE_NAME_CHAR_WITHOUT_EXTENSION; 29 | fileNameChars = FILE_NAME_CHARS_WITHOUT_EXTENSION; 30 | } 31 | } 32 | 33 | // check input to filename field, only characters allowed in file names will be adopted 34 | @Override 35 | public void insertUpdate(DocumentEvent e) { 36 | if (!textFieldResetInProgress) { 37 | String name = textField.getText(); 38 | int pos = e.getOffset(); 39 | if (!name.substring(pos, pos + 1).matches(fileNameChar)) { 40 | textFieldResetInProgress = true; 41 | resetTextField(new StringBuilder(name).deleteCharAt(pos).toString()); 42 | java.awt.Toolkit.getDefaultToolkit().beep(); 43 | } 44 | } 45 | } 46 | 47 | @Override 48 | public void removeUpdate(DocumentEvent e) { 49 | } 50 | 51 | // check paste to filename field, only inserts witch all characters allowed in file names will be adopted 52 | @Override 53 | public void changedUpdate(DocumentEvent e) { 54 | if (!textFieldResetInProgress) { 55 | String name = textField.getText(); 56 | int pos = e.getOffset(); 57 | int length = e.getLength(); 58 | if (!name.substring(pos, pos + length).matches(fileNameChars)) { 59 | textFieldResetInProgress = true; 60 | resetTextField(new StringBuilder(name).delete(pos, pos + length).toString()); 61 | java.awt.Toolkit.getDefaultToolkit().beep(); 62 | } 63 | } 64 | } 65 | 66 | private void resetTextField(final String name) { 67 | SwingUtilities.invokeLater(() -> { 68 | textField.setText(name); 69 | textFieldResetInProgress = false; 70 | }); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/NewFileListCellRenderer.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.utils.ImageUtils; 4 | 5 | import javax.swing.*; 6 | import java.awt.*; 7 | 8 | /** 9 | * @author Markus on 27.10.2015. 10 | */ 11 | class NewFileListCellRenderer extends DefaultListCellRenderer { 12 | 13 | @Override 14 | public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 15 | 16 | JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 17 | String fileType = value.toString(); 18 | int ind1 = fileType.indexOf("("); 19 | int ind2 = fileType.indexOf(")"); 20 | String ext = fileType.substring(ind1 + 3, ind2); 21 | Icon icon = ImageUtils.getIcon(ext); 22 | label.setIcon(icon); 23 | return label; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/NewVersionAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.api.ArgonConst; 4 | import de.axxepta.oxygen.api.TopicHolder; 5 | import de.axxepta.oxygen.customprotocol.ArgonEditorsWatchMap; 6 | import de.axxepta.oxygen.customprotocol.CustomProtocolURLHandlerExtension; 7 | import de.axxepta.oxygen.utils.ConnectionWrapper; 8 | import de.axxepta.oxygen.utils.IOUtils; 9 | import de.axxepta.oxygen.utils.Lang; 10 | import de.axxepta.oxygen.utils.WorkspaceUtils; 11 | import de.axxepta.oxygen.versioncontrol.VersionHistoryUpdater; 12 | import org.apache.logging.log4j.LogManager; 13 | import org.apache.logging.log4j.Logger; 14 | import ro.sync.exml.workspace.api.PluginWorkspace; 15 | import ro.sync.exml.workspace.api.PluginWorkspaceProvider; 16 | import ro.sync.exml.workspace.api.editor.WSEditor; 17 | import ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace; 18 | 19 | import javax.swing.*; 20 | import java.awt.event.ActionEvent; 21 | import java.io.IOException; 22 | import java.net.URL; 23 | 24 | /** 25 | * @author Markus on 04.12.2015. 26 | * This action should be called from a toolbar button only if an Argon protocol file is opened in the current editor 27 | * and initiates an update of the version (and revision) number and storage of the file to BaseX. 28 | */ 29 | public class NewVersionAction extends AbstractAction { 30 | 31 | private static final Logger logger = LogManager.getLogger(NewVersionAction.class); 32 | 33 | private static final PluginWorkspace workspace = PluginWorkspaceProvider.getPluginWorkspace(); 34 | 35 | public NewVersionAction(String name, Icon icon) { 36 | super(name, icon); 37 | } 38 | 39 | @Override 40 | public void actionPerformed(ActionEvent e) { 41 | final WSEditor editorAccess = workspace.getCurrentEditorAccess(StandalonePluginWorkspace.MAIN_EDITING_AREA); 42 | final URL url = editorAccess.getEditorLocation(); 43 | if (url.toString().startsWith(ArgonConst.ARGON)) { 44 | final String protocol = url.getProtocol(); 45 | final CustomProtocolURLHandlerExtension handlerExtension = new CustomProtocolURLHandlerExtension(); 46 | if (handlerExtension.canCheckReadOnly(protocol) && !handlerExtension.isReadOnly(url)) { 47 | WorkspaceUtils.setCursor(WorkspaceUtils.WAIT_CURSOR); 48 | final String encoding = ArgonEditorsWatchMap.getInstance().getEncoding(url); 49 | byte[] outputArray = WorkspaceUtils.getEditorByteContent(editorAccess); 50 | if (!encoding.equals("UTF-8")) { 51 | outputArray = IOUtils.convertToUTF8(outputArray, encoding); 52 | } 53 | updateFile(url, outputArray, encoding); 54 | WorkspaceUtils.setCursor(WorkspaceUtils.DEFAULT_CURSOR); 55 | } else { 56 | workspace.showInformationMessage(Lang.get(Lang.Keys.msg_noupdate1) + " " + url.toString() + ".\n" + 57 | Lang.get(Lang.Keys.msg_noupdate2) + "\nActually, you have to check the file out first"); 58 | } 59 | } 60 | } 61 | 62 | private static void updateFile(URL url, byte[] outputArray, String encoding) { 63 | try { 64 | if (IOUtils.isXML(outputArray)) { 65 | ConnectionWrapper.save(url, outputArray, encoding, true); 66 | } else { 67 | ConnectionWrapper.save(true, url, outputArray, true); 68 | } 69 | } catch (IOException ex) { 70 | WorkspaceUtils.setCursor(WorkspaceUtils.DEFAULT_CURSOR); 71 | workspace.showInformationMessage(Lang.get(Lang.Keys.warn_failednewversion) + "\n" + url.toString()); 72 | } 73 | TopicHolder.changedEditorStatus.postMessage(VersionHistoryUpdater.checkVersionHistory(url)); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/OpenFileAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.tree.TreeListener; 4 | import de.axxepta.oxygen.tree.TreeUtils; 5 | import de.axxepta.oxygen.utils.WorkspaceUtils; 6 | 7 | import javax.swing.*; 8 | import java.awt.event.ActionEvent; 9 | 10 | /** 11 | * @author Markus on 20.07.2016. 12 | */ 13 | public class OpenFileAction extends AbstractAction { 14 | 15 | private final TreeListener treeListener; 16 | 17 | public OpenFileAction(String name, Icon icon, TreeListener treeListener) { 18 | super(name, icon); 19 | this.treeListener = treeListener; 20 | } 21 | 22 | @Override 23 | public void actionPerformed(ActionEvent e) { 24 | if (!treeListener.getNode().getAllowsChildren()) { 25 | String db_path = TreeUtils.urlStringFromTreePath(treeListener.getPath()); 26 | WorkspaceUtils.openURLString(db_path); 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/OpenListSelectionAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.utils.WorkspaceUtils; 4 | import org.apache.logging.log4j.LogManager; 5 | import org.apache.logging.log4j.Logger; 6 | import ro.sync.exml.workspace.api.PluginWorkspace; 7 | import ro.sync.exml.workspace.api.PluginWorkspaceProvider; 8 | 9 | import javax.swing.*; 10 | import java.awt.event.ActionEvent; 11 | import java.util.ArrayList; 12 | 13 | /** 14 | * @author Markus on 11.07.2016. 15 | */ 16 | // made public for access via AspectJ 17 | @SuppressWarnings("all") 18 | public class OpenListSelectionAction extends AbstractAction { 19 | 20 | private static final Logger logger = LogManager.getLogger(OpenListSelectionAction.class); 21 | private static final PluginWorkspace wsa = PluginWorkspaceProvider.getPluginWorkspace(); 22 | 23 | JList results; 24 | JDialog resultsDialog; 25 | 26 | public OpenListSelectionAction(String name, JList results, JDialog resultsDialog) { 27 | super(name); 28 | this.results = results; 29 | this.resultsDialog = resultsDialog; 30 | } 31 | 32 | @Override 33 | public void actionPerformed(ActionEvent e) { 34 | ArrayList selectedResources = new ArrayList<>(); 35 | selectedResources.addAll(results.getSelectedValuesList()); 36 | 37 | for (String resource : selectedResources) { 38 | WorkspaceUtils.openURLString(resource); 39 | } 40 | resultsDialog.dispose(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/ReplyAuthorCommentAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.utils.Lang; 4 | import ro.sync.ecss.extensions.api.AuthorAccess; 5 | import ro.sync.ecss.extensions.api.component.AuthorComponentFactory; 6 | import ro.sync.exml.editor.EditorPageConstants; 7 | import ro.sync.exml.workspace.api.PluginWorkspace; 8 | import ro.sync.exml.workspace.api.PluginWorkspaceProvider; 9 | import ro.sync.exml.workspace.api.editor.WSEditor; 10 | import ro.sync.exml.workspace.api.editor.page.WSEditorPage; 11 | import ro.sync.exml.workspace.api.editor.page.author.WSAuthorEditorPage; 12 | import ro.sync.exml.workspace.api.editor.page.text.WSTextEditorPage; 13 | 14 | import javax.swing.*; 15 | import javax.swing.text.BadLocationException; 16 | import javax.swing.text.Document; 17 | import java.awt.event.ActionEvent; 18 | 19 | /** 20 | * Action class for replying to comments in author mode 21 | */ 22 | public class ReplyAuthorCommentAction extends AbstractAction { 23 | 24 | private static final PluginWorkspace workspace = PluginWorkspaceProvider.getPluginWorkspace(); 25 | 26 | public ReplyAuthorCommentAction(String name, Icon icon) { 27 | super(name, icon); 28 | } 29 | 30 | @Override 31 | public void actionPerformed(ActionEvent e) { 32 | WSEditor editorAccess = workspace.getCurrentEditorAccess(PluginWorkspace.MAIN_EDITING_AREA); 33 | if (editorAccess.getCurrentPageID().equals(EditorPageConstants.PAGE_AUTHOR)) { 34 | WSEditorPage editorPage = editorAccess.getCurrentPage(); 35 | AuthorAccess authorAccess = ((WSAuthorEditorPage) editorPage).getAuthorAccess(); 36 | // store current cursor position for later reset 37 | int currentOnset = authorAccess.getEditorAccess().getSelectionStart(); 38 | int currentOffset = authorAccess.getEditorAccess().getCaretOffset(); 39 | // change to Text mode 40 | editorAccess.changePage(EditorPageConstants.PAGE_TEXT); 41 | WSTextEditorPage textPage = (WSTextEditorPage) editorAccess.getCurrentPage(); 42 | // check whether current cursor position is in a comment 43 | int currentPos = textPage.getSelectionStart(); 44 | Document doc = textPage.getDocument(); 45 | String docStr; 46 | try { 47 | docStr = doc.getText(0, doc.getLength()); 48 | } catch (BadLocationException ex) { 49 | docStr = ""; 50 | } 51 | int commentStart = docStr.lastIndexOf(" currentPos) { 55 | // identify position of end of comment attribute in processing instruction 56 | int endCommentEnd = docStr.indexOf("comment=", commentStart); 57 | endCommentEnd = docStr.indexOf("\"", endCommentEnd + 9); 58 | // add response to comment, hiding that you're working in text mode 59 | editorAccess.changePage(EditorPageConstants.PAGE_AUTHOR); 60 | JFrame parentFrame = (JFrame) ((new AuthorComponentFactory()).getWorkspaceUtilities().getParentFrame()); 61 | String reply = JOptionPane.showInputDialog(parentFrame, Lang.get(Lang.Keys.dlg_replycomment), "Review", JOptionPane.PLAIN_MESSAGE); 62 | editorAccess.changePage(EditorPageConstants.PAGE_TEXT); 63 | if (reply != null) { 64 | try { 65 | doc.insertString(endCommentEnd, " ----------------------------- " 66 | + "Response [" + System.getProperty("user.name") + "]: " + reply, null); 67 | } catch (BadLocationException ex) {/*ToDo? should be in safe range due to previous ifs*/} 68 | } 69 | } 70 | } 71 | // back to Author mode 72 | editorAccess.changePage(EditorPageConstants.PAGE_AUTHOR); 73 | ((WSAuthorEditorPage) editorPage).select(currentOnset, currentOffset); 74 | 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/RollbackVersionAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.api.BaseXConnectionWrapper; 4 | import de.axxepta.oxygen.api.BaseXSource; 5 | import de.axxepta.oxygen.api.Connection; 6 | import de.axxepta.oxygen.customprotocol.CustomProtocolURLUtils; 7 | import de.axxepta.oxygen.utils.WorkspaceUtils; 8 | import de.axxepta.oxygen.versioncontrol.VersionHistoryTableModel; 9 | import org.apache.logging.log4j.LogManager; 10 | import org.apache.logging.log4j.Logger; 11 | import ro.sync.exml.workspace.api.PluginWorkspace; 12 | import ro.sync.exml.workspace.api.PluginWorkspaceProvider; 13 | import ro.sync.exml.workspace.api.editor.WSEditor; 14 | 15 | import javax.swing.*; 16 | import javax.swing.text.BadLocationException; 17 | import javax.swing.text.Document; 18 | import java.awt.event.ActionEvent; 19 | import java.io.ByteArrayInputStream; 20 | import java.io.IOException; 21 | import java.io.InputStream; 22 | import java.lang.reflect.InvocationTargetException; 23 | import java.net.URL; 24 | import java.util.Scanner; 25 | 26 | /** 27 | * @author Markus on 07.02.2016. 28 | */ 29 | public class RollbackVersionAction extends AbstractAction { 30 | 31 | private static final Logger logger = LogManager.getLogger(RollbackVersionAction.class); 32 | private final JTable table; 33 | private WSEditor editorAccess; 34 | 35 | public RollbackVersionAction(String name, JTable table) { 36 | super(name); 37 | this.table = table; 38 | } 39 | 40 | @Override 41 | public void actionPerformed(ActionEvent e) { 42 | URL url = obtainURL(); 43 | 44 | if (table.getSelectedRows()[0] == (table.getModel().getRowCount() - 1)) { 45 | // Reset to last saved revision? Use undo instead! 46 | } else { 47 | editorAccess = PluginWorkspaceProvider.getPluginWorkspace(). 48 | getCurrentEditorAccess(PluginWorkspace.MAIN_EDITING_AREA); 49 | if (editorAccess.isModified()) { 50 | editorAccess.save(); 51 | } 52 | 53 | String newDocumentString = getOldRevisionString(url); 54 | if (newDocumentString != null) { 55 | replaceDocument(newDocumentString); 56 | } 57 | } 58 | } 59 | 60 | private URL obtainURL() { 61 | return ((VersionHistoryTableModel) table.getModel()).getURL(table.getSelectedRows()[0]); 62 | } 63 | 64 | private String getOldRevisionString(URL url) { 65 | String oldDocumentString = null; 66 | try (Connection connection = BaseXConnectionWrapper.getConnection()) { 67 | InputStream oldRevisionStream = new ByteArrayInputStream(connection.get(BaseXSource.DATABASE, 68 | CustomProtocolURLUtils.pathFromURL(url), false)); 69 | oldDocumentString = new Scanner(oldRevisionStream, "UTF-8").useDelimiter("\\A").next(); 70 | } catch (IOException ex) { 71 | logger.error("Couldn't access old file revision during Reset To"); 72 | } 73 | return oldDocumentString; 74 | } 75 | 76 | private void replaceDocument(final String newDoc) { 77 | if (SwingUtilities.isEventDispatchThread()) { 78 | replaceWholeDocument(newDoc); 79 | } else { 80 | try { 81 | SwingUtilities.invokeAndWait(() -> replaceWholeDocument(newDoc)); 82 | } catch (InvocationTargetException | InterruptedException ite) { 83 | logger.error(ite); 84 | } 85 | } 86 | } 87 | 88 | private void replaceWholeDocument(String newDoc) { 89 | Document doc = WorkspaceUtils.getDocumentFromEditor(editorAccess); 90 | try { 91 | doc.remove(0, doc.getLength()); 92 | } catch (BadLocationException el) { 93 | logger.error(el); 94 | } 95 | try { 96 | doc.insertString(0, newDoc, null); 97 | } catch (BadLocationException el) { 98 | logger.error(el); 99 | } 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/actions/SaveFileToArgonAction.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.actions; 2 | 3 | import de.axxepta.oxygen.api.BaseXSource; 4 | import de.axxepta.oxygen.customprotocol.ArgonChooserDialog; 5 | import de.axxepta.oxygen.customprotocol.CustomProtocolURLUtils; 6 | import de.axxepta.oxygen.utils.ConnectionWrapper; 7 | import de.axxepta.oxygen.utils.Lang; 8 | import de.axxepta.oxygen.utils.WorkspaceUtils; 9 | import ro.sync.exml.workspace.api.PluginWorkspace; 10 | import ro.sync.exml.workspace.api.PluginWorkspaceProvider; 11 | import ro.sync.exml.workspace.api.editor.WSEditor; 12 | 13 | import javax.swing.*; 14 | import java.awt.*; 15 | import java.awt.event.ActionEvent; 16 | import java.io.IOException; 17 | import java.net.URL; 18 | 19 | /** 20 | * Store the current editor's content to BaseX. The URL can be chosen from a dialog. If no encoding can be obtained from 21 | * the editor content, the default UTF-8 will be used. 22 | */ 23 | public class SaveFileToArgonAction extends AbstractAction { 24 | 25 | private static final PluginWorkspace workspace = PluginWorkspaceProvider.getPluginWorkspace(); 26 | 27 | public SaveFileToArgonAction(String name, Icon icon) { 28 | super(name, icon); 29 | } 30 | 31 | @Override 32 | public void actionPerformed(ActionEvent e) { 33 | ArgonChooserDialog urlChooser = new ArgonChooserDialog((Frame) workspace.getParentFrame(), 34 | Lang.get(Lang.Keys.dlg_saveas), ArgonChooserDialog.Type.SAVE); 35 | URL[] url = urlChooser.selectURLs(); 36 | 37 | WSEditor editorAccess = workspace.getCurrentEditorAccess(PluginWorkspace.MAIN_EDITING_AREA); 38 | 39 | if (url != null) { 40 | BaseXSource source = CustomProtocolURLUtils.sourceFromURL(url[0]); 41 | String path = CustomProtocolURLUtils.pathFromURL(url[0]); 42 | if (WorkspaceUtils.newResourceOrOverwrite(source, path)) { 43 | if (!ConnectionWrapper.isLocked(source, path)) { 44 | try { 45 | WorkspaceUtils.setCursor(WorkspaceUtils.WAIT_CURSOR); 46 | ConnectionWrapper.lock(source, path); 47 | WorkspaceUtils.saveEditorToBaseXURL(editorAccess, url[0]); 48 | editorAccess.close(false); 49 | workspace.open(url[0]); 50 | WorkspaceUtils.setCursor(WorkspaceUtils.DEFAULT_CURSOR); 51 | } catch (IOException ioe) { 52 | WorkspaceUtils.setCursor(WorkspaceUtils.DEFAULT_CURSOR); 53 | workspace.showErrorMessage(Lang.get(Lang.Keys.warn_resource) + " " + url[0].toString() 54 | + " " + Lang.get(Lang.Keys.warn_storing) + ": " + ioe.getMessage()); 55 | } 56 | } else { 57 | workspace.showInformationMessage(Lang.get(Lang.Keys.warn_resource) + " " + url[0].toString() + 58 | " " + Lang.get(Lang.Keys.warn_locked)); 59 | } 60 | } 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/ArgonConst.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | /** 4 | * @author Markus on 25.09.2016. 5 | */ 6 | public class ArgonConst { 7 | 8 | // PROTOCOL NAMES 9 | public static final String ARGON = "argon"; 10 | public static final String ARGON_XQ = "argonquery"; 11 | public static final String ARGON_REPO = "argonrepo"; 12 | 13 | // DATABASE NAMES 14 | public static final String ARGON_DB = "~argon"; 15 | 16 | public static final String BACKUP_DB_BASE = "~history_"; 17 | 18 | public static final String BACKUP_RESTXQ_BASE = "~history_~restxq/"; 19 | public static final String BACKUP_REPO_BASE = "~history_~repo/"; 20 | 21 | public static final String META_DB_BASE = "~meta_"; 22 | public static final String META_RESTXQ_BASE = "~meta_~restxq/"; 23 | public static final String META_REPO_BASE = "~meta_~repo/"; 24 | 25 | public static final String DATE_FORMAT = "yyyy-MM-dd_HH-mm"; 26 | 27 | // RESOURCE NAMES 28 | public static final String META_TEMPLATE = "MetaTemplate.xml"; 29 | public static final String LOCK_FILE = "~usermanagement"; 30 | public static final String EMPTY_FILE = ".empty.xml"; 31 | 32 | public static final String BXERR_PERMISSION = "BASX0001"; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/ArgonEntity.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | import java.util.Locale; 4 | 5 | /** 6 | * @author Markus on 27.07.2016. 7 | */ 8 | public enum ArgonEntity { 9 | 10 | FILE, 11 | DIR, 12 | DB, 13 | DB_BASE, 14 | REPO, 15 | // XQ, 16 | ROOT; 17 | 18 | public static ArgonEntity get(final String string) { 19 | return ArgonEntity.valueOf(string.toUpperCase(Locale.ENGLISH)); 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return name().toLowerCase(Locale.ENGLISH); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/ArgonWordConnection.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | import org.basex.util.Token; 4 | 5 | import java.io.IOException; 6 | import java.util.ArrayList; 7 | 8 | /** 9 | * @author Markus on 27.04.2016. 10 | */ 11 | public interface ArgonWordConnection { 12 | 13 | /** 14 | * Returns recursively all resources of the given path. 15 | * 16 | * @param path path 17 | * @return entries 18 | * @throws IOException I/O exception 19 | */ 20 | BaseXResource[] list(final String path) throws IOException; 21 | 22 | /** 23 | * Creates a new database. 24 | * 25 | * @param database new database name 26 | * @param chop chop option as string 27 | * @param ftindex ftindex option as string 28 | * @throws IOException I/O exception 29 | */ 30 | void create(final String database, final String chop, final String ftindex) throws IOException; 31 | 32 | /** 33 | * Returns a resource in its binary representation. 34 | * Texts are encoded as UTF-8 and can be converted via {@link Token#string(byte[])}. 35 | * 36 | * @param path path 37 | * @return entry 38 | * @throws IOException I/O exception 39 | */ 40 | byte[] get(final String path) throws IOException; 41 | 42 | /** 43 | * Stores a resource. 44 | * Textual resources must be encoded to UTF-8 via {@link Token#token(String)}. 45 | * 46 | * @param path path 47 | * @param resource resource to be stored 48 | * @param saveOriginalFormat store docx as is or convert to Dita 49 | * @throws IOException I/O exception 50 | */ 51 | void put(final String path, final byte[] resource, final boolean saveOriginalFormat) throws IOException; 52 | 53 | /** 54 | * Deletes a resource. 55 | * 56 | * @param path path 57 | * @throws IOException I/O exception 58 | */ 59 | void delete(final String path) throws IOException; 60 | 61 | /** 62 | * Renames a resource. 63 | * 64 | * @param path path 65 | * @param newPath new path 66 | * @throws IOException I/O exception 67 | */ 68 | void rename(final String path, final String newPath) throws IOException; 69 | 70 | /** 71 | * Searches for resources containing a filter string in it's name. 72 | * 73 | * @param path path 74 | * @param filter search filter 75 | * @return resources 76 | * @throws IOException I/O exception 77 | */ 78 | ArrayList search(final String path, final String filter) throws IOException; 79 | 80 | /** 81 | * Locks a resource. 82 | * 83 | * @param source data source 84 | * @param path path 85 | * @throws IOException I/O exception 86 | */ 87 | void lock(final BaseXSource source, final String path) throws IOException; 88 | 89 | /** 90 | * Unlocks a resource. 91 | * 92 | * @param path path 93 | * @throws IOException I/O exception 94 | */ 95 | void unlock(final String path) throws IOException; 96 | 97 | /** 98 | * Checks if the specified resource is locked for asking user. 99 | * 100 | * @param path path 101 | * @return result of check 102 | * @throws IOException I/O exception 103 | */ 104 | boolean locked(final String path) throws IOException; 105 | 106 | /** 107 | * Checks if the specified resource has no locking information at all 108 | * 109 | * @param path path 110 | * @return result of check 111 | * @throws IOException I/O exception 112 | */ 113 | boolean noLockSet(final String path) throws IOException; 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/BaseXConnectionWrapper.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | import de.axxepta.oxygen.core.ClassFactory; 4 | import de.axxepta.oxygen.utils.ConnectionWrapper; 5 | import de.axxepta.oxygen.workspace.ArgonOptionPage; 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | 9 | import java.net.MalformedURLException; 10 | import java.net.URISyntaxException; 11 | 12 | import static de.axxepta.oxygen.workspace.ArgonOptionPage.*; 13 | 14 | /** 15 | * Wrapper class for connection with BaseX server, loading authentication data from Options 16 | */ 17 | public class BaseXConnectionWrapper { 18 | 19 | private static final Logger logger = LogManager.getLogger(BaseXConnectionWrapper.class); 20 | static Connection connection; 21 | private static String host = null; 22 | 23 | public static void refreshFromOptions(boolean defaults) { 24 | final String host = ArgonOptionPage.getOption(KEY_BASEX_HOST, defaults); 25 | BaseXConnectionWrapper.host = host; 26 | final String user = ArgonOptionPage.getOption(KEY_BASEX_USERNAME, defaults); 27 | final String pass = ArgonOptionPage.getOption(KEY_BASEX_PASSWORD, defaults); 28 | final int port = Integer.parseInt(ArgonOptionPage.getOption(KEY_BASEX_HTTP_PORT, defaults)); 29 | 30 | logger.info("refreshFromOptions " + host + " " + port + " " + user + " " + pass); 31 | try { 32 | connection = ClassFactory.getInstance().getRestConnection(host, port, user, pass); 33 | } catch (URISyntaxException er) { 34 | connection = null; 35 | } 36 | 37 | ConnectionWrapper.init(); 38 | 39 | } 40 | 41 | public static void refreshDefaults() { 42 | try { 43 | connection = ClassFactory.getInstance().getRestConnection("localhost:8984/rest", 8984, "admin", "admin"); 44 | } catch (URISyntaxException er) { 45 | connection = null; 46 | } 47 | } 48 | 49 | public static void refreshDefaults(String host, int port, String user, String password) { 50 | try { 51 | connection = ClassFactory.getInstance().getRestConnection(host, port, user, password); 52 | } catch (URISyntaxException er) { 53 | connection = null; 54 | } 55 | } 56 | 57 | public static Connection getConnection() { 58 | if (host == null) { 59 | refreshFromOptions(false); 60 | } 61 | return connection; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/BaseXQueryException.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | import java.io.IOException; 4 | import java.util.regex.Matcher; 5 | import java.util.regex.Pattern; 6 | 7 | /** 8 | * BaseX resource. 9 | * 10 | * @author Christian Gruen, BaseX GmbH 2015, BSD License 11 | */ 12 | public final class BaseXQueryException extends IOException { 13 | /** 14 | * Error message pattern. 15 | */ 16 | private static final Pattern MESSAGE = Pattern.compile( 17 | "^.* (.*), (\\d+)/(\\d+):\r?\n\\[(.*?)] (.*)$", Pattern.DOTALL); 18 | 19 | /** 20 | * File. 21 | */ 22 | private final String file; 23 | /** 24 | * Line. 25 | */ 26 | private final int line; 27 | /** 28 | * Column. 29 | */ 30 | private final int column; 31 | /** 32 | * Error code. 33 | */ 34 | private final String code; 35 | /** 36 | * Info string. 37 | */ 38 | private final String info; 39 | 40 | /** 41 | * Returns an exception. Tries to convert the given exception to a query exception, 42 | * or returns the original exception. 43 | * 44 | * @param ex exception 45 | * @return new exception 46 | */ 47 | public static IOException get(final IOException ex) { 48 | final String message = ex.getMessage(); 49 | final Matcher matcher = MESSAGE.matcher(message); 50 | return matcher.find() ? new BaseXQueryException(message, matcher) : ex; 51 | } 52 | 53 | /** 54 | * Returns an exception. Tries to convert the given exception to a query exception, 55 | * or returns an I/O exception. 56 | * 57 | * @param message message 58 | * @return new exception 59 | */ 60 | public static IOException get(final String message) { 61 | final Matcher matcher = MESSAGE.matcher(message); 62 | return matcher.find() ? new BaseXQueryException(message, matcher) : new IOException(message); 63 | } 64 | 65 | /** 66 | * Constructor. 67 | * 68 | * @param message message 69 | * @param matcher regular expression matcher 70 | */ 71 | private BaseXQueryException(final String message, final Matcher matcher) { 72 | super(message); 73 | file = matcher.group(1); 74 | line = Integer.parseInt(matcher.group(2)); 75 | column = Integer.parseInt(matcher.group(3)); 76 | code = matcher.group(4); 77 | info = matcher.group(5); 78 | } 79 | 80 | /** 81 | * Returns the line. 82 | * 83 | * @return line 84 | */ 85 | public int getLine() { 86 | return line; 87 | } 88 | 89 | /** 90 | * Returns the column. 91 | * 92 | * @return column 93 | */ 94 | public int getColumn() { 95 | return column; 96 | } 97 | 98 | /** 99 | * Returns the file. 100 | * 101 | * @return file 102 | */ 103 | public String getFile() { 104 | return file; 105 | } 106 | 107 | /** 108 | * Returns the error code. 109 | * 110 | * @return error code 111 | */ 112 | public String getCode() { 113 | return code; 114 | } 115 | 116 | /** 117 | * Return error info. 118 | * 119 | * @return the error info 120 | */ 121 | public String getInfo() { 122 | return info; 123 | } 124 | } -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/BaseXResource.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | /** 4 | * BaseX resource. 5 | * 6 | * @author Christian Gruen, BaseX GmbH 2015, BSD License 7 | */ 8 | 9 | public final class BaseXResource { 10 | /** 11 | * Entry name. 12 | */ 13 | public final String name; 14 | /** 15 | * Entry type. 16 | */ 17 | public final BaseXType type; 18 | /** 19 | * Source. 20 | */ 21 | public final BaseXSource source; 22 | 23 | /** 24 | * Constructor. 25 | * 26 | * @param name name 27 | * @param type type 28 | * @param source source 29 | */ 30 | public BaseXResource(final String name, final BaseXType type, final BaseXSource source) { 31 | this.name = name; 32 | this.type = type; 33 | this.source = source; 34 | } 35 | 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | public BaseXType getType() { 41 | return type; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return name + " (" + type + ")"; 47 | } 48 | 49 | public String getURLString() { 50 | return source.getProtocol() + ":" + name; 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/BaseXSource.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | import java.util.Locale; 4 | 5 | /** 6 | * Resource types. 7 | * 8 | * @author Christian Gruen, BaseX GmbH 2015, BSD License 9 | */ 10 | public enum BaseXSource { 11 | 12 | /** 13 | * Database. 14 | */ 15 | DATABASE("argon"), 16 | // /** 17 | // * RESTXQ. 18 | // */ 19 | // RESTXQ("argonquery"), 20 | /** 21 | * Repository. 22 | */ 23 | REPO("argonrepo"); 24 | 25 | private final String protocol; 26 | 27 | BaseXSource(String protocol) { 28 | 29 | this.protocol = protocol; 30 | } 31 | 32 | public String getProtocol() { 33 | return protocol; 34 | } 35 | 36 | /** 37 | * Returns a source. 38 | * 39 | * @param string string representation 40 | * @return enumeration 41 | */ 42 | public static BaseXSource get(final String string) { 43 | return BaseXSource.valueOf(string.toUpperCase(Locale.ENGLISH)); 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return name().toLowerCase(Locale.ENGLISH); 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/BaseXType.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonValue; 5 | 6 | /** 7 | * Resource types. 8 | * 9 | * @author Christian Gruen, BaseX GmbH 2015, BSD License 10 | */ 11 | public enum BaseXType { 12 | /** 13 | * Directory. 14 | */ 15 | DIRECTORY, 16 | /** 17 | * Resource. 18 | */ 19 | RESOURCE; 20 | 21 | @JsonCreator 22 | public static BaseXType deserialize(String name) { 23 | return BaseXType.valueOf(name); 24 | } 25 | 26 | @JsonValue 27 | @Override 28 | public String toString() { 29 | return this.name(); 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/MetaInfoDefinition.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | /** 4 | * @author Markus on 25.08.2016. 5 | */ 6 | public final class MetaInfoDefinition { 7 | 8 | public static final String HISTORY_FILE_TAG = "historyfile"; 9 | public static final String CREATION_DATE_TAG = "creationdate"; 10 | public static final String LAST_CHANGE_TAG = "lastchange"; 11 | public static final String OWNER_TAG = "owner"; 12 | public static final String GROUP_TAG = "ownergroup"; 13 | public static final String RIGHTS_TAG = "rights"; 14 | public static final String RIGHTS_GROUP_TAG = "group"; 15 | public static final String RIGHTS_OTHERS_TAG = "others"; 16 | 17 | private MetaInfoDefinition() { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/MsgTopic.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | /** 4 | * @author Max on 01.09.2015. 5 | */ 6 | 7 | import de.axxepta.oxygen.core.ObserverInterface; 8 | import de.axxepta.oxygen.core.SubjectInterface; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class MsgTopic implements SubjectInterface { 14 | 15 | private final List observers; 16 | private Object[] message; 17 | private final String type; 18 | private boolean changed; 19 | private final Object MUTEX = new Object(); 20 | 21 | public MsgTopic(String msgType) { 22 | this.observers = new ArrayList<>(); 23 | this.type = msgType; 24 | } 25 | 26 | @Override 27 | public void register(ObserverInterface obj) { 28 | if (obj == null) throw new NullPointerException("Null Observer"); 29 | synchronized (MUTEX) { 30 | if (!observers.contains(obj)) observers.add(obj); 31 | } 32 | } 33 | 34 | /* @Override 35 | public void unregister(ObserverInterface obj) { 36 | synchronized (MUTEX) { 37 | observers.remove(obj); 38 | } 39 | }*/ 40 | 41 | @Override 42 | public void notifyObservers() { 43 | List observersLocal; 44 | //synchronization is used to make sure any observer registered after message is received is not notified 45 | synchronized (MUTEX) { 46 | if (!changed) { 47 | return; 48 | } 49 | observersLocal = new ArrayList<>(this.observers); 50 | this.changed = false; 51 | } 52 | for (ObserverInterface obj : observersLocal) { 53 | obj.update(this, this.message); 54 | } 55 | 56 | } 57 | 58 | /*@Override 59 | public Object getUpdate(ObserverInterface obj) { 60 | return this.message; 61 | }*/ 62 | 63 | //method to post message to the topic 64 | public void postMessage(Object... msg) { 65 | System.out.println("Message Posted to Topic: " + msg[0].toString()); 66 | this.message = msg; 67 | this.changed = true; 68 | notifyObservers(); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/Resource.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | public class Resource { 9 | 10 | public final String name; 11 | public final BaseXType type; 12 | public final boolean locked; 13 | public final List children; 14 | 15 | public Resource(@JsonProperty("name") String name, 16 | @JsonProperty("type") BaseXType type, 17 | @JsonProperty("locked") boolean locked, 18 | @JsonProperty("children") List children) { 19 | this.name = name; 20 | this.type = type; 21 | if (type == BaseXType.DIRECTORY) { 22 | this.locked = false; 23 | this.children = children; 24 | } else { 25 | this.locked = locked; 26 | this.children = Collections.emptyList(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/TopicHolder.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | import de.axxepta.oxygen.api.event.*; 4 | 5 | /** 6 | * @author Max on 01.09.2015. 7 | */ 8 | public class TopicHolder { 9 | 10 | // public static MsgTopic openFile = new openFileEvent(); 11 | // public static MsgTopic changeFile = new changeFileEvent(); 12 | public static final SaveFileEvent saveFile = new SaveFileEvent(); 13 | public static final NewDirEvent newDir = new NewDirEvent(); 14 | public static final DeleteFileEvent deleteFile = new DeleteFileEvent(); 15 | public static final ChangedEditorStatusEvent changedEditorStatus = new ChangedEditorStatusEvent(); 16 | public static final TemplateUpdateRequestedEvent templateUpdateRequested = new TemplateUpdateRequestedEvent(); 17 | public static final ChangedServerStatusEvent changedServerStatus = new ChangedServerStatusEvent(); 18 | public static final TreeNodeRequestedEvent treeNodeRequested = new TreeNodeRequestedEvent(); 19 | public static final ConsoleNotifiedEvent consoleNotified = new ConsoleNotifiedEvent(); 20 | public static final ListDirEvent listDir = new ListDirEvent(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/event/ChangedEditorStatusEvent.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api.event; 2 | 3 | import de.axxepta.oxygen.api.MsgTopic; 4 | 5 | public class ChangedEditorStatusEvent extends MsgTopic { 6 | public ChangedEditorStatusEvent() { 7 | super("EDITOR_STATUS_CHANGED"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/event/ChangedServerStatusEvent.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api.event; 2 | 3 | import de.axxepta.oxygen.api.MsgTopic; 4 | 5 | public class ChangedServerStatusEvent extends MsgTopic { 6 | public ChangedServerStatusEvent() { 7 | super("SERVER_STATUS_CHANGED"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/event/ConsoleNotifiedEvent.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api.event; 2 | 3 | import de.axxepta.oxygen.api.MsgTopic; 4 | 5 | public class ConsoleNotifiedEvent extends MsgTopic { 6 | public ConsoleNotifiedEvent() { 7 | super("MESSAGE_TO_CONSOLE"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/event/DeleteFileEvent.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api.event; 2 | 3 | import de.axxepta.oxygen.api.MsgTopic; 4 | 5 | public class DeleteFileEvent extends MsgTopic { 6 | public DeleteFileEvent() { 7 | super("DELETE_FILE"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/event/ListDirEvent.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api.event; 2 | 3 | import de.axxepta.oxygen.api.MsgTopic; 4 | 5 | public class ListDirEvent extends MsgTopic { 6 | public ListDirEvent() { 7 | super("LIST_DIR"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/event/NewDirEvent.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api.event; 2 | 3 | import de.axxepta.oxygen.api.MsgTopic; 4 | 5 | public class NewDirEvent extends MsgTopic { 6 | public NewDirEvent() { 7 | super("NEW_DIR"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/event/SaveFileEvent.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api.event; 2 | 3 | import de.axxepta.oxygen.api.MsgTopic; 4 | 5 | public class SaveFileEvent extends MsgTopic { 6 | public SaveFileEvent() { 7 | super("SAVE_FILE"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/event/TemplateUpdateRequestedEvent.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api.event; 2 | 3 | import de.axxepta.oxygen.api.MsgTopic; 4 | 5 | public class TemplateUpdateRequestedEvent extends MsgTopic { 6 | public TemplateUpdateRequestedEvent() { 7 | super("TEMPLATE_UPDATE_REQUESTED"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/api/event/TreeNodeRequestedEvent.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api.event; 2 | 3 | import de.axxepta.oxygen.api.MsgTopic; 4 | 5 | public class TreeNodeRequestedEvent extends MsgTopic { 6 | public TreeNodeRequestedEvent() { 7 | super("REQUESTED_TREE_NODE"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/core/ClassFactory.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.core; 2 | 3 | import de.axxepta.oxygen.actions.SearchInPathAction; 4 | import de.axxepta.oxygen.api.Connection; 5 | import de.axxepta.oxygen.api.RestConnection; 6 | import de.axxepta.oxygen.customprotocol.ArgonChooserListCellRenderer; 7 | import de.axxepta.oxygen.tree.*; 8 | import org.apache.logging.log4j.LogManager; 9 | import org.apache.logging.log4j.Logger; 10 | import ro.sync.exml.workspace.api.standalone.ui.TreeCellRenderer; 11 | 12 | import javax.swing.*; 13 | import javax.swing.tree.DefaultMutableTreeNode; 14 | import javax.swing.tree.TreeModel; 15 | import java.net.MalformedURLException; 16 | import java.net.URISyntaxException; 17 | 18 | /** 19 | * @author Markus on 02.06.2016. 20 | * The object instances returned by this factory might be exchanged by aspects from extending plugins to exchange/expand 21 | * functionality. All instances of the respected classes that are used in Argon are (supposed to be) created here. 22 | */ 23 | public class ClassFactory { 24 | 25 | private static final Logger logger = LogManager.getLogger(ClassFactory.class); 26 | private static final ClassFactory ourInstance = new ClassFactory(); 27 | 28 | public static ClassFactory getInstance() { 29 | return ourInstance; 30 | } 31 | 32 | private ClassFactory() { 33 | } 34 | 35 | public DefaultMutableTreeNode getTreeNode(String obj) { 36 | return new ArgonTreeNode(obj); 37 | } 38 | 39 | public DefaultMutableTreeNode getTreeNode(String obj, String url) { 40 | return new ArgonTreeNode(obj, url); 41 | } 42 | 43 | public ArgonPopupMenu getTreePopupMenu(ArgonTree tree, TreeModel treeModel) { 44 | return new ArgonPopupMenu(tree, treeModel); 45 | } 46 | 47 | public Connection getRestConnection(String host, int port, String user, String password) throws URISyntaxException { 48 | return new RestConnection(host, port, user, password); 49 | } 50 | 51 | public Action getSearchInPathAction(String name, Icon icon, JTree tree) { 52 | return new SearchInPathAction(name, icon, tree); 53 | } 54 | 55 | public TreeCellRenderer getTreeCellRenderer() { 56 | return new ArgonTreeCellRenderer(); 57 | } 58 | 59 | public ListCellRenderer getChooserListCellRenderer() { 60 | return new ArgonChooserListCellRenderer(); 61 | } 62 | 63 | public ArgonTreeTransferHandler getTransferHandler(ArgonTree tree) { 64 | return new ArgonTreeTransferHandler(tree); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/core/ObserverInterface.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.core; 2 | 3 | /** 4 | * @author Max on 01.09.2015. 5 | */ 6 | public interface ObserverInterface { 7 | 8 | //method to update the observer, used by subject 9 | void update(T type, Object... message); 10 | 11 | //attach with subject to observe 12 | //public void setSubject(SubjectInterface sub); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/core/SubjectInterface.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.core; 2 | 3 | /** 4 | * @author Max on 01.09.2015. 5 | */ 6 | public interface SubjectInterface { 7 | 8 | //methods to register and unregister observers 9 | void register(ObserverInterface obj); 10 | //void unregister(ObserverInterface obj); 11 | 12 | //method to notify observers of change 13 | void notifyObservers(); 14 | 15 | //method to get updates from subject 16 | //public Object getUpdate(ObserverInterface obj); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/customprotocol/ArgonChooserListCellRenderer.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.customprotocol; 2 | 3 | import de.axxepta.oxygen.tree.ArgonTreeCellRenderer; 4 | import de.axxepta.oxygen.utils.ImageUtils; 5 | import org.apache.logging.log4j.LogManager; 6 | import org.apache.logging.log4j.Logger; 7 | 8 | import javax.swing.*; 9 | import java.awt.*; 10 | 11 | /** 12 | * @author Markus on 27.07.2016. 13 | */ 14 | public class ArgonChooserListCellRenderer implements ListCellRenderer { 15 | 16 | private static final Logger logger = LogManager.getLogger(ArgonChooserListCellRenderer.class); 17 | private static final DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer(); 18 | 19 | @Override 20 | public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, 21 | boolean cellHasFocus) { 22 | JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 23 | 24 | ArgonChooserListModel.Element element = (ArgonChooserListModel.Element) value; 25 | 26 | switch (element.getType()) { 27 | case DB_BASE: 28 | renderer.setIcon(ImageUtils.getIcon(ImageUtils.DB_HTTP)); 29 | break; 30 | case DB: 31 | renderer.setIcon(ImageUtils.getIcon(ImageUtils.DB_CATALOG)); 32 | break; 33 | case REPO: 34 | // case XQ: 35 | renderer.setIcon(ImageUtils.getIcon(ImageUtils.DB_FOLDER)); 36 | break; 37 | case DIR: 38 | case ROOT: 39 | renderer.setIcon(ImageUtils.getIcon(ImageUtils.FOLDER)); 40 | break; 41 | default: 42 | final String thisItemType = ArgonTreeCellRenderer.fileType(element.getName()); 43 | renderer.setIcon(ImageUtils.getIcon(thisItemType)); 44 | } 45 | renderer.setText(element.getName()); 46 | 47 | return renderer; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/customprotocol/ArgonChooserListModel.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.customprotocol; 2 | 3 | import de.axxepta.oxygen.api.ArgonEntity; 4 | 5 | import javax.swing.*; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author Markus on 27.07.2016. 11 | */ 12 | public class ArgonChooserListModel extends AbstractListModel { 13 | 14 | 15 | private final List data; 16 | 17 | ArgonChooserListModel(List data) { 18 | this.data = new ArrayList<>(); 19 | if (data != null) 20 | this.data.addAll(data); 21 | } 22 | 23 | @Override 24 | public int getSize() { 25 | return data.size(); 26 | } 27 | 28 | @Override 29 | public Object getElementAt(int index) { 30 | if (index > getSize()) 31 | return null; 32 | else 33 | return data.get(index); 34 | } 35 | 36 | ArgonEntity getTypeAt(int index) { 37 | if (index > getSize()) 38 | return null; 39 | else 40 | return data.get(index).getType(); 41 | } 42 | 43 | String getNameAt(int index) { 44 | if (index > getSize()) 45 | return null; 46 | else 47 | return data.get(index).getName(); 48 | } 49 | 50 | void setData(List newData) { 51 | int oldSize = getSize(); 52 | data.clear(); 53 | fireIntervalRemoved(this, 0, oldSize - 1); 54 | data.addAll(newData); 55 | fireIntervalAdded(this, 0, getSize() - 1); 56 | } 57 | 58 | void insertElement(Element newElement) { 59 | int oldSize = getSize(); 60 | boolean inserted = false; 61 | for (int index = 1; index < oldSize; index++) { 62 | if ((newElement.getName().compareTo(data.get(index).getName()) < 0) || 63 | data.get(index).getType().equals(ArgonEntity.FILE)) { 64 | data.add(index, newElement); 65 | fireIntervalAdded(this, index, index); 66 | inserted = true; 67 | break; 68 | } 69 | } 70 | if (!inserted) { 71 | data.add(newElement); 72 | fireIntervalAdded(this, oldSize, oldSize); 73 | } 74 | } 75 | 76 | 77 | public static class Element { 78 | 79 | private final ArgonEntity type; 80 | private final String name; 81 | 82 | Element(ArgonEntity type, String name) { 83 | this.type = type; 84 | this.name = name; 85 | } 86 | 87 | public ArgonEntity getType() { 88 | return type; 89 | } 90 | 91 | public String getName() { 92 | return name; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/customprotocol/ArgonEditorsWatchMap.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.customprotocol; 2 | 3 | import de.axxepta.oxygen.api.TopicHolder; 4 | import de.axxepta.oxygen.api.event.ListDirEvent; 5 | import de.axxepta.oxygen.core.ObserverInterface; 6 | 7 | import java.net.URL; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | import static de.axxepta.oxygen.api.TopicHolder.listDir; 12 | 13 | /** 14 | * @author Markus on 28.10.2015. 15 | * The enwraped map contains information about which Argon URLs are opened in editors 16 | */ 17 | public class ArgonEditorsWatchMap implements ObserverInterface { 18 | 19 | private static final ArgonEditorsWatchMap instance = new ArgonEditorsWatchMap(); 20 | 21 | private final Map editorMap = new HashMap<>(); 22 | /** 23 | * contains all Argon resources with locks, locks owned by current user marked with true value 24 | */ 25 | private final Map lockMap = new HashMap<>(); 26 | 27 | 28 | private ArgonEditorsWatchMap() { 29 | } 30 | 31 | public static ArgonEditorsWatchMap getInstance() { 32 | return instance; 33 | } 34 | 35 | public void init() { 36 | TopicHolder.newDir.register(this); 37 | update(listDir, ""); 38 | } 39 | 40 | private boolean isLockInMap(URL url) { 41 | return !(lockMap.get(url) == null); 42 | } 43 | 44 | public boolean hasOwnLock(URL url) { 45 | return isLockInMap(url) && lockMap.get(url); 46 | } 47 | 48 | public boolean hasOtherLock(URL url) { 49 | return isLockInMap(url) && !lockMap.get(url); 50 | } 51 | 52 | public void addURL(URL url) { 53 | if (!isURLInMap(url)) { 54 | editorMap.put(url, new EditorInfo(false)); 55 | } 56 | } 57 | 58 | public void addURL(URL url, boolean checkedOut) { 59 | if (isURLInMap(url)) { 60 | editorMap.get(url).setCheckedOut(checkedOut); 61 | } else { 62 | editorMap.put(url, new EditorInfo(checkedOut)); 63 | } 64 | if (checkedOut) { 65 | lockMap.put(url, true); 66 | } 67 | } 68 | 69 | public void removeURL(URL url) { 70 | editorMap.remove(url); 71 | if (isLockInMap(url) && lockMap.get(url)) { 72 | lockMap.remove(url); 73 | } 74 | } 75 | 76 | private boolean isURLInMap(URL url) { 77 | return !(editorMap.get(url) == null); 78 | } 79 | 80 | public String getEncoding(URL url) { 81 | if (isURLInMap(url)) { 82 | return "UTF-8"; 83 | } else { 84 | return ""; 85 | } 86 | } 87 | 88 | public boolean askedForCheckIn(URL url) { 89 | if (isURLInMap(url)) { 90 | return editorMap.get(url).isAskedForCheckIn(); 91 | } else { 92 | return true; 93 | } 94 | } 95 | 96 | public void setAskedForCheckIn(URL url, boolean asked) { 97 | if (isURLInMap(url)) { 98 | editorMap.get(url).setAskedForCheckIn(asked); 99 | } 100 | } 101 | 102 | @Override 103 | public void update(ListDirEvent type, Object... message) { 104 | // 105 | } 106 | 107 | 108 | private static class EditorInfo { 109 | 110 | boolean checkedOut; 111 | boolean askedForCheckIn = false; 112 | 113 | EditorInfo(boolean checkedOut) { 114 | this.checkedOut = checkedOut; 115 | } 116 | 117 | boolean isAskedForCheckIn() { 118 | return askedForCheckIn; 119 | } 120 | 121 | void setAskedForCheckIn(boolean askedForCheckIn) { 122 | this.askedForCheckIn = askedForCheckIn; 123 | } 124 | 125 | void setCheckedOut(boolean checkedOut) { 126 | this.checkedOut = checkedOut; 127 | } 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/customprotocol/ArgonInputURLChooserCustomizer.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.customprotocol; 2 | 3 | import de.axxepta.oxygen.utils.ImageUtils; 4 | import de.axxepta.oxygen.utils.Lang; 5 | import org.apache.log4j.LogManager; 6 | import org.apache.log4j.Logger; 7 | import ro.sync.exml.workspace.api.PluginWorkspaceProvider; 8 | import ro.sync.exml.workspace.api.standalone.InputURLChooser; 9 | import ro.sync.exml.workspace.api.standalone.InputURLChooserCustomizer; 10 | 11 | import javax.swing.*; 12 | import java.awt.*; 13 | import java.awt.event.ActionEvent; 14 | import java.net.URL; 15 | import java.util.List; 16 | 17 | /** 18 | * @author Markus on 29.10.2016. 19 | */ 20 | public class ArgonInputURLChooserCustomizer implements InputURLChooserCustomizer { 21 | 22 | private static final Logger logger = LogManager.getLogger(ArgonInputURLChooserCustomizer.class); 23 | 24 | @Override 25 | public void customizeBrowseActions(List list, InputURLChooser inputURLChooser) { 26 | final Action browseCMS = new AbstractAction("Argon BaseX", ImageUtils.getIcon(ImageUtils.BASEX)) { 27 | public void actionPerformed(ActionEvent e) { 28 | ArgonChooserDialog urlChooser = new ArgonChooserDialog( 29 | (Frame) PluginWorkspaceProvider.getPluginWorkspace().getParentFrame(), 30 | Lang.get(Lang.Keys.dlg_open), ArgonChooserDialog.Type.OPEN); 31 | URL chosenResource = urlChooser.selectURLs()[0]; 32 | if (chosenResource != null) { 33 | inputURLChooser.urlChosen(chosenResource); 34 | } 35 | } 36 | }; 37 | list.add(browseCMS); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/customprotocol/ArgonProcessor.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.customprotocol; 2 | 3 | import ro.sync.net.protocol.convert.ConversionProvider; 4 | 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.OutputStream; 8 | import java.util.LinkedHashMap; 9 | 10 | /** 11 | * @author Markus on 21.10.2016. 12 | */ 13 | public class ArgonProcessor implements ConversionProvider { 14 | 15 | public void convert(String systemID, String originalSourceSystemID, InputStream is, OutputStream os, 16 | LinkedHashMap properties) throws IOException { 17 | byte[] buffer = new byte[1024]; 18 | int len; 19 | while ((len = is.read(buffer)) != -1) { 20 | os.write(buffer, 0, len); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/customprotocol/ArgonProtocolHandler.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.customprotocol; 2 | 3 | import de.axxepta.oxygen.api.BaseXConnectionWrapper; 4 | import de.axxepta.oxygen.api.BaseXSource; 5 | import de.axxepta.oxygen.api.Connection; 6 | import org.apache.logging.log4j.LogManager; 7 | import org.apache.logging.log4j.Logger; 8 | 9 | import java.io.ByteArrayInputStream; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.io.OutputStream; 13 | import java.net.URL; 14 | import java.net.URLConnection; 15 | import java.net.URLStreamHandler; 16 | 17 | /** 18 | * @author Markus on 12.10.2015. 19 | */ 20 | public class ArgonProtocolHandler extends URLStreamHandler { 21 | 22 | private final BaseXSource source; 23 | private static final Logger logger = LogManager.getLogger(ArgonProtocolHandler.class); 24 | 25 | public ArgonProtocolHandler(BaseXSource source) { 26 | this.source = source; 27 | } 28 | 29 | private static class ArgonConnection extends URLConnection { 30 | 31 | final BaseXSource source; 32 | 33 | ArgonConnection(URL url, BaseXSource source) { 34 | super(url); 35 | this.source = source; 36 | // Allow output 37 | setDoOutput(true); 38 | } 39 | 40 | @Override 41 | public InputStream getInputStream() throws IOException { 42 | ByteArrayInputStream inputStream; 43 | try (Connection connection = BaseXConnectionWrapper.getConnection()) { 44 | logger.info("Requested new InputStream: " + this.url.toString()); 45 | inputStream = new ByteArrayInputStream(connection.get(source, 46 | CustomProtocolURLUtils.pathFromURL(this.url), false)); 47 | // ToDo: try to call OptionPage -> if not accessible, not in editor context (e.g., publishing process), don't add URL to watch map 48 | ArgonEditorsWatchMap.getInstance().addURL(url); 49 | } catch (IOException io) { 50 | logger.debug("Failed to obtain InputStream: ", io.getMessage()); 51 | throw new IOException(io); 52 | } 53 | return inputStream; 54 | } 55 | 56 | @Override 57 | public OutputStream getOutputStream() throws IOException { 58 | return new BaseXByteArrayOutputStream(url); 59 | } 60 | 61 | @Override 62 | public void connect() throws IOException { 63 | this.connected = true; 64 | } 65 | } 66 | 67 | @Override 68 | protected URLConnection openConnection(URL url) throws IOException { 69 | return new ArgonConnection(url, this.source); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/customprotocol/CustomProtocolChooserExtension.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.customprotocol; 2 | 3 | import de.axxepta.oxygen.utils.ImageUtils; 4 | import de.axxepta.oxygen.utils.Lang; 5 | import ro.sync.exml.plugin.urlstreamhandler.URLChooserPluginExtension2; 6 | import ro.sync.exml.plugin.urlstreamhandler.URLChooserToolbarExtension; 7 | import ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace; 8 | 9 | import javax.swing.*; 10 | import java.awt.*; 11 | import java.net.URL; 12 | 13 | /** 14 | * Plugin extension - custom protocol chooser extension 15 | */ 16 | public class CustomProtocolChooserExtension implements URLChooserPluginExtension2, URLChooserToolbarExtension { 17 | 18 | @Override 19 | public URL[] chooseURLs(StandalonePluginWorkspace workspaceAccess) { 20 | ArgonChooserDialog urlChooser = new ArgonChooserDialog((Frame) workspaceAccess.getParentFrame(), 21 | Lang.get(Lang.Keys.dlg_open), ArgonChooserDialog.Type.OPEN); 22 | return urlChooser.selectURLs(); 23 | } 24 | 25 | @Override 26 | public String getMenuName() { 27 | return Lang.get(Lang.Keys.dlg_open); 28 | } 29 | 30 | @Override 31 | public Icon getToolbarIcon() { 32 | return ImageUtils.getIcon(ImageUtils.BASEX24); 33 | } 34 | 35 | @Override 36 | public String getToolbarTooltip() { 37 | return Lang.get(Lang.Keys.dlg_open); 38 | } 39 | } -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/customprotocol/CustomProtocolURLHandlerExtension.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.customprotocol; 2 | 3 | import com.google.common.cache.Cache; 4 | import com.google.common.cache.CacheBuilder; 5 | import de.axxepta.oxygen.api.ArgonConst; 6 | import de.axxepta.oxygen.api.BaseXSource; 7 | import de.axxepta.oxygen.utils.ConnectionWrapper; 8 | import org.apache.logging.log4j.LogManager; 9 | import org.apache.logging.log4j.Logger; 10 | import ro.sync.exml.plugin.lock.LockException; 11 | import ro.sync.exml.plugin.lock.LockHandler; 12 | import ro.sync.exml.plugin.urlstreamhandler.URLHandlerReadOnlyCheckerExtension; 13 | import ro.sync.exml.plugin.urlstreamhandler.URLStreamHandlerWithLockPluginExtension; 14 | 15 | import java.net.URL; 16 | import java.net.URLStreamHandler; 17 | import java.util.concurrent.ExecutionException; 18 | import java.util.concurrent.TimeUnit; 19 | 20 | 21 | /** 22 | * Plugin extension - custom protocol URL handler extension 23 | */ 24 | public class CustomProtocolURLHandlerExtension implements URLStreamHandlerWithLockPluginExtension, URLHandlerReadOnlyCheckerExtension { 25 | 26 | private static final Logger logger = LogManager.getLogger(CustomProtocolURLHandlerExtension.class); 27 | public static final Cache readOnlyCache = CacheBuilder.newBuilder() 28 | .maximumSize(1000) 29 | .expireAfterWrite(10, TimeUnit.SECONDS) 30 | .build(); 31 | 32 | private final LockHandler lockHandler = new LockHandler() { 33 | @Override 34 | public void unlock(URL url) throws LockException { 35 | } 36 | 37 | @Override 38 | public void updateLock(URL url, int i) throws LockException { 39 | } 40 | }; 41 | 42 | /** 43 | * Gets the handler for the custom protocol 44 | */ 45 | @Override 46 | public URLStreamHandler getURLStreamHandler(String protocol) { 47 | //BaseXConnectionWrapper.refreshDefaults(); 48 | URLStreamHandler handler; 49 | switch (protocol.toLowerCase()) { 50 | case ArgonConst.ARGON: 51 | handler = new ArgonProtocolHandler(BaseXSource.DATABASE); 52 | return handler; 53 | // case ArgonConst.ARGON_XQ: 54 | // handler = new ArgonProtocolHandler(BaseXSource.RESTXQ); 55 | // return handler; 56 | case ArgonConst.ARGON_REPO: 57 | handler = new ArgonProtocolHandler(BaseXSource.REPO); 58 | return handler; 59 | default: 60 | return null; 61 | } 62 | } 63 | 64 | @Override 65 | public LockHandler getLockHandler() { 66 | return lockHandler; 67 | } 68 | 69 | @Override 70 | public boolean isLockingSupported(String protocol) { 71 | return protocol.toLowerCase().equals(ArgonConst.ARGON); 72 | } 73 | 74 | @Override 75 | public boolean canCheckReadOnly(String protocol) { 76 | return protocol.toLowerCase().equals(ArgonConst.ARGON); 77 | } 78 | 79 | @Override 80 | public boolean isReadOnly(URL url) { 81 | // FIXME there should be a way to put/remove from cache on checkout/checkin operations 82 | try { 83 | return readOnlyCache.get(url, () -> !ConnectionWrapper.isLockedByUser(CustomProtocolURLUtils.sourceFromURL(url), CustomProtocolURLUtils.pathFromURL(url))); 84 | } catch (ExecutionException e) { 85 | logger.error("Failed to get read-only status from cache: " + e.getMessage(), e); 86 | return true; 87 | } 88 | } 89 | 90 | public void lock(URL url) { 91 | readOnlyCache.put(url, Boolean.FALSE); 92 | } 93 | 94 | public void unlock(URL url) { 95 | readOnlyCache.put(url, Boolean.TRUE); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/customprotocol/CustomProtocolURLUtils.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.customprotocol; 2 | 3 | import de.axxepta.oxygen.api.ArgonConst; 4 | import de.axxepta.oxygen.api.BaseXSource; 5 | import org.apache.logging.log4j.LogManager; 6 | import org.apache.logging.log4j.Logger; 7 | 8 | import java.io.UnsupportedEncodingException; 9 | import java.net.URI; 10 | import java.net.URL; 11 | 12 | public class CustomProtocolURLUtils { 13 | 14 | private static final Logger logger = LogManager.getLogger(CustomProtocolURLUtils.class); 15 | 16 | public static String pathFromURL(URL url) { 17 | String urlString = ""; 18 | try { 19 | urlString = java.net.URLDecoder.decode(url.toString(), "UTF-8"); 20 | } catch (UnsupportedEncodingException | IllegalArgumentException ex) { 21 | logger.error("URLDecoder error decoding " + url.toString(), ex.getMessage()); 22 | } 23 | return pathFromURLString(urlString); 24 | } 25 | 26 | public static String pathFromURLString(String urlString) { 27 | String[] urlComponents = urlString.split(":/*"); 28 | if (urlComponents.length < 2) { 29 | return ""; 30 | // ToDo: exception handling 31 | } else { 32 | return urlComponents[1]; 33 | } 34 | } 35 | 36 | public static BaseXSource sourceFromURL(URL url) { 37 | return sourceFromURLString(url.toString()); 38 | } 39 | 40 | public static BaseXSource sourceFromURLString(String urlString) { 41 | final URI uri = URI.create(urlString); 42 | if (uri.getScheme() == null) { 43 | return null; 44 | } 45 | switch (uri.getScheme()) { 46 | // case ArgonConst.ARGON_XQ: 47 | // return BaseXSource.RESTXQ; 48 | case ArgonConst.ARGON_REPO: 49 | return BaseXSource.REPO; 50 | case ArgonConst.ARGON: 51 | return BaseXSource.DATABASE; 52 | default: 53 | return null; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/tree/ArgonTree.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.tree; 2 | 3 | import de.axxepta.oxygen.core.ClassFactory; 4 | import ro.sync.exml.workspace.api.standalone.ui.Tree; 5 | 6 | import javax.swing.tree.TreeModel; 7 | 8 | 9 | /** 10 | * Tree using custom TreeCellRenderer 11 | */ 12 | 13 | public class ArgonTree extends Tree { 14 | 15 | private static final long serialVersionUID = 1L; 16 | 17 | public ArgonTree(final TreeModel root) { 18 | super(root); 19 | setCellRenderer(ClassFactory.getInstance().getTreeCellRenderer()); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/tree/ArgonTreeCellRenderer.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.tree; 2 | 3 | import de.axxepta.oxygen.utils.ImageUtils; 4 | import org.apache.logging.log4j.LogManager; 5 | import org.apache.logging.log4j.Logger; 6 | import ro.sync.exml.workspace.api.standalone.ui.TreeCellRenderer; 7 | 8 | import javax.swing.*; 9 | import javax.swing.tree.DefaultMutableTreeNode; 10 | import java.awt.*; 11 | 12 | public class ArgonTreeCellRenderer extends TreeCellRenderer { 13 | 14 | private static final Logger logger = LogManager.getLogger(ArgonTreeCellRenderer.class); 15 | 16 | private static final long serialVersionUID = 1L; 17 | 18 | @Override 19 | public Component getTreeCellRendererComponent(JTree aTree, Object aValue, 20 | boolean aSelected, boolean aExpanded, boolean aLeaf, int aRow, 21 | boolean aHasFocus) { 22 | // if ((aValue != null) && (aValue instanceof DefaultMutableTreeNode)) { 23 | if (aLeaf) { 24 | super.getTreeCellRendererComponent(aTree, aValue, aSelected, aExpanded, true, aRow, aHasFocus); 25 | String thisLeafFileType = fileType(aValue.toString()); 26 | setIcon(ImageUtils.getIcon(thisLeafFileType)); 27 | return this; 28 | } else if (isRoot(aTree, aValue)) { 29 | super.getTreeCellRendererComponent(aTree, aValue, aSelected, aExpanded, true, aRow, aHasFocus); 30 | setIcon(ImageUtils.getIcon(ImageUtils.DB_CONNECTION)); 31 | return this; 32 | } else if (isDatabase(aTree, aValue)) { 33 | super.getTreeCellRendererComponent(aTree, aValue, aSelected, aExpanded, true, aRow, aHasFocus); 34 | setIcon(ImageUtils.getIcon(ImageUtils.DB_CATALOG)); 35 | return this; 36 | } else if (isDBSource(aTree, aValue)) { 37 | super.getTreeCellRendererComponent(aTree, aValue, aSelected, aExpanded, true, aRow, aHasFocus); 38 | setIcon(ImageUtils.getIcon(ImageUtils.DB_HTTP)); 39 | return this; 40 | // } else if (isSourceDir(aTree, aValue)) { 41 | // super.getTreeCellRendererComponent(aTree, aValue, aSelected, aExpanded, true, aRow, aHasFocus); 42 | // setIcon(ImageUtils.getIcon(ImageUtils.DB_FOLDER)); 43 | // return this; 44 | } 45 | // } 46 | // For everything else use default renderer. 47 | return super.getTreeCellRendererComponent(aTree, aValue, aSelected, aExpanded, aLeaf, aRow, aHasFocus); 48 | } 49 | 50 | public static String fileType(String leafStr) { 51 | if (leafStr.contains(".")) { 52 | return leafStr.substring(leafStr.lastIndexOf(".") + 1); 53 | } else { 54 | return ""; 55 | } 56 | } 57 | 58 | private boolean isRoot(JTree tree, Object value) { 59 | final DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; 60 | final DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot(); 61 | return node.equals(root); 62 | } 63 | 64 | private boolean isDatabase(JTree tree, Object value) { 65 | final DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; 66 | final DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot(); 67 | final DefaultMutableTreeNode db = (DefaultMutableTreeNode) tree.getModel().getChild(root, 0); 68 | return node.getParent().equals(db); 69 | } 70 | 71 | private boolean isDBSource(JTree tree, Object value) { 72 | final DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; 73 | final DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot(); 74 | final DefaultMutableTreeNode db = (DefaultMutableTreeNode) tree.getModel().getChild(root, 0); 75 | return node.equals(db); 76 | } 77 | 78 | private boolean isSourceDir(JTree tree, Object value) { 79 | final DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; 80 | final DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot(); 81 | final DefaultMutableTreeNode restxq = (DefaultMutableTreeNode) tree.getModel().getChild(root, 1); 82 | final DefaultMutableTreeNode repo = (DefaultMutableTreeNode) tree.getModel().getChild(root, 2); 83 | return (node.equals(restxq) || node.equals(repo)); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/tree/ArgonTreeNode.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.tree; 2 | 3 | import javax.swing.tree.DefaultMutableTreeNode; 4 | 5 | /** 6 | * @author Markus on 02.07.2016. 7 | */ 8 | public class ArgonTreeNode extends DefaultMutableTreeNode { 9 | 10 | private Object tag; 11 | 12 | public ArgonTreeNode() { 13 | super(); 14 | } 15 | 16 | public ArgonTreeNode(Object name) { 17 | super(name); 18 | } 19 | 20 | public ArgonTreeNode(Object name, Object url) { 21 | super(name); 22 | this.tag = url; 23 | } 24 | 25 | public Object getTag() { 26 | return tag; 27 | } 28 | 29 | public void setTag(Object tag) { 30 | this.tag = tag; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/tree/ArgonTreeTransferable.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.tree; 2 | 3 | import de.axxepta.oxygen.actions.ExportAction; 4 | import de.axxepta.oxygen.api.BaseXResource; 5 | import de.axxepta.oxygen.api.BaseXSource; 6 | import de.axxepta.oxygen.api.BaseXType; 7 | import org.apache.logging.log4j.LogManager; 8 | import org.apache.logging.log4j.Logger; 9 | 10 | import javax.swing.tree.TreePath; 11 | import java.awt.datatransfer.DataFlavor; 12 | import java.awt.datatransfer.Transferable; 13 | import java.awt.datatransfer.UnsupportedFlavorException; 14 | import java.io.IOException; 15 | import java.util.List; 16 | 17 | import static de.axxepta.oxygen.tree.TreeUtils.DEPTH_DB; 18 | 19 | /** 20 | * @author Markus on 27.10.2016. 21 | */ 22 | class ArgonTreeTransferable implements Transferable { 23 | 24 | private static final Logger logger = LogManager.getLogger(ArgonTreeTransferable.class); 25 | private static final DataFlavor treePathFlavor = getTreePathFlavor(); 26 | private static final DataFlavor uriListFlavor = getURIListFlavor(); 27 | private static final DataFlavor[] flavors = initFlavors(); 28 | private final TreePath path; 29 | 30 | ArgonTreeTransferable(TreePath path) { 31 | this.path = path; 32 | } 33 | 34 | @Override 35 | public DataFlavor[] getTransferDataFlavors() { 36 | return flavors; 37 | } 38 | 39 | @Override 40 | public boolean isDataFlavorSupported(DataFlavor flavor) { 41 | return (flavor.equals(treePathFlavor) || flavor.equals(uriListFlavor)); 42 | } 43 | 44 | @Override 45 | public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 46 | if (flavor.equals(treePathFlavor)) { 47 | if ((path.getPathCount() < DEPTH_DB) || TreeUtils.isDB(path)) { 48 | throw new IOException("Drag error: Cannot copy/move databases or root branches."); 49 | } 50 | return path; 51 | } 52 | if (flavor.equals(uriListFlavor)) { 53 | if ((path.getPathCount() < DEPTH_DB) || TreeUtils.isDB(path)) { 54 | throw new IOException("Drag error: Cannot open databases or root branches."); 55 | } 56 | return getURIList(); 57 | } 58 | throw new UnsupportedFlavorException(flavor); 59 | } 60 | 61 | private static DataFlavor[] initFlavors() { 62 | DataFlavor[] flavors = new DataFlavor[2]; 63 | flavors[0] = getTreePathDataFlavor(); 64 | flavors[1] = getURIListFlavor(); 65 | return flavors; 66 | } 67 | 68 | private static DataFlavor getTreePathFlavor() { 69 | String mimeType = DataFlavor.javaJVMLocalObjectMimeType + ";class=\"" + 70 | TreePath.class.getName() + "\""; 71 | try { 72 | return new DataFlavor(mimeType); 73 | } catch (ClassNotFoundException cn) { 74 | logger.debug("Class not found creating DataFlavor"); 75 | return new DataFlavor(); 76 | } 77 | } 78 | 79 | private static DataFlavor getURIListFlavor() { 80 | return new DataFlavor("text/uri-list;class=java.lang.String", null); 81 | } 82 | 83 | static DataFlavor getTreePathDataFlavor() { 84 | return treePathFlavor; 85 | } 86 | 87 | private String getURIList() throws IOException { 88 | BaseXSource source = TreeUtils.sourceFromTreePath(path); 89 | List resourceList = ExportAction.getExportResourceList(source, path, TreeUtils.resourceFromTreePath(path)); 90 | StringBuilder uriListBuilder = new StringBuilder(""); 91 | for (BaseXResource resource : resourceList) { 92 | if (resource.getType().equals(BaseXType.RESOURCE)) { 93 | String fullResourceName = ExportAction.getFullResource(path, source, resource); 94 | String resourceURL = source.getProtocol() + ":" + 95 | fullResourceName; 96 | uriListBuilder.append(resourceURL).append("\n"); 97 | } 98 | } 99 | return uriListBuilder.toString(); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/utils/DialogTools.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.utils; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | 6 | /** 7 | * @author Markus on 01.11.2015. 8 | */ 9 | // keep public for access via AspectJ 10 | public class DialogTools { 11 | 12 | public static void CenterDialogRelativeToParent(Dialog dialog) { 13 | Dimension dialogSize = dialog.getSize(); 14 | Container parent = dialog.getParent(); 15 | Dimension parentSize = parent.getSize(); 16 | 17 | int dx = (parentSize.width - dialogSize.width) / 2; 18 | int dy = (parentSize.height - dialogSize.height) / 2; 19 | 20 | dialog.setLocation(parent.getX() + dx, parent.getY() + dy); 21 | } 22 | 23 | public static void wrapAndShow(JDialog dialog, JPanel content, JFrame parentFrame) { 24 | wrap(dialog, content, parentFrame); 25 | dialog.setVisible(true); 26 | } 27 | 28 | public static void wrapAndShow(JDialog dialog, JPanel content, JFrame parentFrame, int width, int height) { 29 | wrap(dialog, content, parentFrame); 30 | dialog.setSize(width, height); 31 | dialog.setVisible(true); 32 | } 33 | 34 | private static void wrap(JDialog dialog, JPanel content, JFrame parentFrame) { 35 | content.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); 36 | dialog.setContentPane(content); 37 | dialog.pack(); 38 | dialog.setLocationRelativeTo(parentFrame); 39 | dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); 40 | } 41 | 42 | public static JDialog getOxygenDialog(JFrame parentFrame, String title) { 43 | JDialog dialog = new JDialog(parentFrame, title); 44 | dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); 45 | // ToDo: image from map 46 | dialog.setIconImage(ImageUtils.createImage("/images/Oxygen16.png")); 47 | dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 48 | return dialog; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/utils/FileUtils.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.utils; 2 | 3 | import de.axxepta.oxygen.api.BaseXConnectionWrapper; 4 | import de.axxepta.oxygen.api.BaseXSource; 5 | import de.axxepta.oxygen.api.Connection; 6 | import de.axxepta.oxygen.customprotocol.CustomProtocolURLUtils; 7 | import org.apache.logging.log4j.LogManager; 8 | import org.apache.logging.log4j.Logger; 9 | 10 | import java.io.File; 11 | import java.io.FileOutputStream; 12 | import java.io.IOException; 13 | import java.nio.file.Files; 14 | import java.nio.file.Path; 15 | import java.nio.file.Paths; 16 | 17 | /** 18 | * @author Markus on 19.02.2016. 19 | */ 20 | public final class FileUtils { 21 | 22 | private static final Logger logger = LogManager.getLogger(FileUtils.class); 23 | 24 | private FileUtils() { 25 | } 26 | 27 | public static boolean directoryExists(File dir) { 28 | if (dir == null) 29 | return false; 30 | return dir.exists() && dir.isDirectory(); 31 | } 32 | 33 | public static void createDirectory(String name) { 34 | try { 35 | Path newPath = Paths.get(name); 36 | Files.createDirectory(newPath); 37 | } catch (IOException use) { 38 | logger.error("Error parsing path name to URI"); 39 | } 40 | } 41 | 42 | public static void copyFromBaseXToFile(String fileToCopy, String destinationFile) throws IOException { 43 | BaseXSource source = CustomProtocolURLUtils.sourceFromURLString(fileToCopy); 44 | String path = CustomProtocolURLUtils.pathFromURLString(fileToCopy); 45 | 46 | try (Connection connection = BaseXConnectionWrapper.getConnection()) { 47 | byte[] bytesToCopy = connection.get(source, path, true); 48 | try (FileOutputStream fos = new FileOutputStream(destinationFile)) { 49 | fos.write(bytesToCopy); 50 | } catch (IOException ioe) { 51 | throw new IOException("Argon: Copying file to file system failed: " + destinationFile); 52 | } 53 | } catch (IOException ioe) { 54 | throw new IOException("Argon: Getting file to copy from database failed: " + destinationFile); 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/utils/IOUtils.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.utils; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | 6 | import java.io.ByteArrayOutputStream; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.UnsupportedEncodingException; 10 | import java.util.Arrays; 11 | 12 | /** 13 | * @author Markus on 08.09.2016. 14 | */ 15 | public final class IOUtils { 16 | 17 | private static final Logger logger = LogManager.getLogger(IOUtils.class); 18 | 19 | private IOUtils() { 20 | } 21 | 22 | static byte[] getBytesFromInputStream(InputStream stream) throws IOException { 23 | byte[] bytes; 24 | try (ByteArrayOutputStream boStream = new ByteArrayOutputStream()) { 25 | int nRead; 26 | int bufferSize = 1024; 27 | final byte[] readData = new byte[bufferSize]; 28 | while ((nRead = stream.read(readData, 0, bufferSize)) != -1) { 29 | boStream.write(readData, 0, nRead); 30 | } 31 | boStream.flush(); 32 | bytes = boStream.toByteArray(); 33 | } 34 | return bytes; 35 | } 36 | 37 | public static byte[] convertToUTF8(byte[] bytes, String encoding) { 38 | try { 39 | return new String(bytes, encoding).getBytes("UTF-8"); 40 | } catch (UnsupportedEncodingException uee) { 41 | try { 42 | logger.error("Error converting output to UTF-8 : ", uee.getMessage()); 43 | return "Original encoding was not supported.".getBytes("UTF-8"); 44 | } catch (UnsupportedEncodingException uuee) { 45 | logger.error("WHAT THE FUCK?"); 46 | return new byte[0]; 47 | } 48 | } 49 | } 50 | 51 | static byte[] returnUTF8Array(String text) { 52 | try { 53 | return text.getBytes("UTF-8"); 54 | } catch (UnsupportedEncodingException uee) { 55 | logger.error("Error converting output to UTF-8 : ", uee.getMessage()); 56 | return new byte[0]; 57 | } 58 | } 59 | 60 | static String returnUTF8String(byte[] bytes) { 61 | try { 62 | return new String(bytes, "UTF-8"); 63 | } catch (UnsupportedEncodingException uee) { 64 | logger.error("Error converting output to UTF-8 : ", uee.getMessage()); 65 | return ""; 66 | } 67 | } 68 | 69 | public static boolean isXML(byte[] bytes) { 70 | if (bytes.length > 4) { 71 | if ((bytes[0] == (byte) 0xFE) && (bytes[1] == (byte) 0xFF)) { // check for UTF-16BE BOM 72 | return checkXML(Arrays.copyOfRange(bytes, 2, bytes.length - 1), "UTF-16BE"); 73 | } else if ((bytes[0] == (byte) 0xFF) && (bytes[1] == (byte) 0xFE)) { // check for UTF-16LE BOM 74 | return checkXML(Arrays.copyOfRange(bytes, 2, bytes.length - 1), "UTF-16LE"); 75 | } else if ((bytes[0] == (byte) 0xEF) && (bytes[1] == (byte) 0xBB) && (bytes[2] == (byte) 0xBF)) { // check for UTF-8 BOM 76 | return checkXML(Arrays.copyOfRange(bytes, 3, bytes.length - 1), "UTF-8"); 77 | } else if ((bytes[0] == (byte) 0x3c) && (bytes[bytes.length - 1] == (byte) 0x3e)) { // check for UTF-8/ISO 8859-1 code starting with '<', ending with '>' 78 | return true; 79 | } else { 80 | return checkXML(bytes, "UTF-8"); 81 | } 82 | } else { 83 | return false; 84 | } 85 | } 86 | 87 | private static boolean isXML(String wannabe) { 88 | String trimmed = wannabe.trim(); 89 | return (trimmed.startsWith("<") && trimmed.endsWith(">")); 90 | } 91 | 92 | private static boolean checkXML(byte[] bytes, String encoding) { 93 | try { 94 | String wannabe = new String(bytes, encoding); 95 | return isXML(wannabe); 96 | } catch (UnsupportedEncodingException use) { 97 | return false; 98 | } 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/utils/NoDatabaseConnectionException.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.utils; 2 | 3 | import java.io.IOException; 4 | 5 | public class NoDatabaseConnectionException extends IOException { 6 | 7 | public NoDatabaseConnectionException() { 8 | super("No database connection"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.utils; 2 | 3 | /** 4 | * @author Markus on 28.07.2016. 5 | */ 6 | public final class StringUtils { 7 | 8 | public static final String LF = System.getProperty("line.separator"); 9 | 10 | private StringUtils() { 11 | } 12 | 13 | public static boolean isEmpty(String s) { 14 | return (s == null) || (s.equals("")); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/utils/URLUtils.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.utils; 2 | 3 | import de.axxepta.oxygen.api.ArgonConst; 4 | 5 | import java.net.URL; 6 | 7 | /** 8 | * @author Markus on 09.12.2015. 9 | */ 10 | public final class URLUtils { 11 | 12 | private URLUtils() { 13 | } 14 | 15 | public static boolean isXML(String file) { 16 | return (file.toLowerCase().endsWith(".xml") || 17 | file.toLowerCase().endsWith(".svg") || 18 | file.toLowerCase().endsWith(".dita") || 19 | file.toLowerCase().endsWith(".ditaval") || 20 | file.toLowerCase().endsWith(".ditamap")); 21 | } 22 | 23 | public static boolean isXML(URL url) { 24 | return isXML(url.toString()); 25 | } 26 | 27 | public static boolean isQuery(String file) { 28 | return (file.toLowerCase().endsWith(".xq") || 29 | file.toLowerCase().endsWith(".xqm") || 30 | file.toLowerCase().endsWith(".xql") || 31 | file.toLowerCase().endsWith(".xqy") || 32 | file.toLowerCase().endsWith(".xquery")); 33 | } 34 | 35 | /** 36 | * Tests whether the file extension indicates a non-XML file type, cannot exclude false negatives (file might be XML anyway) 37 | * 38 | * @param url URL of file 39 | * @return true if non-xml type for sure 40 | */ 41 | public static boolean isBinary(URL url) { 42 | return isBinary(url.toString()); 43 | } 44 | 45 | /** 46 | * Tests whether the file extension indicates a non-XML file type, cannot exclude false negatives (file might be XML anyway) 47 | * 48 | * @param file name of file 49 | * @return true if non-xml type for sure 50 | */ 51 | public static boolean isBinary(String file) { 52 | return (file.toLowerCase().endsWith(".gif") || 53 | file.toLowerCase().endsWith(".png") || 54 | file.toLowerCase().endsWith(".eps") || 55 | file.toLowerCase().endsWith(".tiff") || 56 | file.toLowerCase().endsWith(".jpg") || 57 | file.toLowerCase().endsWith(".jpeg") || 58 | file.toLowerCase().endsWith(".doc") || 59 | file.toLowerCase().endsWith(".docx") || 60 | file.toLowerCase().endsWith(".ppt") || 61 | file.toLowerCase().endsWith(".xls") || 62 | file.toLowerCase().endsWith(".xlsx") || 63 | file.toLowerCase().endsWith(".pdf") || 64 | file.toLowerCase().endsWith(".dll") || 65 | file.toLowerCase().endsWith(".exe") || 66 | file.toLowerCase().endsWith(".htm") || // store only XML as text 67 | file.toLowerCase().endsWith(".html") || 68 | file.toLowerCase().endsWith(".php") || 69 | file.toLowerCase().endsWith(".css") || 70 | file.toLowerCase().endsWith(".txt") || 71 | isQuery(file)); 72 | } 73 | 74 | public static boolean isQuery(URL url) { 75 | return isQuery(url.toString()); 76 | } 77 | 78 | public static boolean isArgon(URL url) { 79 | return url.toString().toLowerCase().startsWith(ArgonConst.ARGON); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/utils/XMLUtils.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.utils; 2 | 3 | import org.w3c.dom.Document; 4 | import org.xml.sax.SAXException; 5 | 6 | import javax.xml.parsers.DocumentBuilder; 7 | import javax.xml.parsers.DocumentBuilderFactory; 8 | import javax.xml.parsers.ParserConfigurationException; 9 | import javax.xml.xpath.XPath; 10 | import javax.xml.xpath.XPathExpression; 11 | import javax.xml.xpath.XPathExpressionException; 12 | import javax.xml.xpath.XPathFactory; 13 | import java.io.ByteArrayInputStream; 14 | import java.io.IOException; 15 | 16 | /** 17 | * @author Markus on 25.08.2016. 18 | */ 19 | public final class XMLUtils { 20 | 21 | private static final XPathFactory xPathFactory = XPathFactory.newInstance(); 22 | private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 23 | 24 | private XMLUtils() { 25 | } 26 | 27 | public static Document docFromByteArray(byte[] is) throws ParserConfigurationException, IOException, SAXException { 28 | DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder(); 29 | return builder.parse(new ByteArrayInputStream(is)); 30 | } 31 | 32 | public static XPathExpression getXPathExpression(String xPath) throws XPathExpressionException { 33 | XPath xpath = xPathFactory.newXPath(); 34 | return xpath.compile(xPath); 35 | } 36 | 37 | static String encodingFromPrologue(String content) { 38 | String encoding = ""; 39 | if (content.contains(" 4) { 52 | if ((content[0] == (byte) 0xFE) && (content[1] == (byte) 0xFF)) { // check for UTF-16BE BOM 53 | return "UTF-16BE"; 54 | } else if ((content[0] == (byte) 0xFF) && (content[1] == (byte) 0xFE)) { // check for UTF-16LE BOM 55 | return "UTF-16LE"; 56 | } else if ((content[0] == (byte) 0xEF) && (content[1] == (byte) 0xBB) && (content[2] == (byte) 0xBF)) { // check for UTF-8 BOM 57 | return "UTF-8"; 58 | // } else if ((content[0] == (byte)0x3c) && (content[content.length - 1] == (byte)0x3e)) { 59 | // ToDo: trim byte array and check for last byte 60 | } else if (content[0] == (byte) 0x3c) { 61 | String contentString = IOUtils.returnUTF8String(content); 62 | encoding = encodingFromPrologue(contentString); 63 | } 64 | } 65 | return encoding; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/versioncontrol/DateTableCellRenderer.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.versioncontrol; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | import ro.sync.exml.workspace.api.PluginWorkspaceProvider; 6 | 7 | import javax.swing.*; 8 | import javax.swing.table.DefaultTableCellRenderer; 9 | import java.awt.*; 10 | import java.time.LocalDateTime; 11 | import java.time.format.DateTimeFormatter; 12 | import java.util.Locale; 13 | 14 | /** 15 | * @author Markus on 01.02.2016. 16 | */ 17 | public class DateTableCellRenderer extends DefaultTableCellRenderer { 18 | 19 | private static final Logger logger = LogManager.getLogger(DateTableCellRenderer.class); 20 | 21 | @Override 22 | public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, 23 | final boolean hasFocus, final int row, final int column) { 24 | final LocalDateTime date = (LocalDateTime) value; 25 | final DateTimeFormatter formatter; 26 | final String currentLocaleStr = PluginWorkspaceProvider.getPluginWorkspace().getUserInterfaceLanguage(); 27 | if (currentLocaleStr.equals("de_DE")) { 28 | formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy, hh:mm").withLocale(Locale.GERMAN); 29 | } else { 30 | formatter = DateTimeFormatter.ofPattern("MMM d, yyyy, h:mm a").withLocale(Locale.UK); 31 | } 32 | final String dateString = date.format(formatter); 33 | return super.getTableCellRendererComponent(table, dateString, isSelected, hasFocus, row, column); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/versioncontrol/VersionControlListSelectionListener.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.versioncontrol; 2 | 3 | import javax.swing.*; 4 | import javax.swing.event.ListSelectionEvent; 5 | import javax.swing.event.ListSelectionListener; 6 | 7 | /** 8 | * @author Markus on 02.02.2016. 9 | */ 10 | public class VersionControlListSelectionListener implements ListSelectionListener { 11 | 12 | private final JTable table; 13 | private final JButton compareButton; 14 | private final JButton replaceButton; 15 | 16 | public VersionControlListSelectionListener(JTable table, JButton compareButton, JButton replaceButton) { 17 | this.table = table; 18 | this.compareButton = compareButton; 19 | this.replaceButton = replaceButton; 20 | } 21 | 22 | @Override 23 | public void valueChanged(ListSelectionEvent e) { 24 | int nSelected = table.getSelectedRows().length; 25 | if ((nSelected == 1) || (nSelected == 2)) 26 | compareButton.setEnabled(true); 27 | else 28 | compareButton.setEnabled(false); 29 | if (nSelected == 1) 30 | replaceButton.setEnabled(true); 31 | else 32 | replaceButton.setEnabled(false); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/versioncontrol/VersionHistoryEntry.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.versioncontrol; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.net.URL; 6 | import java.time.LocalDateTime; 7 | 8 | /** 9 | * @author Markus on 01.02.2016. 10 | */ 11 | public class VersionHistoryEntry { 12 | 13 | private final URL url; 14 | private final int version; 15 | private final int revision; 16 | private final LocalDateTime changeDate; 17 | 18 | public VersionHistoryEntry(@JsonProperty("url") URL url, 19 | @JsonProperty("version") int version, 20 | @JsonProperty("revision") int revision, 21 | @JsonProperty("changeDate") LocalDateTime changeDate) { 22 | this.url = url; 23 | this.version = version; 24 | this.revision = revision; 25 | this.changeDate = changeDate; 26 | } 27 | 28 | Object[] getDisplayVector() { 29 | return new Object[]{version, revision, changeDate }; 30 | } 31 | 32 | protected URL getURL() { 33 | return url; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/versioncontrol/VersionHistoryPanel.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.versioncontrol; 2 | 3 | import de.axxepta.oxygen.actions.CompareVersionsAction; 4 | import de.axxepta.oxygen.actions.RollbackVersionAction; 5 | import de.axxepta.oxygen.api.TopicHolder; 6 | import de.axxepta.oxygen.utils.Lang; 7 | 8 | import javax.swing.*; 9 | import java.awt.*; 10 | 11 | /** 12 | * @author Markus on 04.07.2016. 13 | */ 14 | public class VersionHistoryPanel extends JPanel { 15 | 16 | public VersionHistoryPanel() { 17 | initView(); 18 | } 19 | 20 | private void initView() { 21 | JTable versionHistoryTable; 22 | // Table (will be put in bottom Box) 23 | versionHistoryTable = new JTable(new VersionHistoryTableModel(null)); 24 | versionHistoryTable.getColumnModel().getColumn(0).setPreferredWidth(20); 25 | versionHistoryTable.getColumnModel().getColumn(1).setPreferredWidth(20); 26 | versionHistoryTable.getColumnModel().getColumn(2).setCellRenderer(new DateTableCellRenderer()); 27 | versionHistoryTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 28 | 29 | VersionHistoryUpdater versionHistoryUpdater = new VersionHistoryUpdater(versionHistoryTable); 30 | TopicHolder.changedEditorStatus.register(versionHistoryUpdater); 31 | 32 | // Two Buttons (with filler) in Pane in Top Box 33 | JButton compareRevisionsButton = new JButton(new CompareVersionsAction(Lang.get(Lang.Keys.cm_compare), versionHistoryTable)); 34 | compareRevisionsButton.setEnabled(false); 35 | JButton replaceRevisionButton = new JButton(new RollbackVersionAction(Lang.get(Lang.Keys.cm_reset), versionHistoryTable)); 36 | replaceRevisionButton.setEnabled(false); 37 | JPanel versionHistoryButtonPanel = new JPanel(); 38 | versionHistoryButtonPanel.setLayout(new BoxLayout(versionHistoryButtonPanel, BoxLayout.X_AXIS)); 39 | compareRevisionsButton.setAlignmentY(Component.CENTER_ALIGNMENT); 40 | versionHistoryButtonPanel.add(compareRevisionsButton); 41 | versionHistoryButtonPanel.add(new Box.Filler( 42 | new Dimension(10, 10), new Dimension(20, 10), new Dimension(50, 10))); 43 | replaceRevisionButton.setAlignmentY(Component.CENTER_ALIGNMENT); 44 | versionHistoryButtonPanel.add(replaceRevisionButton); 45 | 46 | // Table in ScrollPane in bottom Box 47 | versionHistoryTable.getSelectionModel().addListSelectionListener( 48 | new VersionControlListSelectionListener(versionHistoryTable, compareRevisionsButton, replaceRevisionButton)); 49 | JScrollPane scrollPane = new JScrollPane(versionHistoryTable); 50 | 51 | this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 52 | versionHistoryButtonPanel.setAlignmentX(Component.CENTER_ALIGNMENT); 53 | this.add(versionHistoryButtonPanel); 54 | scrollPane.setAlignmentX(Component.CENTER_ALIGNMENT); 55 | this.add(scrollPane); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/versioncontrol/VersionHistoryTableModel.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.versioncontrol; 2 | 3 | import de.axxepta.oxygen.utils.Lang; 4 | import org.apache.log4j.LogManager; 5 | import org.apache.log4j.Logger; 6 | 7 | import javax.swing.table.AbstractTableModel; 8 | import java.net.URL; 9 | import java.util.ArrayList; 10 | import java.util.Collections; 11 | import java.util.List; 12 | 13 | /** 14 | * @author Markus on 01.02.2016. 15 | */ 16 | 17 | public class VersionHistoryTableModel extends AbstractTableModel { 18 | 19 | private static final Logger logger = LogManager.getLogger(VersionHistoryTableModel.class); 20 | 21 | private static final String[] COLUMN_NAMES = 22 | {Lang.get(Lang.Keys.lbl_version), Lang.get(Lang.Keys.lbl_revision), Lang.get(Lang.Keys.lbl_date)}; 23 | 24 | private List data; 25 | 26 | public VersionHistoryTableModel(List data) { 27 | this.data = data != null ? new ArrayList<>(data) : Collections.emptyList(); 28 | } 29 | 30 | @Override 31 | public int getRowCount() { 32 | return data.size(); 33 | } 34 | 35 | @Override 36 | public int getColumnCount() { 37 | return 3; 38 | } 39 | 40 | @Override 41 | public Object getValueAt(int rowIndex, int columnIndex) { 42 | if (rowIndex >= getRowCount()) { 43 | throw new IllegalArgumentException("Row argument out of bounds."); 44 | } 45 | if (columnIndex >= getColumnCount()) { 46 | throw new IllegalArgumentException("Column argument out of bounds."); 47 | } 48 | return data.get(rowIndex).getDisplayVector()[columnIndex]; 49 | } 50 | 51 | @Override 52 | public String getColumnName(final int columnIndex) { 53 | if (columnIndex >= getColumnCount()) 54 | throw new IllegalArgumentException("Column argument out of bounds."); 55 | return COLUMN_NAMES[columnIndex]; 56 | } 57 | 58 | public void setNewContent(List newData) { 59 | logger.info("setNewContent " + newData); 60 | data = new ArrayList<>(newData); 61 | fireTableDataChanged(); 62 | } 63 | 64 | public URL getURL(int rowIndex) { 65 | if (rowIndex >= getRowCount()) { 66 | throw new IllegalArgumentException("Row argument out of bounds."); 67 | } 68 | return data.get(rowIndex).getURL(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/versioncontrol/VersionHistoryUpdater.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.versioncontrol; 2 | 3 | import de.axxepta.oxygen.api.ArgonConst; 4 | import de.axxepta.oxygen.api.BaseXConnectionWrapper; 5 | import de.axxepta.oxygen.api.Connection; 6 | import de.axxepta.oxygen.api.MsgTopic; 7 | import de.axxepta.oxygen.core.ObserverInterface; 8 | import de.axxepta.oxygen.customprotocol.CustomProtocolURLUtils; 9 | import de.axxepta.oxygen.utils.URLUtils; 10 | import org.apache.logging.log4j.LogManager; 11 | import org.apache.logging.log4j.Logger; 12 | 13 | import javax.swing.*; 14 | import java.io.IOException; 15 | import java.net.URL; 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | /** 20 | * @author Markus on 31.01.2016. 21 | */ 22 | 23 | public class VersionHistoryUpdater implements ObserverInterface { 24 | 25 | private final Logger logger = LogManager.getLogger(VersionHistoryUpdater.class); 26 | 27 | private List historyList = new ArrayList<>(); 28 | private final JTable versionHistoryTable; 29 | 30 | VersionHistoryUpdater(JTable versionHistoryTable) { 31 | this.versionHistoryTable = versionHistoryTable; 32 | } 33 | 34 | public void update(MsgTopic type, Object... msg) { 35 | // ToDo: store data permanently in editor watch map to avoid repeated traffic--refresh historyList if editor is saved 36 | if ((msg[0] instanceof String) && !(msg[0]).equals("")) { 37 | String urlString = (String) msg[0]; 38 | String resource = CustomProtocolURLUtils.pathFromURLString(urlString); 39 | 40 | if (urlString.startsWith(ArgonConst.ARGON + ":")) { 41 | try (Connection connection = BaseXConnectionWrapper.getConnection()) { 42 | historyList = connection.getHistory(resource); 43 | } catch (IOException ioe) { 44 | logger.error("Argon connection error while getting meta data from resource " + resource + ": " + ioe.getMessage(), ioe); 45 | } 46 | } else { 47 | historyList = new ArrayList<>(); 48 | } 49 | } 50 | updateVersionHistory(); 51 | } 52 | 53 | public static String checkVersionHistory(URL editorLocation) { 54 | if ((editorLocation != null) && (URLUtils.isArgon(editorLocation))) 55 | return editorLocation.toString(); 56 | else 57 | return ""; 58 | } 59 | 60 | private void updateVersionHistory() { 61 | ((VersionHistoryTableModel) versionHistoryTable.getModel()).setNewContent(historyList); 62 | versionHistoryTable.setFillsViewportHeight(true); 63 | versionHistoryTable.getColumnModel().getColumn(0).setPreferredWidth(20); 64 | versionHistoryTable.getColumnModel().getColumn(1).setPreferredWidth(20); 65 | versionHistoryTable.getColumnModel().getColumn(2).setCellRenderer(new DateTableCellRenderer()); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/workspace/ArgonEditorListener.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.workspace; 2 | 3 | import de.axxepta.oxygen.api.TopicHolder; 4 | import de.axxepta.oxygen.versioncontrol.VersionHistoryUpdater; 5 | import ro.sync.exml.workspace.api.PluginWorkspace; 6 | import ro.sync.exml.workspace.api.listeners.WSEditorListener; 7 | import ro.sync.exml.workspace.api.standalone.StandalonePluginWorkspace; 8 | 9 | import java.net.URL; 10 | 11 | /** 12 | * @author Markus on 02.07.2016. 13 | */ 14 | class ArgonEditorListener extends WSEditorListener { 15 | 16 | private final StandalonePluginWorkspace pluginWorkspaceAccess; 17 | 18 | ArgonEditorListener(final StandalonePluginWorkspace pluginWorkspaceAccess) { 19 | this.pluginWorkspaceAccess = pluginWorkspaceAccess; 20 | } 21 | 22 | @Override 23 | public void editorSaved(final int operationType) { 24 | final URL editorLocation = pluginWorkspaceAccess.getCurrentEditorAccess(PluginWorkspace.MAIN_EDITING_AREA).getEditorLocation(); 25 | TopicHolder.changedEditorStatus.postMessage(VersionHistoryUpdater.checkVersionHistory(editorLocation)); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/workspace/ArgonOptionListener.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.workspace; 2 | 3 | import de.axxepta.oxygen.api.BaseXConnectionWrapper; 4 | import ro.sync.exml.workspace.api.options.WSOptionChangedEvent; 5 | import ro.sync.exml.workspace.api.options.WSOptionListener; 6 | 7 | /** 8 | * @author Markus on 20.10.2015. 9 | */ 10 | public class ArgonOptionListener extends WSOptionListener { 11 | 12 | public ArgonOptionListener(String s) { 13 | super(s); 14 | } 15 | 16 | @Override 17 | public void optionValueChanged(WSOptionChangedEvent wsOptionChangedEvent) { 18 | BaseXConnectionWrapper.refreshFromOptions(false); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/workspace/ArgonToolbarComponentCustomizer.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.workspace; 2 | 3 | import ro.sync.exml.workspace.api.standalone.ToolbarComponentsCustomizer; 4 | import ro.sync.exml.workspace.api.standalone.ToolbarInfo; 5 | import ro.sync.exml.workspace.api.standalone.ui.ToolbarButton; 6 | 7 | import javax.swing.*; 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | import java.util.List; 11 | 12 | class ArgonToolbarComponentCustomizer implements ToolbarComponentsCustomizer { 13 | 14 | private static final String ARGON_WORKSPACE_ACCESS_TOOLBAR_ID = "ArgonWorkspaceAccessToolbarID"; 15 | 16 | private final ToolbarButton runQueryButton; 17 | private final ToolbarButton newVersionButton; 18 | private final ToolbarButton saveToArgonButton; 19 | private final ToolbarButton replyCommentButton; 20 | 21 | ArgonToolbarComponentCustomizer(ToolbarButton runQueryButton, ToolbarButton newVersionButton, 22 | ToolbarButton saveToArgonButton, ToolbarButton replyCommentButton) { 23 | this.runQueryButton = runQueryButton; 24 | this.newVersionButton = newVersionButton; 25 | this.saveToArgonButton = saveToArgonButton; 26 | this.replyCommentButton = replyCommentButton; 27 | } 28 | 29 | @Override 30 | public void customizeToolbar(ToolbarInfo toolbarInfo) { 31 | 32 | addButtons(ARGON_WORKSPACE_ACCESS_TOOLBAR_ID, 33 | new JComponent[]{runQueryButton, new JSeparator(SwingConstants.VERTICAL), newVersionButton}, 34 | toolbarInfo, -1); 35 | 36 | // Set title 37 | if (ARGON_WORKSPACE_ACCESS_TOOLBAR_ID.equals(toolbarInfo.getToolbarID())) 38 | toolbarInfo.setTitle("BaseX DB Connection"); 39 | 40 | addButtons("File", new JComponent[]{saveToArgonButton}, toolbarInfo, 2); 41 | addButtons("toolbar.review", new JComponent[]{replyCommentButton}, toolbarInfo, -1); 42 | } 43 | 44 | private void addButtons(String toolbarID, JComponent[] components, final ToolbarInfo toolbarInfo, int pos) { 45 | if (toolbarID.equals(toolbarInfo.getToolbarID())) { 46 | List comps = new ArrayList<>(); 47 | JComponent[] initialComponents = toolbarInfo.getComponents(); 48 | boolean hasInitialComponents = (initialComponents != null) && (initialComponents.length > 0); 49 | if (hasInitialComponents) { 50 | // Add initial toolbar components 51 | comps.addAll(Arrays.asList(initialComponents)); 52 | } 53 | for (JComponent component : components) { 54 | if (pos == -1) 55 | comps.add(component); 56 | else 57 | comps.add(pos, component); 58 | } 59 | toolbarInfo.setComponents(comps.toArray(new JComponent[comps.size()])); 60 | } 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/workspace/ArgonValidationProblemsFilter.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.workspace; 2 | 3 | import de.axxepta.oxygen.utils.ConnectionWrapper; 4 | import org.apache.logging.log4j.LogManager; 5 | import org.apache.logging.log4j.Logger; 6 | import ro.sync.document.DocumentPositionedInfo; 7 | import ro.sync.exml.workspace.api.editor.WSEditor; 8 | import ro.sync.exml.workspace.api.editor.validation.ValidationProblems; 9 | import ro.sync.exml.workspace.api.editor.validation.ValidationProblemsFilter; 10 | 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import java.util.Scanner; 16 | 17 | class ArgonValidationProblemsFilter extends ValidationProblemsFilter { 18 | 19 | private static final Logger logger = LogManager.getLogger(ArgonValidationProblemsFilter.class); 20 | 21 | private final WSEditor editorAccess; 22 | 23 | ArgonValidationProblemsFilter(WSEditor editorAccess) { 24 | super(); 25 | this.editorAccess = editorAccess; 26 | } 27 | 28 | @Override 29 | public void filterValidationProblems(ValidationProblems validationProblems) { 30 | final List problemList = new ArrayList<>(); 31 | Thread validatorThread = new Thread(new QueryValidator(editorAccess, problemList)); 32 | validatorThread.run(); 33 | try { 34 | validatorThread.join(); 35 | } catch (InterruptedException ie) { 36 | // 37 | } 38 | 39 | //The DocumentPositionInfo represents an error with location in the document and has a constructor like: 40 | // public DocumentPositionedInfo(int severity, String message, String systemID, int line, int column, int length) 41 | validationProblems.setProblemsList(problemList); 42 | super.filterValidationProblems(validationProblems); 43 | } 44 | 45 | private static class QueryValidator implements Runnable { 46 | 47 | private final WSEditor editorAccess; 48 | private final List problemList; 49 | 50 | QueryValidator(WSEditor editorAccess, List problemList) { 51 | this.editorAccess = editorAccess; 52 | this.problemList = problemList; 53 | } 54 | 55 | public void run() { 56 | String editorContent; 57 | logger.debug("filter validation problems"); 58 | try { 59 | InputStream editorStream = editorAccess.createContentInputStream(); 60 | Scanner s = new java.util.Scanner(editorStream, "UTF-8").useDelimiter("\\A"); 61 | editorContent = s.hasNext() ? s.next() : ""; 62 | editorStream.close(); 63 | } catch (IOException er) { 64 | logger.error(er); 65 | editorContent = ""; 66 | } 67 | List valProbStr; 68 | try { 69 | valProbStr = ConnectionWrapper.parse(editorContent); 70 | } catch (Exception er) { 71 | logger.error("query to BaseX failed"); 72 | valProbStr = new ArrayList<>(); 73 | valProbStr.add("1"); 74 | valProbStr.add("1"); 75 | valProbStr.add("Fatal BaseX request error: " + er.getMessage()); 76 | er.printStackTrace(); 77 | } 78 | if (valProbStr.size() > 0) { 79 | DocumentPositionedInfo dpi = 80 | new DocumentPositionedInfo(DocumentPositionedInfo.SEVERITY_ERROR, valProbStr.get(2), "", 81 | Integer.parseInt(valProbStr.get(0)), Integer.parseInt(valProbStr.get(1)), 0); 82 | problemList.add(dpi); 83 | } 84 | } 85 | 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/de/axxepta/oxygen/workspace/WorkspaceAccessPlugin.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.workspace; 2 | 3 | import ro.sync.exml.plugin.Plugin; 4 | import ro.sync.exml.plugin.PluginDescriptor; 5 | 6 | /** 7 | * Workspace access plugin. 8 | * 9 | * @author daltiparmak on 02.04.15. 10 | */ 11 | public class WorkspaceAccessPlugin extends Plugin { 12 | 13 | /** 14 | * The static plugin instance. 15 | */ 16 | private static WorkspaceAccessPlugin instance = null; 17 | 18 | /** 19 | * Constructs the plugin. 20 | * 21 | * @param descriptor The plugin descriptor 22 | */ 23 | public WorkspaceAccessPlugin(PluginDescriptor descriptor) { 24 | super(descriptor); 25 | 26 | if (instance != null) { 27 | throw new IllegalStateException("Already instantiated!"); 28 | } 29 | instance = this; 30 | } 31 | 32 | /** 33 | * Get the plugin instance. 34 | * 35 | * @return the shared plugin instance. 36 | */ 37 | public static WorkspaceAccessPlugin getInstance() { 38 | return instance; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/resources/Argon_de_DE.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/Argon_de_DE.properties -------------------------------------------------------------------------------- /src/main/resources/api/MetaTemplate.xml: -------------------------------------------------------------------------------- 1 | 2 | 0.0.3 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | true 19 | true 20 | false 21 | 22 | 23 | true 24 | true 25 | false 26 | 27 | 28 | true 29 | true 30 | false 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/main/resources/api/checked-out-files.xq: -------------------------------------------------------------------------------- 1 | (:~ Lock database. :) 2 | declare variable $LOCK-DB := '~argon'; 3 | declare variable $USER-FILE := '~usermanagement'; 4 | 5 | let $user := user:current() 6 | let $lock-file := db:open($LOCK-DB, $USER-FILE) 7 | 8 | for $lock in $lock-file//locks/*[@user = $user] 9 | return ( 10 | $lock/name(), $lock/text() 11 | ) -------------------------------------------------------------------------------- /src/main/resources/api/create-database.xq: -------------------------------------------------------------------------------- 1 | (:~ New database name. :) 2 | declare variable $DB as xs:string external; 3 | declare variable $CHOP as xs:string external; 4 | declare variable $FTINDEX as xs:string external; 5 | declare variable $TEXTINDEX as xs:string external; 6 | declare variable $ATTRINDEX as xs:string external; 7 | declare variable $TOKENINDEX as xs:string external; 8 | 9 | let $exists := db:exists($DB) 10 | let $meta := concat('~meta_', $DB) 11 | let $history := concat('~history_', $DB) 12 | 13 | return if(not($exists)) then ( 14 | db:create($meta), 15 | db:create($history), 16 | db:create($DB, (), (), map { 'chop' : $CHOP , 'ftindex' : $FTINDEX , 'textindex' : $TEXTINDEX , 'attrindex' : $ATTRINDEX , 'tokenindex' : $TOKENINDEX }) 17 | ) else () 18 | -------------------------------------------------------------------------------- /src/main/resources/api/delete-database.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 5 | let $path := substring-after($PATH, '/') 6 | return if(string-length($path) = 0) then ( 7 | (: drop database :) 8 | db:drop($db) 9 | ) else ( 10 | db:delete($db, $path) 11 | ) -------------------------------------------------------------------------------- /src/main/resources/api/delete-repo.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ Resource. :) 4 | declare variable $RESOURCE as xs:base64Binary external; 5 | 6 | let $path := db:system()//repopath || '/' || $PATH 7 | return file:delete($path, true()) -------------------------------------------------------------------------------- /src/main/resources/api/delete-restxq.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $system := db:system() 5 | let $webpath := $system//webpath/string() 6 | let $restxqpath := $system//restxqpath/string() 7 | let $path := file:resolve-path($restxqpath, file:resolve-path($webpath)) || $PATH 8 | return file:delete($path, true()) -------------------------------------------------------------------------------- /src/main/resources/api/drop-database.xq: -------------------------------------------------------------------------------- 1 | (:~ New database name. :) 2 | declare variable $DB as xs:string external; 3 | 4 | let $exists := db:exists($DB) 5 | let $meta := concat('~meta_', $DB) 6 | let $history := concat('~history_', $DB) 7 | 8 | return if(not($exists)) then ( 9 | ) else ( 10 | db:drop($DB), 11 | db:drop($meta), 12 | db:drop($history) 13 | ) -------------------------------------------------------------------------------- /src/main/resources/api/exists-database.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 5 | let $path := substring-after($PATH, '/') 6 | 7 | return db:exists($db, $path) -------------------------------------------------------------------------------- /src/main/resources/api/exists-repo.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $path := db:system()//repopath || '/' || $PATH 5 | 6 | return file:exists($path) -------------------------------------------------------------------------------- /src/main/resources/api/exists-restxq.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $system := db:system() 5 | let $webpath := $system//webpath/string() 6 | let $restxqpath := $system//restxqpath/string() 7 | let $path := file:resolve-path($restxqpath, file:resolve-path($webpath)) || $PATH 8 | 9 | return file:exists($path) -------------------------------------------------------------------------------- /src/main/resources/api/find-database.xq: -------------------------------------------------------------------------------- 1 | (:~ Root path for search. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ Search filter. :) 4 | declare variable $FILTER as xs:string external; 5 | 6 | (: name of database :) 7 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 8 | (: path: ensure existence trailing slash :) 9 | let $path := replace(substring-after($PATH, '/'), '([^/])$', '$1/') 10 | 11 | let $dbconnect := db:open($db, $path) 12 | let $ft := $db//*[contains(., $FILTER)] 13 | 14 | return ( 15 | $ft 16 | ) -------------------------------------------------------------------------------- /src/main/resources/api/get-database.xq: -------------------------------------------------------------------------------- 1 | declare option output:method "basex"; 2 | 3 | (: test :) 4 | (:~ Path to resource. :) 5 | declare variable $PATH as xs:string external; 6 | 7 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 8 | let $path := substring-after($PATH, '/') 9 | let $metadb := concat('~meta_', $db) 10 | let $metapath := concat($path, '.xml') 11 | let $exists := db:exists($db, $path) 12 | 13 | let $doctypecomponents := if(db:exists($metadb, $metapath)) then ( 14 | db:open($metadb, $metapath)//doctypecomponent/text() 15 | ) else () 16 | 17 | return if($exists and db:is-xml($db, $path)) then ( 18 | let $doctype := if(not(empty(($doctypecomponents)))) then ( 19 | , 20 | 21 | ) else () 22 | (: 23 | let $doctype := if(contains($path, 'ditamap')) then 24 | (, ) 25 | else if(contains($path, 'c_')) then 26 | (, ) 27 | else if(contains($path, 'r_')) then 28 | (, ) 29 | else if(contains($path, 't_')) then 30 | (, ) 31 | else if(contains($path, 'g_')) then 32 | (, ) 33 | else () 34 | :) 35 | let $params := 36 | 37 | 38 | { $doctype } 39 | 40 | return serialize(db:open($db, $path), $params) 41 | ) else if($exists and db:is-raw($db, $path)) then ( 42 | db:retrieve($db, $path) 43 | ) else ( 44 | (: raise error if database or resource does not exist :) 45 | error(xs:QName("api"), "Database resource does not exist: " || $PATH) 46 | ) 47 | -------------------------------------------------------------------------------- /src/main/resources/api/get-history.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | declare variable $histpattern := '[0-9]{4}-[0-1][0-9]-[0-3][0-9]_[0-2][0-9]-[0-5][0-9]_v[0-9]+r[0-9]+'; 5 | 6 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 7 | let $path := substring-after($PATH, '/') 8 | let $metapath := concat($path, '.xml') 9 | 10 | let $histdb := concat('argon:~history_', $db) 11 | let $metadb := concat('~meta_', $db) 12 | return if(db:exists($metadb, $metapath)) then ( 13 | let $entries := db:open($metadb, $metapath)/*//historyfile/text() 14 | return if(empty($entries)) then ( 15 | () 16 | ) else ( 17 | for $entry in $entries 18 | let $sigpos := if (matches($entry,$histpattern)) 19 | then string-length(tokenize($entry, $histpattern)[1]) + 1 20 | else (0) 21 | let $histsignature := substring($entry, $sigpos) 22 | let $sigparts := tokenize($histsignature, '[v|r|.]') 23 | return (concat($histdb, '/', $entry), subsequence($sigparts, 2, 2), substring($histsignature, 0, 17)) 24 | ) 25 | ) else ( 26 | () 27 | ) -------------------------------------------------------------------------------- /src/main/resources/api/get-repo.xq: -------------------------------------------------------------------------------- 1 | declare option output:method "basex"; 2 | 3 | (:~ Path to resource. :) 4 | declare variable $PATH as xs:string external; 5 | 6 | let $path := db:system()//repopath || '/' || $PATH 7 | 8 | return if(file:exists($path)) then ( 9 | file:read-binary($path) 10 | ) else ( 11 | (: raise error if resource does not exist :) 12 | error(xs:QName("api"), "Repository resource does not exist: " || $PATH) 13 | ) 14 | -------------------------------------------------------------------------------- /src/main/resources/api/get-restxq.xq: -------------------------------------------------------------------------------- 1 | declare option output:method "basex"; 2 | 3 | (:~ Path to resource. :) 4 | declare variable $PATH as xs:string external; 5 | 6 | let $system := db:system() 7 | let $webpath := $system//webpath/string() 8 | let $restxqpath := $system//restxqpath/string() 9 | let $path := file:resolve-path($restxqpath, file:resolve-path($webpath)) || $PATH 10 | 11 | return if(file:exists($path)) then ( 12 | file:read-binary($path) 13 | ) else ( 14 | (: raise error if resource does not exist :) 15 | error(xs:QName("api"), "RESTXQ resource does not exist: " || $PATH) 16 | ) -------------------------------------------------------------------------------- /src/main/resources/api/init.xq: -------------------------------------------------------------------------------- 1 | (:~ Source. :) 2 | declare variable $RESOURCE as xs:string external; 3 | 4 | declare variable $LOCK-DB := '~argon'; 5 | declare variable $REPO_HIST := '~history_~repo'; 6 | declare variable $XQ_HIST := '~history_~restxq'; 7 | declare variable $PATH := 'MetaTemplate.xml'; 8 | 9 | let $exists := db:exists($LOCK-DB) 10 | let $xq_exists := db:exists($XQ_HIST) 11 | let $repo_exists := db:exists($REPO_HIST) 12 | 13 | return ( 14 | if($exists) then ( db:replace($LOCK-DB, $PATH, $RESOURCE) ) else ( db:create($LOCK-DB, $RESOURCE, $PATH) ), 15 | if($xq_exists) then () else (db:create($XQ_HIST)), 16 | if($repo_exists) then () else (db:create($REPO_HIST)) 17 | ) -------------------------------------------------------------------------------- /src/main/resources/api/list-database.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | if(string-length($PATH) = 0) then ( 5 | (: skip locking databases :) 6 | for $db in db:list()[not(starts-with(., '~'))] 7 | return ('directory', $db) 8 | ) else ( 9 | (: name of database :) 10 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 11 | (: path: ensure existence trailing slash :) 12 | let $path := replace(substring-after($PATH, '/'), '([^/])$', '$1/') 13 | (: retrieve all entries on this and lower levels :) 14 | let $resources := db:list-details($db, $path) 15 | (: retrieve entries of current level :) 16 | for $entry in distinct-values( 17 | for $resource in $resources 18 | let $without-root := substring($resource, string-length($path) + 1) 19 | let $name := substring-before($without-root, '/') 20 | return if($name) then ( 21 | $name 22 | ) else ( 23 | $without-root 24 | ) 25 | ) 26 | let $full-path := $path || $entry 27 | let $resource := $resources[. = $full-path] 28 | let $dir := empty($resource) 29 | (: show directories first, case-insensitive order :) 30 | order by $dir descending, lower-case($entry) 31 | return if($dir) then ( 32 | 'directory', $entry 33 | ) else ( 34 | (: xml and binary resources :) 35 | 'resource', $entry 36 | ) 37 | ) -------------------------------------------------------------------------------- /src/main/resources/api/list-repo.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $repopath := if (empty(db:system()//repopath)) then ( 5 | error(xs:QName("api"), "Need admin rights to access repo path.") 6 | ) else (db:system()//repopath) 7 | let $path := db:system()//repopath || '/' || $PATH 8 | for $resource in file:children($path) 9 | let $name := file:name($resource) 10 | let $dir := file:is-dir($resource) 11 | (: show directories first, case-insensitive order :) 12 | order by $dir descending, lower-case($name) 13 | 14 | return ( 15 | if($dir) then 'directory' else 'resource', 16 | (: file:size($resource) :) 17 | $name 18 | ) -------------------------------------------------------------------------------- /src/main/resources/api/list-restxq.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $system := db:system() 5 | let $webpath := $system//webpath/string() 6 | (: absolute, or relative to webpath :) 7 | let $restxqpath := if (empty($system//restxqpath)) then ( 8 | error(xs:QName("api"), "Need admin rights to access query path.") 9 | ) else ($system//restxqpath/string()) 10 | 11 | let $path := file:resolve-path($restxqpath, file:resolve-path($webpath)) || $PATH 12 | for $resource in file:children($path) 13 | let $name := file:name($resource) 14 | let $dir := file:is-dir($resource) 15 | (: show directories first, case-insensitive order :) 16 | order by $dir descending, lower-case($name) 17 | return ( 18 | if($dir) then 'directory' else 'resource', 19 | (: file:size($resource) :) 20 | $name 21 | ) -------------------------------------------------------------------------------- /src/main/resources/api/listall-database.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | if(string-length($PATH) = 0) then ( 5 | (: skip locking databases :) 6 | for $db in db:list()[not(starts-with(., '~'))] 7 | return ('directory', $db) 8 | ) else ( 9 | (: name of database :) 10 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 11 | (: path: ensure existence trailing slash :) 12 | let $path := replace(substring-after($PATH, '/'), '([^/])$', '$1/') 13 | (: retrieve all entries on this and lower levels :) 14 | let $resources := db:list-details($db, $path)/text() 15 | (: extract directories on all levels :) 16 | let $directories := distinct-values( 17 | for $resource in $resources 18 | let $pathtokens := tokenize($resource, '/') 19 | let $ntokens := count($pathtokens) - 1 20 | return if ($ntokens > 1) then ( 21 | for $i in (2 to $ntokens) 22 | let $subpathsequence := subsequence($pathtokens, 1, $i) 23 | return string-join( 24 | for $component in $subpathsequence 25 | return ($component, '/') 26 | ,'') 27 | ) else ( 28 | () 29 | ) 30 | ) 31 | (: combine and sort files and directories :) 32 | let $allresources := sort(($resources, $directories)) 33 | (: return types and names, pair-wise :) 34 | for $entry in $allresources 35 | return if(ends-with($entry, '/')) then ( 36 | 'directory', $entry 37 | ) else ( 38 | (: xml and binary resources :) 39 | 'resource', $entry 40 | ) 41 | ) -------------------------------------------------------------------------------- /src/main/resources/api/listall-repo.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $repopath := if (empty(db:system()//repopath)) then ( 5 | error(xs:QName("api"), "Need admin rights to access repo path.") 6 | ) else (db:system()//repopath) 7 | 8 | let $path := db:system()//repopath || '/' || $PATH 9 | for $resource in file:list($path, true()) 10 | let $name := concat($path, '/', $resource) 11 | let $dir := file:is-dir($name) 12 | (: show directories first, case-insensitive order :) 13 | order by $dir descending, lower-case($name) 14 | 15 | return ( 16 | if($dir) then 'directory' else 'resource', 17 | (: file:size($resource) :) 18 | concat($PATH, '/', $resource) 19 | ) -------------------------------------------------------------------------------- /src/main/resources/api/listall-restxq.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $system := db:system() 5 | let $webpath := $system//webpath/string() 6 | (: absolute, or relative to webpath :) 7 | let $restxqpath := if (empty($system//restxqpath)) then ( 8 | error(xs:QName("api"), "Need admin rights to access query path.") 9 | ) else ($system//restxqpath/string()) 10 | 11 | let $path := file:resolve-path($restxqpath, file:resolve-path($webpath)) || $PATH 12 | for $resource in file:list($path, true()) 13 | let $name := concat($path, '/', $resource) 14 | let $dir := file:is-dir($name) 15 | (: show directories first, case-insensitive order :) 16 | order by $dir descending, lower-case($name) 17 | return ( 18 | if($dir) then 'directory' else 'resource', 19 | concat($PATH, '/', $resource) 20 | ) -------------------------------------------------------------------------------- /src/main/resources/api/lock.xq: -------------------------------------------------------------------------------- 1 | (:~ Source. :) 2 | declare variable $SOURCE as xs:string external; 3 | (:~ Path to resource. :) 4 | declare variable $PATH as xs:string external; 5 | 6 | (:~ Lock database. :) 7 | declare variable $LOCK-DB := '~argon'; 8 | declare variable $USER-FILE := '~usermanagement'; 9 | 10 | let $user := user:current() 11 | let $lock-file := db:open($LOCK-DB, $USER-FILE) 12 | let $my-lock := if(exists($lock-file)) then ( 13 | $lock-file//*[name() = $SOURCE][text() = $PATH] 14 | ) else () 15 | 16 | let $locks := ( 17 | if(exists($lock-file)) 18 | then $lock-file 19 | else document { admin 20 | admin } 21 | ) update ( 22 | insert node element { $SOURCE } { attribute user { $user }, $PATH } into .//locks ) 23 | 24 | return if(exists($lock-file) and exists($my-lock) ) then ( 25 | () 26 | ) else if(exists($lock-file) ) then ( 27 | db:replace($LOCK-DB, $USER-FILE, $locks) 28 | ) else ( 29 | db:add($LOCK-DB, $locks, $USER-FILE) 30 | ) -------------------------------------------------------------------------------- /src/main/resources/api/locked.xq: -------------------------------------------------------------------------------- 1 | (:~ Source. :) 2 | declare variable $SOURCE as xs:string external; 3 | (:~ Path to resource. :) 4 | declare variable $PATH as xs:string external; 5 | 6 | (:~ Lock database. :) 7 | declare variable $LOCK-DB := '~argon'; 8 | declare variable $USER-FILE := '~usermanagement'; 9 | 10 | let $user := user:current() 11 | let $lock-file := db:open($LOCK-DB, $USER-FILE) 12 | return exists($lock-file) and exists($lock-file//locks/*[name() = $SOURCE][text() = $PATH]) and empty($lock-file//locks/*[name() = $SOURCE][text() = $PATH][@user = $user]) -------------------------------------------------------------------------------- /src/main/resources/api/lockedByUser.xq: -------------------------------------------------------------------------------- 1 | (:~ Source. :) 2 | declare variable $SOURCE as xs:string external; 3 | (:~ Path to resource. :) 4 | declare variable $PATH as xs:string external; 5 | 6 | (:~ Lock database. :) 7 | declare variable $LOCK-DB := '~argon'; 8 | declare variable $USER-FILE := '~usermanagement'; 9 | 10 | let $user := user:current() 11 | return db:exists($LOCK-DB, $USER-FILE) and max(db:open($LOCK-DB, $USER-FILE)//[name() = $SOURCE and text() = $PATH and @user = $user]) 12 | -------------------------------------------------------------------------------- /src/main/resources/api/newdir-repo.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to new directory. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $repopath := if (empty(db:system()//repopath)) then ( 5 | error(xs:QName("api"), "Need admin rights to access repo path.") 6 | ) else (db:system()//repopath) 7 | 8 | let $path := $repopath || '/' || $PATH 9 | let $dir-exists := file:exists($path) 10 | return if($dir-exists) then () else(file:create-dir($path)) -------------------------------------------------------------------------------- /src/main/resources/api/newdir-restxq.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to new directory. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $system := db:system() 5 | let $webpath := $system//webpath/string() 6 | let $restxqpath := if (empty($system//restxqpath)) then ( 7 | error(xs:QName("api"), "Need admin rights to access query path.") 8 | ) else ($system//restxqpath/string()) 9 | 10 | let $path := file:resolve-path($restxqpath, file:resolve-path($webpath)) || $PATH 11 | let $dir-exists := file:exists($path) 12 | return if($dir-exists) then () else(file:create-dir($path)) -------------------------------------------------------------------------------- /src/main/resources/api/no-lock-set.xq: -------------------------------------------------------------------------------- 1 | (:~ Source. :) 2 | declare variable $SOURCE as xs:string external; 3 | (:~ Path to resource. :) 4 | declare variable $PATH as xs:string external; 5 | 6 | (:~ Lock database. :) 7 | declare variable $LOCK-DB := '~argon'; 8 | declare variable $USER-FILE := '~usermanagement'; 9 | 10 | not(db:exists($LOCK-DB, $USER-FILE)) or empty(db:open($LOCK-DB, $USER-FILE)/*[name() = $SOURCE][text() = $PATH]) 11 | -------------------------------------------------------------------------------- /src/main/resources/api/parse-repo.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $path := db:system()//repopath || '/' || $PATH 5 | return xquery:parse-uri($path, map { 'plan': false() }) -------------------------------------------------------------------------------- /src/main/resources/api/parse-restxq.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | 4 | let $system := db:system() 5 | let $webpath := $system//webpath/string() 6 | let $restxqpath := $system//restxqpath/string() 7 | let $path := file:resolve-path($restxqpath, file:resolve-path($webpath)) || $PATH 8 | return xquery:parse-uri($path, map { 'plan': false() }) -------------------------------------------------------------------------------- /src/main/resources/api/parse.xq: -------------------------------------------------------------------------------- 1 | 2 | (:~ Path to resource. :) 3 | declare variable $XQUERY as xs:string external; 4 | 5 | xquery:parse($XQUERY, map { 'plan': false(), 'pass': true() }) 6 | -------------------------------------------------------------------------------- /src/main/resources/api/put-repo.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ Resource (XML string or Base64). :) 4 | declare variable $RESOURCE as xs:string external; 5 | (:~ Binary storage? :) 6 | declare variable $BINARY as xs:string external; 7 | (:~ Original encoding for XML. Irrelevant for Repo. :) 8 | declare variable $ENCODING as xs:string external; 9 | (:~ Owner of resource. :) 10 | declare variable $OWNER as xs:string external; 11 | (:~ Put copy in history and increase revision? :) 12 | declare variable $VERSIONIZE as xs:boolean external; 13 | (: increase version? :) 14 | declare variable $VERSION-UP as xs:boolean external; 15 | 16 | let $repopath := if (empty(db:system()//repopath)) then ( 17 | error(xs:QName("api"), "Need admin rights to access repo path.") 18 | ) else (db:system()//repopath) 19 | 20 | let $pathtokens := tokenize($PATH, '/') 21 | let $ntokens := count($pathtokens) 22 | let $dir := if($ntokens gt 1) then ( 23 | let $tokenlengths := for $i in (1 to ($ntokens -1)) return string-length(subsequence($pathtokens, $i, 1)) 24 | let $dirEnd := sum($tokenlengths) + $ntokens - 2 25 | return concat($repopath || '/' , substring($PATH, 1, $dirEnd)) 26 | ) else ( 27 | $repopath || '' 28 | ) 29 | 30 | let $path := $repopath || '/' || $PATH 31 | let $dir-exists := file:exists($dir) 32 | 33 | return if($BINARY eq 'false') then ( 34 | if($dir-exists) then () else(file:create-dir($dir)), 35 | file:write-text($path, $RESOURCE) 36 | ) else ( 37 | if($dir-exists) then () else(file:create-dir($dir)), 38 | file:write-binary($path, xs:base64Binary($RESOURCE)) 39 | ) -------------------------------------------------------------------------------- /src/main/resources/api/put-restxq.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ Resource (XML string or Base64). :) 4 | declare variable $RESOURCE as xs:string external; 5 | (:~ Binary storage? :) 6 | declare variable $BINARY as xs:string external; 7 | (:~ Original encoding for XML. Irrelevant for RestXQ. :) 8 | declare variable $ENCODING as xs:string external; 9 | (:~ Owner of resource. :) 10 | declare variable $OWNER as xs:string external; 11 | (:~ Put copy in history and increase revision? :) 12 | declare variable $VERSIONIZE as xs:boolean external; 13 | (: increase version? :) 14 | declare variable $VERSION-UP as xs:boolean external; 15 | 16 | let $system := db:system() 17 | let $webpath := $system//webpath/string() 18 | let $restxqpath := if (empty($system//restxqpath)) then ( 19 | error(xs:QName("api"), "Need admin rights to access query path.") 20 | ) else ($system//restxqpath/string()) 21 | 22 | let $pathtokens := tokenize($PATH, '/') 23 | let $ntokens := count($pathtokens) 24 | let $dir := if($ntokens gt 1) then ( 25 | let $tokenlengths := for $i in (1 to ($ntokens -1)) return string-length(subsequence($pathtokens, $i, 1)) 26 | let $dirEnd := sum($tokenlengths) + $ntokens - 2 27 | return concat(file:resolve-path($restxqpath, file:resolve-path($webpath)) || '/' , substring($PATH, 1, $dirEnd)) 28 | ) else ( 29 | file:resolve-path($restxqpath, file:resolve-path($webpath)) || '' 30 | ) 31 | 32 | let $path := file:resolve-path($restxqpath, file:resolve-path($webpath)) || $PATH 33 | let $dir-exists := file:exists($dir) 34 | return if($BINARY eq 'false') then ( 35 | if($dir-exists) then () else(file:create-dir($dir)), 36 | file:write-text($path, $RESOURCE) 37 | ) else ( 38 | if($dir-exists) then () else(file:create-dir($dir)), 39 | file:write-binary($path, xs:base64Binary($RESOURCE)) 40 | ) -------------------------------------------------------------------------------- /src/main/resources/api/rename-database.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ New path to resource. :) 4 | declare variable $NEWPATH as xs:string external; 5 | 6 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 7 | let $path := substring-after($PATH, '/') 8 | let $newpath := substring-after($NEWPATH, '/') 9 | 10 | let $is-db := (string-length($path) = 0) 11 | let $is-dir := if ($is-db) then (false) else ( 12 | not(db:exists($db, $path)) 13 | ) 14 | 15 | let $histdb := '~history_' 16 | let $metadb := '~meta_' 17 | let $oldmetadb := concat($metadb, $db) 18 | let $oldhistdb := concat($histdb, $db) 19 | let $newmetadb := concat($metadb, $NEWPATH) 20 | let $newhistdb := concat($histdb, $NEWPATH) 21 | let $metapath := concat($path, '.xml') 22 | let $newmetapath := concat($newpath, '.xml') 23 | (: obtain all files if directory :) 24 | let $files := if ($is-dir) then ( 25 | db:list($db, $path) 26 | ) else ( () ) 27 | let $newfiles := if ($is-dir) then ( 28 | for $file in $files 29 | return concat($newpath, substring-after($file, $path)) 30 | ) else ( () ) 31 | let $oldmetafiles := if ($is-dir) then ( 32 | for $file in $files 33 | return concat($file, '.xml') 34 | ) else ( () ) 35 | let $newmetafiles := if ($is-dir) then ( 36 | for $file in $newfiles 37 | return concat($file, '.xml') 38 | ) else ( () ) 39 | 40 | (: Check for admin rights. :) 41 | let $user := user:current() 42 | let $userdetails := try { 43 | user:list-details($user) 44 | } catch * { 45 | () 46 | } 47 | let $permission := if (empty($userdetails)) then ( 48 | 'not' 49 | ) else ( 50 | $userdetails/@permission/string() 51 | ) 52 | let $is-admin := ($permission eq 'admin') 53 | 54 | return if($is-db) then ( 55 | if ($is-admin) then ( 56 | (: rename database :) 57 | db:alter($db, $NEWPATH), 58 | db:alter($oldmetadb, $newmetadb), 59 | db:alter($oldhistdb, $newhistdb) 60 | ) else ( 61 | error(xs:QName("api"), "Need admin rights to rename databases") 62 | ) 63 | ) else if($is-dir) then ( 64 | for $file at $pos in $files 65 | return ( 66 | db:rename($db, $file, $newfiles[position() = $pos]), 67 | db:rename($oldmetadb, $oldmetafiles[position() = $pos], $newmetafiles[position() = $pos]) 68 | ) 69 | ) else ( 70 | db:rename($db, $path, $newpath), 71 | db:rename($oldmetadb, $metapath, $newmetapath) 72 | ) -------------------------------------------------------------------------------- /src/main/resources/api/rename-repo.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ New path to resource. :) 4 | declare variable $NEWPATH as xs:string external; 5 | 6 | let $path := db:system()//repopath || '/' || $PATH 7 | let $newpath := db:system()//repopath || '/' || $NEWPATH 8 | 9 | return file:move($path, $newpath) 10 | -------------------------------------------------------------------------------- /src/main/resources/api/rename-restxq.xq: -------------------------------------------------------------------------------- 1 | (:~ Path to resource. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ New path to resource. :) 4 | declare variable $NEWPATH as xs:string external; 5 | 6 | let $system := db:system() 7 | let $webpath := $system//webpath/string() 8 | let $restxqpath := $system//restxqpath/string() 9 | let $path := file:resolve-path($restxqpath, file:resolve-path($webpath)) || $PATH 10 | let $newpath := file:resolve-path($restxqpath, file:resolve-path($webpath)) || $NEWPATH 11 | 12 | return file:move($path, $newpath) 13 | -------------------------------------------------------------------------------- /src/main/resources/api/search-attributes.xq: -------------------------------------------------------------------------------- 1 | (:~ Root path for search. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ Search filter. :) 4 | declare variable $FILTER as xs:string external; 5 | (:~ Whole word. :) 6 | declare variable $WHOLE as xs:string external; 7 | (:~ Exact Case. :) 8 | declare variable $EXACTCASE as xs:string external; 9 | 10 | let $whole := ($WHOLE eq 'true') 11 | let $exactcase := ($EXACTCASE eq 'true') 12 | 13 | (: name of database :) 14 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 15 | (: path: ensure existence trailing slash :) 16 | let $path := replace(substring-after($PATH, '/'), '([^/])$', '$1/') 17 | 18 | let $resources := if (empty($path)) then ( 19 | db:list($db) 20 | ) else ( 21 | db:list($db, $path) 22 | ) 23 | 24 | for $resource in $resources 25 | let $conn := db:open($db, $resource) 26 | return if ($whole) then ( 27 | if ($exactcase) then ( 28 | if ($conn//@*[name(.) = $FILTER]) then ($resource) else () 29 | ) else ( 30 | if ($conn//@*[lower-case(name(.)) = lower-case($FILTER)]) then ($resource) else () 31 | ) 32 | ) else ( 33 | if ($exactcase) then ( 34 | if ($conn//*/@*[contains(name(.), $FILTER)]) then ($resource) else () 35 | ) else ( 36 | if ($conn//*/@*[contains(lower-case(name(.)), lower-case($FILTER))]) then ($resource) else () 37 | ) 38 | ) -------------------------------------------------------------------------------- /src/main/resources/api/search-attrvalues.xq: -------------------------------------------------------------------------------- 1 | (:~ Root path for search. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ Search filter. :) 4 | declare variable $FILTER as xs:string external; 5 | (:~ Whole word. :) 6 | declare variable $WHOLE as xs:string external; 7 | (:~ Exact Case. :) 8 | declare variable $EXACTCASE as xs:string external; 9 | 10 | let $whole := ($WHOLE eq 'true') 11 | let $exactcase := ($EXACTCASE eq 'true') 12 | 13 | (: name of database :) 14 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 15 | (: path: ensure existence trailing slash :) 16 | let $path := replace(substring-after($PATH, '/'), '([^/])$', '$1/') 17 | 18 | let $resources := if (empty($path)) then ( 19 | db:list($db) 20 | ) else ( 21 | db:list($db, $path) 22 | ) 23 | for $resource in $resources 24 | let $conn := db:open($db, $resource) 25 | 26 | return if ($whole) then ( 27 | if ($exactcase) then ( 28 | if ($conn//*[attribute() = $FILTER]) then ($resource) else () 29 | ) else ( 30 | if ($conn//@*[lower-case(.) = lower-case($FILTER)]) then ($resource) else () 31 | ) 32 | ) else ( 33 | if ($exactcase) then ( 34 | if ($conn//*/@*[contains(., $FILTER)]) then ($resource) else () 35 | ) else ( 36 | if ($conn//*/@*[contains(lower-case(.), lower-case($FILTER))]) then ($resource) else () 37 | ) 38 | ) -------------------------------------------------------------------------------- /src/main/resources/api/search-database.xq: -------------------------------------------------------------------------------- 1 | (:~ Root path for search. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ Search filter. :) 4 | declare variable $FILTER as xs:string external; 5 | 6 | (: name of database :) 7 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 8 | (: path: ensure existence trailing slash :) 9 | let $path := replace(substring-after($PATH, '/'), '([^/])$', '$1/') 10 | (: retrieve all entries on this and lower levels :) 11 | let $resources := db:list($db, $path) 12 | 13 | return ( 14 | $resources 15 | ) -------------------------------------------------------------------------------- /src/main/resources/api/search-elements.xq: -------------------------------------------------------------------------------- 1 | (:~ Root path for search. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ Search filter. :) 4 | declare variable $FILTER as xs:string external; 5 | (:~ Whole word. :) 6 | declare variable $WHOLE as xs:string external; 7 | (:~ Exact Case. :) 8 | declare variable $EXACTCASE as xs:string external; 9 | 10 | let $whole := ($WHOLE eq 'true') 11 | let $exactcase := ($EXACTCASE eq 'true') 12 | 13 | (: name of database :) 14 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 15 | (: path: ensure existence trailing slash :) 16 | let $path := replace(substring-after($PATH, '/'), '([^/])$', '$1/') 17 | 18 | let $resources := if (empty($path)) then ( 19 | db:list($db) 20 | ) else ( 21 | db:list($db, $path) 22 | ) 23 | 24 | for $resource in $resources 25 | let $conn := db:open($db, $resource) 26 | return if ($whole) then ( 27 | if ($exactcase) then ( 28 | if ($conn//*[name()=$FILTER]) then ($resource) else () 29 | ) else ( 30 | if ($conn//*[lower-case(name())=lower-case($FILTER)]) then ($resource) else () 31 | ) 32 | ) else ( 33 | if ($exactcase) then ( 34 | if ($conn//*[contains(./name(), $FILTER)]) then ($resource) else () 35 | ) else ( 36 | if ($conn//*[contains(lower-case(./name()), lower-case($FILTER))]) then ($resource) else () 37 | ) 38 | ) -------------------------------------------------------------------------------- /src/main/resources/api/search-repo.xq: -------------------------------------------------------------------------------- 1 | (:~ Root path for search. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ Search filter. :) 4 | declare variable $FILTER as xs:string external; 5 | 6 | let $path := db:system()//repopath || '/' || $PATH 7 | for $resource in file:list($path, true()) 8 | let $dir := file:is-dir($resource) 9 | (: show directories first, case-insensitive order :) 10 | order by $dir descending, lower-case($resource) 11 | 12 | return ( 13 | $resource 14 | ) 15 | -------------------------------------------------------------------------------- /src/main/resources/api/search-restxq.xq: -------------------------------------------------------------------------------- 1 | (:~ Root path for search. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ Search filter. :) 4 | declare variable $FILTER as xs:string external; 5 | 6 | let $system := db:system() 7 | let $webpath := $system//webpath/string() 8 | (: absolute, or relative to webpath :) 9 | let $restxqpath := $system//restxqpath/string() 10 | 11 | let $path := file:resolve-path($restxqpath, file:resolve-path($webpath)) || $PATH 12 | for $resource in file:list($path, true()) 13 | let $dir := file:is-dir($resource) 14 | (: show directories first, case-insensitive order :) 15 | order by $dir descending, lower-case($resource) 16 | return ( 17 | $resource 18 | ) -------------------------------------------------------------------------------- /src/main/resources/api/search-text.xq: -------------------------------------------------------------------------------- 1 | (:~ Root path for search. :) 2 | declare variable $PATH as xs:string external; 3 | (:~ Search filter. :) 4 | declare variable $FILTER as xs:string external; 5 | (:~ Whole word. :) 6 | declare variable $WHOLE as xs:string external; 7 | (:~ Exact Case. :) 8 | declare variable $EXACTCASE as xs:string external; 9 | 10 | let $whole := ($WHOLE eq 'true') 11 | let $exactcase := ($EXACTCASE eq 'true') 12 | 13 | (: name of database :) 14 | let $db := if(contains($PATH, '/')) then substring-before($PATH, '/') else $PATH 15 | (: path: ensure existence trailing slash :) 16 | let $path := replace(substring-after($PATH, '/'), '([^/])$', '$1/') 17 | 18 | let $resources := if (empty($path)) then ( 19 | db:list($db) 20 | ) else ( 21 | db:list($db, $path) 22 | ) 23 | 24 | for $resource in $resources 25 | let $conn := db:open($db, $resource) 26 | return if ($whole) then ( 27 | if ($exactcase) then ( 28 | if ($conn//*[text() = $FILTER]) then ($resource) else () 29 | ) else ( 30 | if ($conn//*[lower-case(.) = lower-case($FILTER)]) then ($resource) else () 31 | ) 32 | ) else ( 33 | if ($exactcase) then ( 34 | if ($conn//*[contains(., $FILTER)]) then ($resource) else () 35 | ) else ( 36 | if ($conn//*[contains(lower-case(.), lower-case($FILTER))]) then ($resource) else () 37 | ) 38 | ) 39 | -------------------------------------------------------------------------------- /src/main/resources/api/unlock.xq: -------------------------------------------------------------------------------- 1 | (:~ Source. :) 2 | declare variable $SOURCE as xs:string external; 3 | (:~ Path to resource. :) 4 | declare variable $PATH as xs:string external; 5 | 6 | (:~ Lock database. :) 7 | declare variable $LOCK-DB := '~argon'; 8 | declare variable $USER-FILE := '~usermanagement'; 9 | 10 | let $user := user:current() 11 | let $exists := db:exists($LOCK-DB, $USER-FILE) 12 | let $locks := ( 13 | if($exists) 14 | then db:open($LOCK-DB, $USER-FILE) 15 | else document { admin } 16 | ) update ( 17 | delete node *//locks/*[name() = $SOURCE][text() = $PATH][@user = $user] 18 | ) 19 | return if($exists) then ( 20 | db:replace($LOCK-DB, $USER-FILE, $locks) 21 | ) else ( 22 | db:create($LOCK-DB, $locks, $USER-FILE) 23 | ) -------------------------------------------------------------------------------- /src/main/resources/api/users.xq: -------------------------------------------------------------------------------- 1 | (:~ List users. :) 2 | declare variable $LOCK-DB := '~argon'; 3 | declare variable $USER-FILE := '~usermanagement'; 4 | 5 | distinct-values( 6 | if(not(db:exists($LOCK-DB, $USER-FILE))) then () else 7 | db:open($LOCK-DB, $USER-FILE)/*/@user/string() 8 | ) -------------------------------------------------------------------------------- /src/main/resources/images/AddDb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/AddDb.png -------------------------------------------------------------------------------- /src/main/resources/images/AddDb16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/AddDb16.png -------------------------------------------------------------------------------- /src/main/resources/images/AddDir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/AddDir.png -------------------------------------------------------------------------------- /src/main/resources/images/AddFile16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/AddFile16.gif -------------------------------------------------------------------------------- /src/main/resources/images/AddFile16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/AddFile16.png -------------------------------------------------------------------------------- /src/main/resources/images/BaseX24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/BaseX24.png -------------------------------------------------------------------------------- /src/main/resources/images/BaseX24add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/BaseX24add.png -------------------------------------------------------------------------------- /src/main/resources/images/BaseX_16_tr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/BaseX_16_tr.png -------------------------------------------------------------------------------- /src/main/resources/images/BaseXadd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/BaseXadd.png -------------------------------------------------------------------------------- /src/main/resources/images/BaseXlocked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/BaseXlocked.png -------------------------------------------------------------------------------- /src/main/resources/images/DBHttp16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/DBHttp16.png -------------------------------------------------------------------------------- /src/main/resources/images/DbCatalog16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/DbCatalog16.gif -------------------------------------------------------------------------------- /src/main/resources/images/DbCatalog16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/DbCatalog16.png -------------------------------------------------------------------------------- /src/main/resources/images/DbCatalogF16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/DbCatalogF16.png -------------------------------------------------------------------------------- /src/main/resources/images/DbCatalogP16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/DbCatalogP16.png -------------------------------------------------------------------------------- /src/main/resources/images/DbCatalogS16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/DbCatalogS16.png -------------------------------------------------------------------------------- /src/main/resources/images/DbCatalogShared16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/DbCatalogShared16.png -------------------------------------------------------------------------------- /src/main/resources/images/DbCatalogT16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/DbCatalogT16.png -------------------------------------------------------------------------------- /src/main/resources/images/DbCatalogTeam16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/DbCatalogTeam16.png -------------------------------------------------------------------------------- /src/main/resources/images/DbConnection16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/DbConnection16.gif -------------------------------------------------------------------------------- /src/main/resources/images/DbFolder16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/DbFolder16.png -------------------------------------------------------------------------------- /src/main/resources/images/Export16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/Export16.png -------------------------------------------------------------------------------- /src/main/resources/images/FolderClosed16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/FolderClosed16.png -------------------------------------------------------------------------------- /src/main/resources/images/IncVersion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/IncVersion.png -------------------------------------------------------------------------------- /src/main/resources/images/IncVersion16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/IncVersion16.png -------------------------------------------------------------------------------- /src/main/resources/images/InsertTemplate16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/InsertTemplate16.png -------------------------------------------------------------------------------- /src/main/resources/images/OpenURL16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/OpenURL16.gif -------------------------------------------------------------------------------- /src/main/resources/images/Oxygen16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/Oxygen16.png -------------------------------------------------------------------------------- /src/main/resources/images/Refresh16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/Refresh16.png -------------------------------------------------------------------------------- /src/main/resources/images/Remove16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/Remove16.png -------------------------------------------------------------------------------- /src/main/resources/images/Rename16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/Rename16.png -------------------------------------------------------------------------------- /src/main/resources/images/ReplyComment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/ReplyComment.png -------------------------------------------------------------------------------- /src/main/resources/images/RunQuery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/RunQuery.png -------------------------------------------------------------------------------- /src/main/resources/images/SearchInFiles16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/SearchInFiles16.png -------------------------------------------------------------------------------- /src/main/resources/images/SearchInPath16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/SearchInPath16.png -------------------------------------------------------------------------------- /src/main/resources/images/UpdateSingleDocument16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/UpdateSingleDocument16.png -------------------------------------------------------------------------------- /src/main/resources/images/VerHistory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/VerHistory.png -------------------------------------------------------------------------------- /src/main/resources/images/browseCMS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/browseCMS.png -------------------------------------------------------------------------------- /src/main/resources/images/file16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/file16.png -------------------------------------------------------------------------------- /src/main/resources/images/snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/snippet.png -------------------------------------------------------------------------------- /src/main/resources/images/txt16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/txt16.png -------------------------------------------------------------------------------- /src/main/resources/images/unlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/unlock.png -------------------------------------------------------------------------------- /src/main/resources/images/xml16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axxepta/project-argon/233d59c4562206bb08d0a1d3ce0c3c5a67d42343/src/main/resources/images/xml16.png -------------------------------------------------------------------------------- /src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | HelloWorldServlet 8 | HelloWorldServlet 9 | de.axxepta.oxygen.web.HelloWorldServlet 10 | 11 | 12 | 13 | HelloWorldServlet 14 | / 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/test/java/de/axxepta/oxygen/api/ArgonRestConnectionTest.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.api; 2 | 3 | import org.junit.BeforeClass; 4 | import org.junit.AfterClass; 5 | import org.junit.Test; 6 | 7 | import java.io.IOException; 8 | import java.net.URL; 9 | import java.net.URLConnection; 10 | import java.net.URLStreamHandler; 11 | import java.net.URLStreamHandlerFactory; 12 | 13 | import static org.junit.Assert.*; 14 | 15 | public class ArgonRestConnectionTest { 16 | 17 | static RestConnection conn; 18 | 19 | @BeforeClass 20 | public static void setUp() throws Exception { 21 | 22 | conn = new RestConnection("localhost", 8984, "admin", "admin"); 23 | } 24 | 25 | @Test 26 | public void createDatabase() throws Exception { 27 | 28 | conn.create("test-db","no", "no", "yes", "yes", "no"); 29 | 30 | } 31 | 32 | /* 33 | @Test 34 | public void deleteDatabase() throws Exception { 35 | 36 | conn.delete(BaseXSource.DATABASE, "test-db"); 37 | } 38 | */ 39 | 40 | @AfterClass 41 | public static void TearDown() throws Exception{ 42 | 43 | //conn.delete(BaseXSource.DATABASE, "test-db"); 44 | 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/de/axxepta/oxygen/customprotocol/ArgonChooserDialogTest.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.customprotocol; 2 | 3 | import de.axxepta.oxygen.api.ArgonEntity; 4 | import de.axxepta.oxygen.customprotocol.ArgonChooserListModel.Element; 5 | import org.junit.Test; 6 | 7 | import java.util.Arrays; 8 | 9 | import static de.axxepta.oxygen.api.ArgonEntity.DB; 10 | import static org.junit.Assert.assertEquals; 11 | 12 | public class ArgonChooserDialogTest { 13 | 14 | @Test 15 | public void getResourceString() throws Exception { 16 | assertEquals("", ArgonChooserDialog.getResourceString(Arrays.asList( 17 | new Element(DB, "foo")))); 18 | assertEquals("bar", ArgonChooserDialog.getResourceString(Arrays.asList( 19 | new Element(DB, "foo"), new Element(ArgonEntity.DIR, "bar")))); 20 | assertEquals("bar/baz", ArgonChooserDialog.getResourceString(Arrays.asList( 21 | new Element(DB, "foo"), 22 | new Element(ArgonEntity.DIR, "bar"), 23 | new Element(ArgonEntity.FILE, "baz")))); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/test/java/de/axxepta/oxygen/customprotocol/CustomProtocolURLUtilsTest.java: -------------------------------------------------------------------------------- 1 | package de.axxepta.oxygen.customprotocol; 2 | 3 | import de.axxepta.oxygen.api.BaseXSource; 4 | import org.junit.BeforeClass; 5 | import org.junit.Test; 6 | 7 | import java.io.IOException; 8 | import java.net.URL; 9 | import java.net.URLConnection; 10 | import java.net.URLStreamHandler; 11 | import java.net.URLStreamHandlerFactory; 12 | 13 | import static org.junit.Assert.*; 14 | 15 | public class CustomProtocolURLUtilsTest { 16 | 17 | static final String ARGON = "argon"; 18 | 19 | @BeforeClass 20 | public static void setUp() { 21 | URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() { 22 | @Override 23 | public URLStreamHandler createURLStreamHandler(String protocol) { 24 | if (ARGON.equals(protocol)) { 25 | return new URLStreamHandler() { 26 | @Override 27 | protected URLConnection openConnection(URL url) throws IOException { 28 | return new URLConnection(url) { 29 | @Override 30 | public void connect() throws IOException { 31 | throw new UnsupportedOperationException(); 32 | } 33 | }; 34 | } 35 | }; 36 | } 37 | return null; 38 | } 39 | }); 40 | } 41 | 42 | @Test 43 | public void pathFromURL() throws Exception { 44 | assertEquals("foo", CustomProtocolURLUtils.pathFromURL(new URL(ARGON + ":foo"))); 45 | assertEquals("foo/bar", CustomProtocolURLUtils.pathFromURL(new URL(ARGON + ":foo/bar"))); 46 | assertEquals("foo/bar", CustomProtocolURLUtils.pathFromURL(new URL(ARGON + ":/foo/bar"))); 47 | } 48 | 49 | @Test 50 | public void pathFromURLString() throws Exception { 51 | assertEquals("foo", CustomProtocolURLUtils.pathFromURLString(ARGON + ":foo")); 52 | assertEquals("foo/bar", CustomProtocolURLUtils.pathFromURLString(ARGON + ":foo/bar")); 53 | assertEquals("foo/bar", CustomProtocolURLUtils.pathFromURLString(ARGON + ":/foo/bar")); 54 | assertEquals("", CustomProtocolURLUtils.pathFromURLString("/foo/bar")); 55 | assertEquals("", CustomProtocolURLUtils.pathFromURLString("foo/bar")); 56 | } 57 | 58 | @Test 59 | public void sourceFromURL() throws Exception { 60 | assertEquals(BaseXSource.DATABASE, CustomProtocolURLUtils.sourceFromURL(new URL(ARGON + ":foo/bar"))); 61 | assertEquals(null, CustomProtocolURLUtils.sourceFromURL(new URL( "http://foo/bar"))); 62 | } 63 | 64 | @Test 65 | public void sourceFromURLString() throws Exception { 66 | assertEquals(BaseXSource.DATABASE, CustomProtocolURLUtils.sourceFromURLString(ARGON + ":foo/bar")); 67 | assertEquals(null, CustomProtocolURLUtils.sourceFromURLString( "http://foo/bar")); 68 | assertEquals(null, CustomProtocolURLUtils.sourceFromURLString("foo/bar")); 69 | } 70 | 71 | } --------------------------------------------------------------------------------