From 73c65ad73de2ca05e18ea1f95f2fc2c8f5b572ad Mon Sep 17 00:00:00 2001 From: rpesek Date: Wed, 7 Jun 2017 10:48:39 +0200 Subject: [PATCH 01/85] External repository support (Vaadin module) 1.0 The new external repository module and Vaadin UI. Upgrading the pax-web-jetty-bundle, pax-web-extender-war ... (shared-build-settings version 2.1.2-SNAPSHOT) --- build/compiled/pom.xml | 2 + build/pom.xml | 1357 +++++++++-------- core/crce-metadata-api/pom.xml | 1 + core/crce-metadata-dao-api/pom.xml | 2 +- core/crce-metadata-json-api/pom.xml | 2 +- core/crce-plugin-api/pom.xml | 2 +- modules/crce-external-repository/.classpath | 37 + modules/crce-external-repository/.project | 49 + modules/crce-external-repository/pom.xml | 52 + .../crce/external/web/impl/SettingsUrl.java | 54 + .../crce/external/web/inf/InfSettingsUrl.java | 13 + modules/crce-webui-vaadin/.classpath | 39 + modules/crce-webui-vaadin/.project | 50 + modules/crce-webui-vaadin/README.md | 52 + modules/crce-webui-vaadin/pom.xml | 298 ++++ .../crce_webui_vaadin/CentralMavenForm.java | 89 ++ .../crce_webui_vaadin/DefinedMavenForm.java | 143 ++ .../crce/crce_webui_vaadin/LoadFileForm.java | 71 + .../crce_webui_vaadin/LocalMavenForm.java | 36 + .../crce_webui_vaadin/LogoBackground.java | 14 + .../kiv/crce/crce_webui_vaadin/MenuForm.java | 42 + .../zcu/kiv/crce/crce_webui_vaadin/MyUI.java | 80 + .../crce/crce_webui_vaadin/SettingsForm.java | 92 ++ .../classes/CentralMaven.java | 85 ++ .../classes/DefinedMaven.java | 140 ++ .../crce_webui_vaadin/classes/LocalMaven.java | 59 + .../other/TypePackaging.java | 5 + .../src/main/resources/README | 1 + .../webapp/VAADIN/themes/mytheme/addons.scss | 7 + .../webapp/VAADIN/themes/mytheme/favicon.ico | Bin 0 -> 31005 bytes .../webapp/VAADIN/themes/mytheme/mytheme.scss | 38 + .../webapp/VAADIN/themes/mytheme/styles.scss | 10 + .../src/main/webapp/WEB-INF/web.xml | 24 + modules/pom.xml | 7 +- modules/provision/pom.xml | 348 +++-- pom.xml | 2 +- pom/pom.xml | 4 +- 37 files changed, 2457 insertions(+), 850 deletions(-) create mode 100644 modules/crce-external-repository/.classpath create mode 100644 modules/crce-external-repository/.project create mode 100644 modules/crce-external-repository/pom.xml create mode 100644 modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/impl/SettingsUrl.java create mode 100644 modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java create mode 100644 modules/crce-webui-vaadin/.classpath create mode 100644 modules/crce-webui-vaadin/.project create mode 100644 modules/crce-webui-vaadin/README.md create mode 100644 modules/crce-webui-vaadin/pom.xml create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/CentralMavenForm.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/DefinedMavenForm.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LoadFileForm.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LocalMavenForm.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LogoBackground.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MenuForm.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MyUI.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/SettingsForm.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/CentralMaven.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/DefinedMaven.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/LocalMaven.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/TypePackaging.java create mode 100644 modules/crce-webui-vaadin/src/main/resources/README create mode 100644 modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss create mode 100644 modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico create mode 100644 modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss create mode 100644 modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss create mode 100644 modules/crce-webui-vaadin/src/main/webapp/WEB-INF/web.xml diff --git a/build/compiled/pom.xml b/build/compiled/pom.xml index c0ceda26..0557ad67 100644 --- a/build/compiled/pom.xml +++ b/build/compiled/pom.xml @@ -127,4 +127,6 @@ + 2.1.1 + cz.zcu.kiv.crce diff --git a/build/pom.xml b/build/pom.xml index 1dea9cd0..720243a9 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -1,676 +1,685 @@ - - - 4.0.0 - - - cz.zcu.kiv.crce - crce-parent - 2.1.0 - - - - shared-build-settings - 2.1.2-SNAPSHOT - - CRCE - Build - Shared build configuration - - pom - - - cz.zcu.kiv.crce - 1.7 - 3.0.4 - 2.11.3 - 0.8.1-incubator - 4.3.1 - 3.0.3 - 3.2.0 - 2.6.1 - 1.9.13 - 1.7.7 - - - - https://github.com/ReliSA/crce/tree/master/build - https://github.com/ReliSA/crce.git - scm:git:git@github.com:ReliSA/crce.git - HEAD - - - - wrappers - compiled - - - - - - - org.ops4j - maven-pax-plugin - 1.5 - - - - org.ops4j.pax.exam - exam-maven-plugin - 4.3.0 - - - org.apache.maven.plugins - maven-surefire-plugin - 2.18 - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.18 - - - org.apache.servicemix.tooling - depends-maven-plugin - 1.2 - - - org.apache.felix - maven-bundle-plugin - 2.5.3 - true - - - org.apache.maven.plugins - maven-compiler-plugin - 3.2 - - ${version.jdk} - ${version.jdk} - ${project.build.sourceEncoding} - - - - org.apache.maven.plugins - maven-enforcer-plugin - 1.3.1 - - - enforce-versions - - enforce - - - - - ${version.jdk} - - - ${version.maven} - - - - - - - - maven-war-plugin - 2.5 - - - org.apache.maven.plugins - maven-pmd-plugin - 3.1 - - - org.codehaus.mojo - findbugs-maven-plugin - 3.0.0 - - - org.apache.felix - org.apache.felix.dependencymanager.annotation - ${version.org.apache.felix.dependencymanager} - - - - scan - - - info - - - - - - org.apache.maven.plugins - maven-dependency-plugin - 2.9 - - - org.apache.cxf - cxf-xjc-plugin - 3.0.2 - - - - - - - - - - - - - org.ops4j.pax.runner - pax-runner - 1.8.6 - provided - - - - - - org.osgi - org.osgi.core - ${version.org.osgi} - provided - true - - - - org.osgi - org.osgi.compendium - ${version.org.osgi} - provided - true - - - - - - org.ops4j.pax.web - pax-web-extender-war - ${version.org.ops4j.pax.web} - provided - - - org.ops4j.pax.web - pax-web-jetty-bundle - ${version.org.ops4j.pax.web} - provided - - - org.ops4j.pax.web - pax-web-jsp - ${version.org.ops4j.pax.web} - provided - - - org.ops4j.pax.web - pax-web-spi - ${version.org.ops4j.pax.web} - provided - - - - - - - org.slf4j - slf4j-api - ${version.org.slf4j} - provided - - - - - org.slf4j - osgi-over-slf4j - ${version.org.slf4j} - provided - - - org.slf4j - log4j-over-slf4j - ${version.org.slf4j} - provided - - - org.slf4j - jcl-over-slf4j - ${version.org.slf4j} - provided - - - org.slf4j - jul-to-slf4j - ${version.org.slf4j} - provided - - - - - ch.qos.logback - logback-core - 1.1.2 - provided - - - ch.qos.logback - logback-classic - 1.1.2 - provided - - - - - - org.apache.felix - org.apache.felix.framework - 4.0.3 - - - org.apache.felix - org.apache.felix.eventadmin - 1.4.2 - provided - - - org.apache.felix - org.apache.felix.dependencymanager - ${version.org.apache.felix.dependencymanager} - provided - - - org.apache.felix - org.apache.felix.dependencymanager.shell - ${version.org.apache.felix.dependencymanager} - - provided - - - org.apache.felix - org.apache.felix.dependencymanager.annotation - ${version.org.apache.felix.dependencymanager} - compile - - - biz.aQute - bndlib - - - - - org.apache.felix - org.apache.felix.dependencymanager.runtime - ${version.org.apache.felix.dependencymanager} - provided - - - org.apache.felix - org.apache.felix.configadmin - 1.8.0 - provided - - - org.apache.felix - org.apache.felix.bundlerepository - 2.0.2 - provided - - - org.apache.felix - org.osgi.service.obr - 1.0.2 - provided - - - org.apache.felix - org.apache.felix.scr - 1.8.2 - provided - - - org.apache.felix - org.apache.felix.webconsole - 4.2.2 - provided - - - org.apache.felix - org.apache.felix.shell - 1.4.3 - provided - - - org.apache.felix - org.apache.felix.fileinstall - 3.4.2 - provided - - - - - - - log4j - log4j - 1.2.17 - true - - - org.slf4j - slf4j-log4j12 - 1.7.7 - true - - - - - - javax.servlet - servlet-api - 2.5 - provided - - - javax.servlet - jsp-api - 2.0 - provided - - - - - org.apache.ace - org.apache.ace.httplistener - ${version.org.apache.ace} - provided - - - org.apache.ace - org.apache.ace.obr.metadata - ${version.org.apache.ace} - provided - - - org.apache.ace - org.apache.ace.obr.storage - ${version.org.apache.ace} - provided - - - org.apache.ace - org.apache.ace.obr.servlet - ${version.org.apache.ace} - provided - - - - - - org.mybatis - mybatis - 3.2.2 - provided - - - com.h2database - h2 - 1.3.176 - provided - - - com.googlecode.flyway - flyway-core - 2.3.1 - compile - - - - org.mongodb - mongo-java-driver - ${version.mongodb} - provided - - - - - - org.codehaus.plexus - plexus-utils - 3.0.15 - provided - - - org.apache.commons - commons-io - 1.3.2 - jar - provided - - - - commons-beanutils - commons-beanutils - 1.9.1 - provided - - - org.apache.commons - commons-lang3 - 3.3.2 - provided - - - - org.apache.felix - org.apache.felix.utils - 1.6.0 - jar - compile - - - - asm - asm-all - 3.3.1 - provided - - - org.ow2.asm - asm-all - 4.1 - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.commons-vfs - 1.0_6 - provided - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.bcel - 5.2_4 - provided - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.jaxp-ri - 1.4.5_1 - provided - - - com.google.code.gson - gson - 2.2.4 - provided - - - org.codehaus.groovy - groovy-all - 2.2.1 - provided - - - commons-fileupload - commons-fileupload - 1.3.1 - provided - - - commons-io - commons-io - 2.4 - provided - - - commons-net - commons-net - 3.3 - provided - - - de.twentyeleven.skysail - org.json-osgi - 20080701 - provided - - - org.apache.xbean - xbean-finder - 3.13 - - provided - - - org.apache.xbean - xbean-bundleutils - 3.13 - - - - com.google.code.findbugs - jsr305 - 3.0.0 - true - - - com.google.code.findbugs - annotations - 3.0.0 - true - - - com.fasterxml.jackson.core - jackson-core - ${version.com.fasterxml.jackson} - compile - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-base - ${version.com.fasterxml.jackson} - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-xml-provider - ${version.com.fasterxml.jackson} - - - com.fasterxml.jackson.core - jackson-databind - ${version.com.fasterxml.jackson} - compile - - - com.fasterxml.jackson.core - jackson-annotations - ${version.com.fasterxml.jackson} - compile - - - com.fasterxml.jackson.module - jackson-module-jaxb-annotations - ${version.com.fasterxml.jackson} - compile - - - org.codehaus.jackson - jackson-core-asl - ${version.org.codehaus.jackson} - - - org.codehaus.jackson - jackson-jaxrs - ${version.org.codehaus.jackson} - - - org.codehaus.jackson - jackson-mapper-asl - ${version.org.codehaus.jackson} - - - org.codehaus.jackson - jackson-xc - ${version.org.codehaus.jackson} - - - org.codehaus.jettison - jettison - 1.3.6 - - - - - - junit - junit - 4.11 - test - - - org.skyscreamer - jsonassert - 1.2.3 - test - - - org.mockito - mockito-core - 1.9.5 - test - - - - - - - - - relisa-global - ReliSA Global Proxy repository - http://relisa-dev.kiv.zcu.cz:8081/nexus/content/groups/public - - - maven.kalwi.eu.releases - kalwi.eu releases repository - http://maven.kalwi.eu/repo/releases - - - + + + 4.0.0 + + + cz.zcu.kiv.crce + crce-parent + + 2.1.1-SNAPSHOT + + + + shared-build-settings + 2.1.2-SNAPSHOT + + CRCE - Build - Shared build configuration + + pom + + + cz.zcu.kiv.crce + 1.7 + 3.0.4 + 2.11.3 + 0.8.1-incubator + 4.3.1 + + 6.0.4 + 3.2.0 + 2.6.1 + 1.9.13 + 1.7.7 + + + + + + wrappers + compiled + + + + + + + org.ops4j + maven-pax-plugin + 1.5 + + + + org.ops4j.pax.exam + exam-maven-plugin + 4.3.0 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.18 + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.18 + + + org.apache.servicemix.tooling + depends-maven-plugin + 1.2 + + + org.apache.felix + maven-bundle-plugin + 2.5.3 + true + + + org.apache.maven.plugins + maven-compiler-plugin + 3.2 + + ${version.jdk} + ${version.jdk} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-enforcer-plugin + 1.3.1 + + + enforce-versions + + enforce + + + + + ${version.jdk} + + + ${version.maven} + + + + + + + + maven-war-plugin + 2.5 + + + org.apache.maven.plugins + maven-pmd-plugin + 3.1 + + + org.codehaus.mojo + findbugs-maven-plugin + 3.0.0 + + + org.apache.felix + org.apache.felix.dependencymanager.annotation + ${version.org.apache.felix.dependencymanager} + + + + scan + + + info + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.9 + + + org.apache.cxf + cxf-xjc-plugin + 3.0.2 + + + + + + + + + + + + + org.ops4j.pax.runner + pax-runner + 1.8.6 + provided + + + + + + org.osgi + org.osgi.core + ${version.org.osgi} + provided + true + + + + org.osgi + org.osgi.compendium + ${version.org.osgi} + provided + true + + + + + + org.ops4j.pax.web + pax-web-jsp + ${version.org.ops4j.pax.web} + provided + + + org.ops4j.pax.web + pax-web-jetty-bundle + ${version.org.ops4j.pax.web} + provided + + + org.ops4j.pax.web + pax-web-spi + ${version.org.ops4j.pax.web} + provided + + + org.ops4j.pax.web + pax-web-api + ${version.org.ops4j.pax.web} + provided + + + org.ops4j.pax.web + pax-web-extender-war + ${version.org.ops4j.pax.web} + provided + + + org.ops4j.pax.web + pax-web-descriptor + ${version.org.ops4j.pax.web} + provided + + + + + + + org.slf4j + slf4j-api + ${version.org.slf4j} + provided + + + + + org.slf4j + osgi-over-slf4j + ${version.org.slf4j} + provided + + + org.slf4j + log4j-over-slf4j + ${version.org.slf4j} + provided + + + org.slf4j + jcl-over-slf4j + ${version.org.slf4j} + provided + + + org.slf4j + jul-to-slf4j + ${version.org.slf4j} + provided + + + + + ch.qos.logback + logback-core + 1.1.2 + provided + + + ch.qos.logback + logback-classic + 1.1.2 + provided + + + + + + org.apache.felix + org.apache.felix.framework + 4.0.3 + + + org.apache.felix + org.apache.felix.eventadmin + 1.4.2 + provided + + + org.apache.felix + org.apache.felix.dependencymanager + ${version.org.apache.felix.dependencymanager} + provided + + + org.apache.felix + org.apache.felix.dependencymanager.shell + ${version.org.apache.felix.dependencymanager} + + provided + + + org.apache.felix + org.apache.felix.dependencymanager.annotation + ${version.org.apache.felix.dependencymanager} + compile + + + biz.aQute + bndlib + + + + + org.apache.felix + org.apache.felix.dependencymanager.runtime + ${version.org.apache.felix.dependencymanager} + provided + + + org.apache.felix + org.apache.felix.configadmin + 1.8.0 + provided + + + org.apache.felix + org.apache.felix.bundlerepository + 2.0.2 + provided + + + org.apache.felix + org.osgi.service.obr + 1.0.2 + provided + + + org.apache.felix + org.apache.felix.scr + 1.8.2 + provided + + + org.apache.felix + org.apache.felix.webconsole + 4.2.2 + provided + + + org.apache.felix + org.apache.felix.shell + 1.4.3 + provided + + + org.apache.felix + org.apache.felix.fileinstall + 3.4.2 + provided + + + + + + + log4j + log4j + 1.2.17 + true + + + org.slf4j + slf4j-log4j12 + 1.7.7 + true + + + + + + javax.servlet + servlet-api + 2.5 + provided + + + javax.servlet + jsp-api + 2.0 + provided + + + + + org.apache.ace + org.apache.ace.httplistener + ${version.org.apache.ace} + provided + + + org.apache.ace + org.apache.ace.obr.metadata + ${version.org.apache.ace} + provided + + + org.apache.ace + org.apache.ace.obr.storage + ${version.org.apache.ace} + provided + + + org.apache.ace + org.apache.ace.obr.servlet + ${version.org.apache.ace} + provided + + + + + + org.mybatis + mybatis + 3.2.2 + provided + + + com.h2database + h2 + 1.3.176 + provided + + + com.googlecode.flyway + flyway-core + 2.3.1 + compile + + + + org.mongodb + mongo-java-driver + ${version.mongodb} + provided + + + + + + org.codehaus.plexus + plexus-utils + 3.0.15 + provided + + + org.apache.commons + commons-io + 1.3.2 + jar + provided + + + + commons-beanutils + commons-beanutils + 1.9.1 + provided + + + org.apache.commons + commons-lang3 + 3.3.2 + provided + + + + org.apache.felix + org.apache.felix.utils + 1.6.0 + jar + compile + + + + asm + asm-all + 3.3.1 + provided + + + org.ow2.asm + asm-all + 4.1 + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.commons-vfs + 1.0_6 + provided + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.bcel + 5.2_4 + provided + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.jaxp-ri + 1.4.5_1 + provided + + + com.google.code.gson + gson + 2.2.4 + provided + + + org.codehaus.groovy + groovy-all + 2.2.1 + provided + + + commons-fileupload + commons-fileupload + 1.3.1 + provided + + + commons-io + commons-io + 2.4 + provided + + + commons-net + commons-net + 3.3 + provided + + + de.twentyeleven.skysail + org.json-osgi + 20080701 + provided + + + org.apache.xbean + xbean-finder + 4.5 + + + provided + + + org.apache.xbean + xbean-bundleutils + 4.5 + + provided + + + + com.google.code.findbugs + jsr305 + 3.0.0 + true + + + com.google.code.findbugs + annotations + 3.0.0 + true + + + com.fasterxml.jackson.core + jackson-core + ${version.com.fasterxml.jackson} + compile + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base + ${version.com.fasterxml.jackson} + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-xml-provider + ${version.com.fasterxml.jackson} + + + com.fasterxml.jackson.core + jackson-databind + ${version.com.fasterxml.jackson} + compile + + + com.fasterxml.jackson.core + jackson-annotations + ${version.com.fasterxml.jackson} + compile + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + ${version.com.fasterxml.jackson} + compile + + + org.codehaus.jackson + jackson-core-asl + ${version.org.codehaus.jackson} + + + org.codehaus.jackson + jackson-jaxrs + ${version.org.codehaus.jackson} + + + org.codehaus.jackson + jackson-mapper-asl + ${version.org.codehaus.jackson} + + + org.codehaus.jackson + jackson-xc + ${version.org.codehaus.jackson} + + + org.codehaus.jettison + jettison + 1.3.6 + + + + + + junit + junit + 4.11 + test + + + org.skyscreamer + jsonassert + 1.2.3 + test + + + org.mockito + mockito-core + 1.9.5 + test + + + + + + + + relisa-global + ReliSA Global Proxy repository + http://relisa-dev.kiv.zcu.cz:8081/nexus/content/groups/public + + + maven.kalwi.eu.releases + kalwi.eu releases repository + http://maven.kalwi.eu/repo/releases + + + cz.zcu.kiv.crce diff --git a/core/crce-metadata-api/pom.xml b/core/crce-metadata-api/pom.xml index 303c5ec3..c383f269 100644 --- a/core/crce-metadata-api/pom.xml +++ b/core/crce-metadata-api/pom.xml @@ -64,4 +64,5 @@ + cz.zcu.kiv.crce diff --git a/core/crce-metadata-dao-api/pom.xml b/core/crce-metadata-dao-api/pom.xml index 483bcd54..d1f8e2eb 100644 --- a/core/crce-metadata-dao-api/pom.xml +++ b/core/crce-metadata-dao-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/core/crce-metadata-json-api/pom.xml b/core/crce-metadata-json-api/pom.xml index 60b02a3c..584fc5b2 100644 --- a/core/crce-metadata-json-api/pom.xml +++ b/core/crce-metadata-json-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/core/crce-plugin-api/pom.xml b/core/crce-plugin-api/pom.xml index 7a20350d..1491a2d2 100644 --- a/core/crce-plugin-api/pom.xml +++ b/core/crce-plugin-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1-SNAPSHOT + 2.1.1 diff --git a/modules/crce-external-repository/.classpath b/modules/crce-external-repository/.classpath new file mode 100644 index 00000000..71a86ecf --- /dev/null +++ b/modules/crce-external-repository/.classpath @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-external-repository/.project b/modules/crce-external-repository/.project new file mode 100644 index 00000000..0d92023e --- /dev/null +++ b/modules/crce-external-repository/.project @@ -0,0 +1,49 @@ + + + crce-external-repository + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + + diff --git a/modules/crce-external-repository/pom.xml b/modules/crce-external-repository/pom.xml new file mode 100644 index 00000000..9bbbaa16 --- /dev/null +++ b/modules/crce-external-repository/pom.xml @@ -0,0 +1,52 @@ + + 4.0.0 + cz.zcu.kiv.crce + crce-external-repository + 1.0 + + 1.8 + 1.8 + + + + + maven-jar-plugin + 3.0.2 + + + ${project.build.directory}/META-INF/MANIFEST.MF + + + + + org.apache.felix + maven-bundle-plugin + 3.2.0 + true + + + bundle-manifest + process-classes + + manifest + + + + + ${project.build.directory}/META-INF + + jar + bundle + + + * + cz.zcu.kiv.crce.external.web.impl + ${project.artifactId} + + + + + + CRCE - External Repository Support + \ No newline at end of file diff --git a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/impl/SettingsUrl.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/impl/SettingsUrl.java new file mode 100644 index 00000000..e0f9429f --- /dev/null +++ b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/impl/SettingsUrl.java @@ -0,0 +1,54 @@ +package cz.zcu.kiv.crce.external.web.impl; + +import java.io.File; + +import cz.zcu.kiv.crce.external.web.inf.InfSettingsUrl; + +public class SettingsUrl implements InfSettingsUrl { + + private String localMavenUrl = System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository"; + private String centralMavenUrl = "http://repo.maven.apache.org/maven2/"; + private String localAetherUrl = "target/local-repo"; + private String externalAetherUrl = "http://repo.maven.apache.org/maven2/"; + + @Override + public String getLocalMavenUrl() { + return localMavenUrl; + } + + @Override + public String getCentralMavenUrl() { + return centralMavenUrl; + } + + @Override + public String getLocalAetherUrl() { + return localAetherUrl; + } + + @Override + public String getExternalAetherUrl() { + return externalAetherUrl; + } + + @Override + public void setLocalMavenUrl(String url) { + this.localMavenUrl = url; + } + + @Override + public void setCentralMavenUrl(String url) { + this.centralMavenUrl = url; + } + + @Override + public void setLocalAetherUrl(String url) { + this.localAetherUrl = url; + } + + @Override + public void setExternalAetherUrl(String url) { + this.externalAetherUrl = url; + } + +} diff --git a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java new file mode 100644 index 00000000..13d237b6 --- /dev/null +++ b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java @@ -0,0 +1,13 @@ +package cz.zcu.kiv.crce.external.web.inf; + +public interface InfSettingsUrl { + public String getLocalMavenUrl(); + public String getCentralMavenUrl(); + public String getLocalAetherUrl(); + public String getExternalAetherUrl(); + + public void setLocalMavenUrl(String url); + public void setCentralMavenUrl(String url); + public void setLocalAetherUrl(String url); + public void setExternalAetherUrl(String url); +} diff --git a/modules/crce-webui-vaadin/.classpath b/modules/crce-webui-vaadin/.classpath new file mode 100644 index 00000000..abbb4e7d --- /dev/null +++ b/modules/crce-webui-vaadin/.classpath @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-webui-vaadin/.project b/modules/crce-webui-vaadin/.project new file mode 100644 index 00000000..05d97306 --- /dev/null +++ b/modules/crce-webui-vaadin/.project @@ -0,0 +1,50 @@ + + + crce-webui-vaadin + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.jsdt.core.jsNature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + + diff --git a/modules/crce-webui-vaadin/README.md b/modules/crce-webui-vaadin/README.md new file mode 100644 index 00000000..6b54f414 --- /dev/null +++ b/modules/crce-webui-vaadin/README.md @@ -0,0 +1,52 @@ +crce-webui-vaadin +============== + +Template for a simple Vaadin application that only requires a Servlet 3.0 container to run. + + +Workflow +======== + +To compile the entire project, run "mvn install". + +To run the application, run "mvn jetty:run" and open http://localhost:8080/ . + +To produce a deployable production mode WAR: +- change productionMode to true in the servlet class configuration (nested in the UI class) +- run "mvn clean package" +- test the war file with "mvn jetty:run-war" + +Client-Side compilation +------------------------- + +The generated maven project is using an automatically generated widgetset by default. +When you add a dependency that needs client-side compilation, the maven plugin will +automatically generate it for you. Your own client-side customisations can be added into +package "client". + +Debugging client side code + - run "mvn vaadin:run-codeserver" on a separate console while the application is running + - activate Super Dev Mode in the debug window of the application + +Developing a theme using the runtime compiler +------------------------- + +When developing the theme, Vaadin can be configured to compile the SASS based +theme at runtime in the server. This way you can just modify the scss files in +your IDE and reload the browser to see changes. + +To use the runtime compilation, open pom.xml and comment out the compile-theme +goal from vaadin-maven-plugin configuration. To remove a possibly existing +pre-compiled theme, run "mvn clean package" once. + +When using the runtime compiler, running the application in the "run" mode +(rather than in "debug" mode) can speed up consecutive theme compilations +significantly. + +It is highly recommended to disable runtime compilation for production WAR files. + +Using Vaadin pre-releases +------------------------- + +If Vaadin pre-releases are not enabled by default, use the Maven parameter +"-P vaadin-prerelease" or change the activation default value of the profile in pom.xml . diff --git a/modules/crce-webui-vaadin/pom.xml b/modules/crce-webui-vaadin/pom.xml new file mode 100644 index 00000000..05896252 --- /dev/null +++ b/modules/crce-webui-vaadin/pom.xml @@ -0,0 +1,298 @@ + + + 4.0.0 + + cz.zcu.kiv.crce + crce-webui-vaadin + war + 1.0 + CRCE - Web UI (Vaadin) + + + + + 7.7.7 + 7.7.7 + 9.3.9.v20160517 + UTF-8 + 1.8 + 1.8 + + local + + + + + vaadin-addons + http://maven.vaadin.com/vaadin-addons + + + + + + + com.vaadin + vaadin-bom + ${vaadin.version} + pom + import + + + org.eclipse.aether + aether-impl + 1.1.0 + + + org.eclipse.aether + aether-connector-basic + 1.1.0 + + + org.eclipse.aether + aether-transport-file + 1.1.0 + + + org.eclipse.aether + aether-transport-http + 1.1.0 + + + org.apache.maven + maven-aether-provider + 3.3.9 + + + org.slf4j + slf4j-simple + 1.7.22 + + + + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + com.vaadin + vaadin-server + + + com.vaadin + vaadin-push + + + com.vaadin + vaadin-client-compiled + + + com.vaadin + vaadin-themes + + + org.eclipse.aether + aether-impl + + + org.eclipse.aether + aether-connector-basic + + + org.eclipse.aether + aether-transport-file + + + org.eclipse.aether + aether-transport-http + + + org.apache.maven + maven-aether-provider + + + org.slf4j + slf4j-simple + + + cz.zcu.kiv.crce + crce-external-repository + 1.0 + + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.6 + + false + + WEB-INF/classes/VAADIN/widgetsets/WEB-INF/** + + ${project.build.directory}/META-INF/MANIFEST.MF + + WEB-INF/classes + + + + + + com.vaadin + vaadin-maven-plugin + ${vaadin.plugin.version} + + + + update-theme + update-widgetset + compile + + compile-theme + + + + + + org.apache.maven.plugins + maven-clean-plugin + 3.0.0 + + + + + src/main/webapp/VAADIN/themes + + **/styles.css + **/styles.scss.cache + + + + + + + org.apache.felix + maven-bundle-plugin + 3.2.0 + true + + + bundle-manifest + process-classes + + manifest + + + + + ${project.build.directory}/META-INF + + bundle + war + + + + * + + + cz.zcu.kiv.crce.external.web.impl + + ${project.artifactId} + + WEB-INF/classes, + WEB-INF/lib/aether-api-1.1.0.jar, + WEB-INF/lib/aether-connector-basic-1.1.0.jar, + WEB-INF/lib/aether-impl-1.1.0.jar, + WEB-INF/lib/aether-spi-1.1.0.jar, + WEB-INF/lib/aether-transport-file-1.1.0.jar, + WEB-INF/lib/aether-transport-http-1.1.0.jar, + WEB-INF/lib/aether-util-1.1.0.jar, + WEB-INF/lib/atmosphere-runtime-2.2.9.vaadin2.jar, + WEB-INF/lib/commons-codec-1.6.jar, + WEB-INF/lib/commons-lang3-3.4.jar, + WEB-INF/lib/crce-external-repository-1.0.jar, + WEB-INF/lib/flute-1.3.0.gg2.jar, + WEB-INF/lib/guava-18.0.jar, + WEB-INF/lib/httpclient-4.3.5.jar, + WEB-INF/lib/httpcore-4.3.2.jar, + WEB-INF/lib/jcl-over-slf4j-1.6.2.jar, + WEB-INF/lib/jsoup-1.8.3.jar, + WEB-INF/lib/maven-aether-provider-3.3.9.jar, + WEB-INF/lib/maven-artifact-3.3.9.jar, + WEB-INF/lib/maven-builder-support-3.3.9.jar, + WEB-INF/lib/maven-model-3.3.9.jar, + WEB-INF/lib/maven-model-builder-3.3.9.jar, + WEB-INF/lib/maven-repository-metadata-3.3.9.jar, + WEB-INF/lib/plexus-component-annotations-1.6.jar, + WEB-INF/lib/plexus-interpolation-1.21.jar, + WEB-INF/lib/plexus-utils-3.0.22.jar, + WEB-INF/lib/sac-1.3.jar, + WEB-INF/lib/slf4j-api-1.7.22.jar, + WEB-INF/lib/slf4j-simple-1.7.22.jar, + WEB-INF/lib/vaadin-client-compiled-7.7.7.jar, + WEB-INF/lib/vaadin-push-7.7.7.jar, + WEB-INF/lib/vaadin-sass-compiler-0.9.13.jar, + WEB-INF/lib/vaadin-server-7.7.7.jar, + WEB-INF/lib/vaadin-shared-7.7.7.jar, + WEB-INF/lib/vaadin-slf4j-jdk14-1.6.1.jar, + WEB-INF/lib/vaadin-themes-7.7.7.jar + + crce-vaadin + crce-vaadin + <_wab>src/main/webapp + + + + + + + + + + vaadin-prerelease + + false + + + + vaadin-prereleases + http://maven.vaadin.com/vaadin-prereleases + + + vaadin-snapshots + https://oss.sonatype.org/content/repositories/vaadin-snapshots/ + + false + + + true + + + + + + vaadin-prereleases + http://maven.vaadin.com/vaadin-prereleases + + + vaadin-snapshots + https://oss.sonatype.org/content/repositories/vaadin-snapshots/ + + false + + + true + + + + + + diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/CentralMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/CentralMavenForm.java new file mode 100644 index 00000000..10338753 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/CentralMavenForm.java @@ -0,0 +1,89 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin; + +import java.util.EnumSet; +import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.server.VaadinSession; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.Button; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.NativeSelect; +import com.vaadin.ui.TextField; +import com.vaadin.ui.Tree; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; +import cz.zcu.kiv.crce.crce_webui_vaadin.classes.CentralMaven; +import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; + +@SuppressWarnings("serial") +public class CentralMavenForm extends FormLayout { + private Label caption = new Label("Central Maven repository"); + private TextField group = new TextField("Group Id"); + private TextField artifact = new TextField("Artifact Id"); + private TextField version = new TextField("Version"); + private NativeSelect packaging = new NativeSelect("Packaging"); + private Button searchButton = new Button("Search"); + private Button clearButton = new Button("Clear"); + private Label notFound = new Label("No artifact found"); + private Tree tree; + + public CentralMavenForm() { + HorizontalLayout content = new HorizontalLayout(); + addComponent(content); + } + + public CentralMavenForm(VaadinSession session){ + VerticalLayout userForm = new VerticalLayout(); + HorizontalLayout content = new HorizontalLayout(); + packaging.addItems(EnumSet.allOf(TypePackaging.class)); + packaging.select(TypePackaging.jar); + packaging.setNullSelectionAllowed(false); + + searchButton.setStyleName(ValoTheme.BUTTON_PRIMARY); + searchButton.setClickShortcut(KeyCode.ENTER); + + HorizontalLayout buttons = new HorizontalLayout(searchButton, clearButton); + buttons.setSpacing(true); + userForm.addComponents(caption, group, artifact, version, packaging, buttons); + userForm.setSpacing(true); + userForm.setMargin(new MarginInfo(false, true)); + content.addComponent(userForm); + + // Add tree + searchButton.addClickListener(e ->{ + // erasing any previous components shown + if(content.getComponentIndex(notFound) != -1){ + content.removeComponent(notFound); + } + if(content.getComponentIndex(tree) != -1){ + content.removeComponent(tree); + } + // check exist component from central Maven repository + tree = new CentralMaven(session).getTree(group.getValue(),artifact.getValue(), + version.getValue(),packaging.getValue()); + if(tree == null){ + content.addComponent(notFound); + } + else{ + content.addComponent(tree); + } + }); + + + // Clear user form + clearButton.addClickListener(e ->{ + content.removeAllComponents(); + group.clear(); + artifact.clear(); + version.clear(); + packaging.select(TypePackaging.jar); + content.addComponent(userForm); + }); + + content.setSpacing(true); + addComponent(content); + } + + +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/DefinedMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/DefinedMavenForm.java new file mode 100644 index 00000000..e314627f --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/DefinedMavenForm.java @@ -0,0 +1,143 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin; + +import java.util.EnumSet; +import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.server.VaadinSession; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.Button; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.NativeSelect; +import com.vaadin.ui.TextField; +import com.vaadin.ui.Tree; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; +import cz.zcu.kiv.crce.crce_webui_vaadin.classes.DefinedMaven; +import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; +import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; + +@SuppressWarnings("serial") +public class DefinedMavenForm extends FormLayout { + private DefinedMaven definedMaven; + private TextField definedUrl = new TextField(); + private Label caption = new Label("Defined Maven repository"); + private TextField group = new TextField("Group Id"); + private TextField artifact = new TextField("Artifact Id"); + private TextField version = new TextField("Version"); + private NativeSelect packaging = new NativeSelect("Packaging"); + private Button searchButton = new Button("Search"); + private Button clearButton = new Button("Clear"); + private Label notFound = new Label("No artifact found"); + private Tree tree; + + public DefinedMavenForm() { + HorizontalLayout content = new HorizontalLayout(); + addComponent(content); + } + + public DefinedMavenForm(VaadinSession session) { + // settings url + if (session.getAttribute("settingsUrl") == null) { + SettingsUrl settings = new SettingsUrl(); + definedUrl.setValue(settings.getExternalAetherUrl()); + } else { + definedUrl.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getExternalAetherUrl()); + } + + VerticalLayout fieldLayout = new VerticalLayout(); + HorizontalLayout treeLayout = new HorizontalLayout(); + VerticalLayout formLayout = new VerticalLayout(); + HorizontalLayout content = new HorizontalLayout(); + + definedUrl.setWidth("450px"); + + packaging.addItems(EnumSet.allOf(TypePackaging.class)); + packaging.select(TypePackaging.jar); + packaging.setNullSelectionAllowed(false); + + searchButton.setStyleName(ValoTheme.BUTTON_PRIMARY); + searchButton.setClickShortcut(KeyCode.ENTER); + + HorizontalLayout buttons = new HorizontalLayout(searchButton, clearButton); + buttons.setSpacing(true); + + Button setUrl = new Button("Set"); + CssLayout definedCss = new CssLayout(); + definedCss.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); + definedCss.addComponents(definedUrl, setUrl); + + fieldLayout.addComponents(group, artifact, version, packaging, buttons); + fieldLayout.setSpacing(true); + fieldLayout.setMargin(new MarginInfo(false, true, false, false)); + + treeLayout.addComponent(fieldLayout); + treeLayout.setSpacing(true); + + formLayout.addComponents(caption, definedCss, treeLayout); + formLayout.setSpacing(true); + formLayout.setMargin(new MarginInfo(false, true)); + + content.addComponents(formLayout); + + // Setting url defined repository + setUrl.addClickListener(e -> { + SettingsUrl settings; + if (session.getAttribute("settingsUrl") == null) { + settings = new SettingsUrl(); + settings.setExternalAetherUrl(definedUrl.getValue()); + getSession().setAttribute("settingsUrl", settings); + } else { + settings = (SettingsUrl) session.getAttribute("settingsUrl"); + settings.setExternalAetherUrl(definedUrl.getValue()); + getSession().setAttribute("settingsUrl", settings); + } + }); + + // clear form + clearButton.addClickListener(e -> { + group.clear(); + artifact.clear(); + version.clear(); + packaging.select(TypePackaging.jar); + // erasing any previous components shown + if (treeLayout.getComponentIndex(notFound) != -1) { + treeLayout.removeComponent(notFound); + } + if (treeLayout.getComponentIndex(tree) != -1) { + treeLayout.removeComponent(tree); + } + }); + + // search artefact from defined repository + searchButton.addClickListener(e -> { + SettingsUrl settings; + if (session.getAttribute("settingsUrl") == null) { + settings = new SettingsUrl(); + } else { + settings = (SettingsUrl) session.getAttribute("settingsUrl"); + } + // erasing any previous components shown + if (treeLayout.getComponentIndex(notFound) != -1) { + treeLayout.removeComponent(notFound); + } + if (treeLayout.getComponentIndex(tree) != -1) { + treeLayout.removeComponent(tree); + } + + // předání hodnot - doplnit + definedMaven = new DefinedMaven(settings); + tree = definedMaven.getTree(group.getValue(), artifact.getValue(), version.getValue(), + packaging.getValue()); + if (tree == null) { + treeLayout.addComponent(notFound); + } else { + treeLayout.addComponent(tree); + } + }); + + content.setSpacing(true); + addComponent(content); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LoadFileForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LoadFileForm.java new file mode 100644 index 00000000..02acdc76 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LoadFileForm.java @@ -0,0 +1,71 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import com.vaadin.server.Page; +import com.vaadin.shared.Position; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Notification; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.Upload; +import com.vaadin.ui.Upload.Receiver; +import com.vaadin.ui.Upload.SucceededEvent; +import com.vaadin.ui.Upload.SucceededListener; +import com.vaadin.ui.VerticalLayout; + +@SuppressWarnings("serial") +public class LoadFileForm extends FormLayout { + final TextArea area = new TextArea(); + public LoadFileForm() { + FileUploader receiver = new FileUploader(); + VerticalLayout content = new VerticalLayout(); + Upload upload = new Upload("Directly Upload File:", receiver); + upload.setButtonCaption("Browse Files"); + upload.addSucceededListener(receiver); + upload.setImmediate(true); + area.setVisible(false); + area.setSizeFull(); + content.addComponents(upload, area); + content.setMargin(new MarginInfo(false, true, false, false)); + content.setSpacing(true); + addComponent(content); + } + + class FileUploader implements Receiver, SucceededListener { + public File file; + + public OutputStream receiveUpload(String filename, String mimeType) { + FileOutputStream fos = null; + try { + file = new File(filename); + fos = new FileOutputStream(file); + } catch (FileNotFoundException e) { + new Notification("Could not open file", e.getMessage(), Notification.Type.ERROR_MESSAGE) + .show(Page.getCurrent()); + return null; + } + return fos; + } + + public void uploadSucceeded(SucceededEvent event) { + Notification notif = new Notification("Info", "File upload sucess", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + try { + area.setCaption("Content of File " + file.getName()); + area.setValue(new String(Files.readAllBytes(file.toPath()))); + area.setVisible(true); + area.setHeight("600px"); + } catch (IOException e) { + new Notification("Could not open file", e.getMessage(), Notification.Type.ERROR_MESSAGE) + .show(Page.getCurrent()); + } + } + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LocalMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LocalMavenForm.java new file mode 100644 index 00000000..733cec45 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LocalMavenForm.java @@ -0,0 +1,36 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin; + +import com.vaadin.server.VaadinSession; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Tree; +import com.vaadin.ui.VerticalLayout; +import cz.zcu.kiv.crce.crce_webui_vaadin.classes.LocalMaven; + +@SuppressWarnings("serial") +public class LocalMavenForm extends FormLayout{ + private LocalMaven localMaven = new LocalMaven(); + private Label caption = new Label("Local Maven repository"); + + public LocalMavenForm() { + HorizontalLayout content = new HorizontalLayout(); + addComponent(content); + } + + public LocalMavenForm(VaadinSession session){ + VerticalLayout content = new VerticalLayout(); + // Tree of Maven local repository + Tree localMavenTree = localMaven.getTree(session); + content.setMargin(new MarginInfo(false, true)); + if(localMavenTree == null){ + content.addComponent(new Label("Local Maven repository not found")); + } + else{ + content.addComponents(caption, localMavenTree); + content.setSpacing(true); + } + addComponent(content); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LogoBackground.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LogoBackground.java new file mode 100644 index 00000000..33c5173b --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LogoBackground.java @@ -0,0 +1,14 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin; + +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Label; + +@SuppressWarnings("serial") +public class LogoBackground extends FormLayout{ + public LogoBackground(){ + Label logoBackground = new Label("

CRCE

",ContentMode.HTML); + addComponent(logoBackground); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MenuForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MenuForm.java new file mode 100644 index 00000000..f7c9c5f4 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MenuForm.java @@ -0,0 +1,42 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin; + +import com.vaadin.annotations.StyleSheet; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.MenuBar.MenuItem; + +@SuppressWarnings("serial") +@StyleSheet("https://fonts.googleapis.com/css?family=Fredoka+One") +public class MenuForm extends FormLayout{ + public MenuForm(MyUI myUI) { + HorizontalLayout headHL = new HorizontalLayout(); + Label logo = new Label("

CRCE UI

",ContentMode.HTML); + MenuBar menu = new MenuBar(); + MenuItem upload = menu.addItem("Upload", null); + MenuItem repository = menu.addItem("Repository", null); + MenuItem settings = menu.addItem("Settings", null); + + // submenu upload + upload.addItem("Local", e ->{myUI.setContentBodyLocalMaven();}); + upload.addItem("Central", e ->{myUI.setContentBodyCentralMaven();}); + upload.addItem("Defined", e ->{myUI.setContentBodyDefinedMaven();}); + upload.addItem("File", e ->{myUI.setContentBodyLoadFile();}); + + // submenu repository + repository.addItem("Refresh", null); + + // submenu settings + settings.addItem("Repository", e ->{myUI.setContentSettings();}); + + headHL.addComponents(logo,menu); + headHL.setComponentAlignment(menu,Alignment.MIDDLE_LEFT); + headHL.setSpacing(true); + headHL.setMargin(false); + addComponent(headHL); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MyUI.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MyUI.java new file mode 100644 index 00000000..f8ceb659 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MyUI.java @@ -0,0 +1,80 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin; + +import javax.servlet.annotation.WebServlet; +import com.vaadin.annotations.Theme; +import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinServlet; +import com.vaadin.ui.Panel; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +/** + * This UI is the application entry point. A UI may either represent a browser window + * (or tab) or some part of a html page where a Vaadin application is embedded. + *

+ * The UI is initialized using {@link #init(VaadinRequest)}. This method is intended to be + * overridden to add component to the user interface and initialize non-component functionality. + */ +@SuppressWarnings("serial") +@Theme("mytheme") +public class MyUI extends UI { + private MenuForm menu = new MenuForm(this); + private Panel head = new Panel(); + private Panel body = new Panel(); + private LocalMavenForm localMavenForm = new LocalMavenForm(); + private CentralMavenForm centralMavenForm = new CentralMavenForm(); + private DefinedMavenForm definedMavenForm = new DefinedMavenForm(); + private SettingsForm settingsForm = new SettingsForm(); + + + private LoadFileForm loadFileForm = new LoadFileForm(); + private VerticalLayout content = new VerticalLayout(); + + @Override + protected void init(VaadinRequest vaadinRequest) { + // menu components + menu.setMargin(false); + head.setContent(menu); + + // body components + LogoBackground logoBackgroung = new LogoBackground(); + body.setContent(logoBackgroung); + + // content components + content.setMargin(true); + content.setSpacing(true); + content.addComponents(head,body); + setContent(content); + } + + @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) + @VaadinServletConfiguration(ui = MyUI.class, productionMode = false) + public static class MyUIServlet extends VaadinServlet { + } + + public void setContentBodyLocalMaven(){ + localMavenForm = new LocalMavenForm(this.getSession()); + body.setContent(localMavenForm); + } + + public void setContentBodyCentralMaven(){ + centralMavenForm = new CentralMavenForm(this.getSession()); + body.setContent(centralMavenForm); + } + + public void setContentBodyDefinedMaven(){ + definedMavenForm = new DefinedMavenForm(this.getSession()); + body.setContent(definedMavenForm); + } + + public void setContentBodyLoadFile(){ + body.setContent(loadFileForm); + } + + public void setContentSettings(){ + settingsForm = new SettingsForm(this.getSession()); + body.setContent(settingsForm); + } +} + diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/SettingsForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/SettingsForm.java new file mode 100644 index 00000000..fe976def --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/SettingsForm.java @@ -0,0 +1,92 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin; + +import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.server.Page; +import com.vaadin.server.VaadinSession; +import com.vaadin.shared.Position; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.Button; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Notification; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; +import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; + +@SuppressWarnings("serial") +public class SettingsForm extends FormLayout { + + public SettingsForm() { + HorizontalLayout content = new HorizontalLayout(); + addComponent(content); + } + + public SettingsForm(VaadinSession session) { + TextField localMavenUrl = new TextField("Local Maven path"); + TextField centralMavenUrl = new TextField("Central Maven url"); + TextField localAetherRepo = new TextField("Local Aether repository"); + + localMavenUrl.setWidth("400px"); + centralMavenUrl.setWidth("400px"); + localAetherRepo.setWidth("400px"); + + // default value + + if (session.getAttribute("settingsUrl") == null) { + SettingsUrl settingsUrl = new SettingsUrl(); + localMavenUrl.setValue(settingsUrl.getLocalMavenUrl()); + centralMavenUrl.setValue(settingsUrl.getCentralMavenUrl()); + localAetherRepo.setValue(settingsUrl.getLocalAetherUrl()); + } else { + localMavenUrl.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getLocalMavenUrl()); + centralMavenUrl.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getCentralMavenUrl()); + localAetherRepo.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getLocalAetherUrl()); + } + + HorizontalLayout buttonsLayout = new HorizontalLayout(); + Button saveButton = new Button("Save"); + Button defaultButton = new Button("Default"); + buttonsLayout.addComponents(saveButton,defaultButton); + buttonsLayout.setSpacing(true); + + saveButton.setStyleName(ValoTheme.BUTTON_PRIMARY); + saveButton.setClickShortcut(KeyCode.ENTER); + + VerticalLayout content = new VerticalLayout(); + content.addComponents(localMavenUrl, centralMavenUrl, localAetherRepo, buttonsLayout); + content.setSpacing(true); + + HorizontalLayout formLayout = new HorizontalLayout(); + formLayout.addComponent(content); + formLayout.setMargin(new MarginInfo(false, true)); + + saveButton.addClickListener(e -> { + SettingsUrl settingsUrl; + if(getSession().getAttribute("settingsUrl") == null){ + settingsUrl = new SettingsUrl(); + } + else{ + settingsUrl = (SettingsUrl) getSession().getAttribute("settingsUrl"); + } + settingsUrl.setLocalMavenUrl(localMavenUrl.getValue()); + settingsUrl.setCentralMavenUrl(centralMavenUrl.getValue()); + settingsUrl.setLocalAetherUrl(localAetherRepo.getValue()); + getSession().setAttribute("settingsUrl", settingsUrl); + Notification notif = new Notification("Info", "Settings saved successfully" , + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + }); + + defaultButton.addClickListener(e ->{ + SettingsUrl settingsUrl = new SettingsUrl(); + getSession().setAttribute("settingsUrl", settingsUrl); + localMavenUrl.setValue(settingsUrl.getLocalMavenUrl()); + centralMavenUrl.setValue(settingsUrl.getCentralMavenUrl()); + localAetherRepo.setValue(settingsUrl.getLocalAetherUrl()); + }); + + addComponent(formLayout); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/CentralMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/CentralMaven.java new file mode 100644 index 00000000..2aa60a8e --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/CentralMaven.java @@ -0,0 +1,85 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.classes; + +import java.io.IOException; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import com.vaadin.server.FontAwesome; +import com.vaadin.server.VaadinSession; +import com.vaadin.ui.Tree; +import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; + +public class CentralMaven { + private static String centralMavenUrl; + private Tree resultSearchTree = new Tree("Result Search"); + private VaadinSession session; + + public CentralMaven(VaadinSession session){ + this.session = session; + } + + public Tree getTree(String group, String artifact, String version, Object packaging) { + // reset tree + resultSearchTree.removeAllItems(); + directSearch(group, artifact, version, packaging.toString()); + // is tree empty? + if(resultSearchTree.size() == 0){ + return null; + } + else{ + return resultSearchTree; + } + } + + private void directSearch(String group, String artifact, String version, String packaging){ + URL website; + if(session.getAttribute("settingsUrl") == null){ + SettingsUrl settings = new SettingsUrl(); + centralMavenUrl = settings.getCentralMavenUrl(); + } + else{ + centralMavenUrl = ((SettingsUrl)session.getAttribute("settingsUrl")).getCentralMavenUrl(); + } + try { + website = new URL(centralMavenUrl + group.replace('.', '/') + "/" + artifact + "/" + version + + "/" + artifact + "-" + version + "." + packaging); + ReadableByteChannel rbc = Channels.newChannel(website.openStream()); + if(rbc.isOpen()){ + String[] pom = group.split("\\."); + // adding group + resultSearchTree.addItem(pom[0]); + for(int i=1; i< pom.length; i++){ + resultSearchTree.addItem(pom[i]); + resultSearchTree.setParent(pom[i], pom[i-1]); + } + resultSearchTree.addItem(artifact); + resultSearchTree.setParent(artifact, pom[pom.length-1]); + resultSearchTree.addItem(version); + resultSearchTree.setParent(version,artifact); + //end artifact + resultSearchTree.addItem(website.toString()); + resultSearchTree.setParent(website.toString(),version); + resultSearchTree.setItemCaption(website.toString(), artifact + "-" + version + "." + packaging); + resultSearchTree.setChildrenAllowed(website.toString(),false); + if(packaging.equals("jar") || packaging.equals("war")){ + resultSearchTree.setItemIcon(website.toString(), FontAwesome.GIFT); + } + else if(packaging.equals("xml") || packaging.equals("pom")){ + resultSearchTree.setItemIcon(website.toString(), FontAwesome.CODE); + } + else{ + resultSearchTree.setItemIcon(website.toString(), FontAwesome.FILE); + } + + rbc.close(); + + // real download from url + /*FileOutputStream fos = new FileOutputStream("information.html"); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);*/ + + } + } catch (IOException e) { + resultSearchTree.clear(); + } + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/DefinedMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/DefinedMaven.java new file mode 100644 index 00000000..6bf436b9 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/DefinedMaven.java @@ -0,0 +1,140 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.classes; + +import java.util.Arrays; +import org.apache.maven.repository.internal.MavenRepositorySystemUtils; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; +import org.eclipse.aether.impl.DefaultServiceLocator; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.resolution.VersionRangeRequest; +import org.eclipse.aether.resolution.VersionRangeResolutionException; +import org.eclipse.aether.resolution.VersionRangeResult; +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; +import org.eclipse.aether.spi.connector.transport.TransporterFactory; +import org.eclipse.aether.transport.file.FileTransporterFactory; +import org.eclipse.aether.transport.http.HttpTransporterFactory; +import org.eclipse.aether.version.Version; + +import com.vaadin.server.FontAwesome; +import com.vaadin.ui.Tree; + +import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; + +public class DefinedMaven { + private Tree definedMavenTree = new Tree("Result Search"); + private String groupText; + private String artifactText; + private String versionText; + private String packagingText; + private SettingsUrl settings; + + public DefinedMaven(SettingsUrl settings){ + this.settings = settings; + } + + public Tree getTree(String group, String artifact, String version, Object packaging) { + // validator empty entries + if(group.equals("") || artifact.equals("")){ + return null; + } + else{ + // reset tree + definedMavenTree.removeAllItems(); + this.groupText = group; + this.artifactText = artifact; + this.versionText = version; + this.packagingText = packaging.toString(); + callAetherLib(); + return definedMavenTree; + } + } + + private void callAetherLib() { + RemoteRepository central = new RemoteRepository.Builder("nexus", "default", settings.getExternalAetherUrl()).build(); + RepositorySystem repoSystem = newRepositorySystem(); + RepositorySystemSession session = newSession(repoSystem, settings.getLocalAetherUrl()); + + // Artifact artifact = new DefaultArtifact("groupId:artifactId:(0,]"); + Artifact artifact; + if(!versionText.equals("")){ + artifact = new DefaultArtifact(groupText + ":" + artifactText + ":" + "[" + versionText + "]"); + } + else{ + artifact = new DefaultArtifact(groupText + ":" + artifactText + ":" + "(0,]"); + } + VersionRangeRequest request = new VersionRangeRequest(artifact, Arrays.asList(central), null); + try { + VersionRangeResult versionResult = repoSystem.resolveVersionRange(session, request); + if(versionResult.getHighestVersion() == null) { + definedMavenTree = null; + } + else { + String[] pom = artifact.getGroupId().split("\\."); + definedMavenTree.addItem(pom[0]); + for(int i=1; i< pom.length; i++){ + definedMavenTree.addItem(pom[i]); + definedMavenTree.setParent(pom[i], pom[i-1]); + } + + if(versionResult.getVersions().size() > 1){ + for(Version v : versionResult.getVersions()){ + addArtefactToTree(artifact, v, pom[pom.length-1]); + } + } + else{ + addArtefactToTree(artifact, versionResult.getHighestVersion(), pom[pom.length-1]); + } + } + + } catch (VersionRangeResolutionException e) { + e.printStackTrace(); + } + } + + private void addArtefactToTree(Artifact artifact, Version version, String parent){ + definedMavenTree.addItem(artifact.getArtifactId()); + definedMavenTree.setParent(artifact.getArtifactId(), parent); + definedMavenTree.addItem(version.toString()); + definedMavenTree.setParent(version.toString(),artifact.getArtifactId()); + + //end artefact + //konečný artefact je komplet url link např. pro wget - UPRAVIT DLE POTŘEBY + String urlArtefact = settings.getExternalAetherUrl() + "/" + groupText + "/" + artifactText + + "/" + version + "." + packagingText; + + definedMavenTree.addItem(urlArtefact); + definedMavenTree.setParent(urlArtefact, version.toString()); + definedMavenTree.setItemCaption(urlArtefact, artifact.getArtifactId() + + "-" + version.toString() + "." + packagingText); + definedMavenTree.setChildrenAllowed(urlArtefact, false); + if(packagingText.equals("jar") || packagingText.equals("war")){ + definedMavenTree.setItemIcon(urlArtefact, FontAwesome.GIFT); + } + else if(packagingText.equals("xml") || packagingText.equals("pom")){ + definedMavenTree.setItemIcon(urlArtefact, FontAwesome.CODE); + } + else{ + definedMavenTree.setItemIcon(urlArtefact, FontAwesome.FILE); + } + } + + private static RepositorySystem newRepositorySystem() { + DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); + locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); + locator.addService(TransporterFactory.class, FileTransporterFactory.class); + locator.addService(TransporterFactory.class, HttpTransporterFactory.class); + return locator.getService(RepositorySystem.class); + } + + private static RepositorySystemSession newSession(RepositorySystem system, String localAetherUrl) { + DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); + LocalRepository localRepo = new LocalRepository(localAetherUrl); + session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)); + return session; + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/LocalMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/LocalMaven.java new file mode 100644 index 00000000..fda0abd9 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/LocalMaven.java @@ -0,0 +1,59 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.classes; + +import java.io.File; +import com.vaadin.server.FontAwesome; +import com.vaadin.server.VaadinSession; +import com.vaadin.ui.Tree; + +import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; + +public class LocalMaven { + private Tree localMavenTree = new Tree(); + private String path;// = System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository"; + public Tree getTree(VaadinSession session) { + // get local Maven path + if(session.getAttribute("settingsUrl") == null){ + SettingsUrl settings = new SettingsUrl(); + path = settings.getLocalMavenUrl(); + } + else{ + path = ((SettingsUrl)session.getAttribute("settingsUrl")).getLocalMavenUrl(); + } + + File f = new File(path); + if(f.exists()){ + list(f); + return localMavenTree; + } + else{ + return null; + } + } + + private void list(File file) { + File[] children = file.listFiles(); + for (File child : children) { + if ((child.isDirectory()) && (child.getName().charAt(0) != '.')) { + localMavenTree.addItem(child.getAbsolutePath()); + localMavenTree.setItemCaption(child.getAbsolutePath(), child.getName()); + localMavenTree.setParent(child.getAbsolutePath(), child.getParentFile().getAbsolutePath()); + list(child); + } + else if(child.isFile() && !child.getParentFile().getAbsolutePath().equals(path)){ + localMavenTree.addItem(child.getAbsolutePath()); + localMavenTree.setItemCaption(child.getAbsolutePath(), child.getName()); + localMavenTree.setParent(child.getAbsolutePath(), child.getParentFile().getAbsolutePath()); + localMavenTree.setChildrenAllowed(child.getAbsolutePath(), false); + if(child.getName().endsWith(".jar") || child.getName().endsWith(".war")){ + localMavenTree.setItemIcon(child.getAbsolutePath(), FontAwesome.GIFT); + } + else if(child.getName().endsWith(".xml") || child.getName().endsWith(".pom")){ + localMavenTree.setItemIcon(child.getAbsolutePath(), FontAwesome.CODE); + } + else{ + localMavenTree.setItemIcon(child.getAbsolutePath(), FontAwesome.FILE); + } + } + } + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/TypePackaging.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/TypePackaging.java new file mode 100644 index 00000000..af77ae48 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/TypePackaging.java @@ -0,0 +1,5 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.other; + +public enum TypePackaging { + jar,war,ejb,ear,pom,maven_plugin +} diff --git a/modules/crce-webui-vaadin/src/main/resources/README b/modules/crce-webui-vaadin/src/main/resources/README new file mode 100644 index 00000000..faabc74a --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/resources/README @@ -0,0 +1 @@ +Please add your static resources here diff --git a/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss b/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss new file mode 100644 index 00000000..a5670b70 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss @@ -0,0 +1,7 @@ +/* This file is automatically managed and will be overwritten from time to time. */ +/* Do not manually edit this file. */ + +/* Import and include this mixin into your project theme to include the addon themes */ +@mixin addons { +} + diff --git a/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico b/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ffb34a65c73eb1b3d59dcbb8f18ec78a8b0fc767 GIT binary patch literal 31005 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 + + crce-webui-vaadin + + org.atmosphere.cpr.SessionSupport + true + + + productionMode + false + + + MyUIServlet + cz.zcu.kiv.crce.crce_webui_vaadin.MyUI$MyUIServlet + + + MyUIServlet + /* + + + 30 + + diff --git a/modules/pom.xml b/modules/pom.xml index 60173cc6..54450c2a 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -57,7 +57,7 @@ pom - provision + crce-metadata-osgi-bundle @@ -69,7 +69,7 @@ crce-handler-metrics - crce-webui + crce-rest-v2 @@ -83,6 +83,9 @@ crce-webservices-indexer + crce-external-repository + crce-webui-vaadin + provision diff --git a/modules/provision/pom.xml b/modules/provision/pom.xml index 1e5a075c..f8e848b0 100644 --- a/modules/provision/pom.xml +++ b/modules/provision/pom.xml @@ -1,171 +1,183 @@ - - - 4.0.0 - - - ../pom - cz.zcu.kiv.crce - crce-modules-parent - 2.1.1-SNAPSHOT - - - provision - - CRCE - Provision - - pom - - - - - - - - org.osgi - org.osgi.core - - - org.osgi - org.osgi.compendium - - - - - - org.ops4j.pax.web - pax-web-extender-war - - - org.ops4j.pax.web - pax-web-jetty-bundle - - - org.ops4j.pax.web - pax-web-jsp - - - org.ops4j.pax.web - pax-web-spi - - - - - - org.apache.felix - org.apache.felix.configadmin - - - org.apache.felix - org.apache.felix.dependencymanager - - - org.apache.felix - org.apache.felix.dependencymanager.shell - - - org.apache.felix - org.apache.felix.gogo.runtime - - - - - org.apache.felix - org.apache.felix.dependencymanager.runtime - - - org.apache.felix - org.apache.felix.eventadmin - - - org.apache.felix - org.apache.felix.scr - - - org.apache.felix - org.apache.felix.webconsole - - - org.apache.felix - org.apache.felix.shell - - - org.apache.felix - org.apache.felix.bundlerepository - - - org.apache.felix - org.apache.felix.fileinstall - - - org.apache.felix - org.osgi.service.obr - - - - - - asm - asm-all - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.commons-vfs - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.bcel - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.jaxp-ri - - - com.google.code.gson - gson - - - org.codehaus.groovy - groovy-all - - - commons-fileupload - commons-fileupload - - - commons-io - commons-io - - - de.twentyeleven.skysail - org.json-osgi - - - org.apache.xbean - xbean-finder - - - - org.mybatis - mybatis - - - - com.h2database - h2 - - - - - - cz.zcu.kiv.crce - crce-core - pom - - + + + 4.0.0 + + + ../pom + cz.zcu.kiv.crce + crce-modules-parent + 2.1.1-SNAPSHOT + + + provision + + CRCE - Provision + + pom + + + + + + + + org.osgi + org.osgi.core + + + org.osgi + org.osgi.compendium + + + + + + org.ops4j.pax.web + pax-web-jsp + + + org.ops4j.pax.web + pax-web-jetty-bundle + + + org.ops4j.pax.web + pax-web-spi + + + org.ops4j.pax.web + pax-web-api + + + org.ops4j.pax.web + pax-web-extender-war + + + org.ops4j.pax.web + pax-web-descriptor + + + + + + org.apache.felix + org.apache.felix.configadmin + + + org.apache.felix + org.apache.felix.dependencymanager + + + org.apache.felix + org.apache.felix.dependencymanager.shell + + + org.apache.felix + org.apache.felix.gogo.runtime + + + + + org.apache.felix + org.apache.felix.dependencymanager.runtime + + + org.apache.felix + org.apache.felix.eventadmin + + + org.apache.felix + org.apache.felix.scr + + + org.apache.felix + org.apache.felix.webconsole + + + org.apache.felix + org.apache.felix.shell + + + org.apache.felix + org.apache.felix.bundlerepository + + + org.apache.felix + org.apache.felix.fileinstall + + + org.apache.felix + org.osgi.service.obr + + + + + + asm + asm-all + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.commons-vfs + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.bcel + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.jaxp-ri + + + com.google.code.gson + gson + + + org.codehaus.groovy + groovy-all + + + commons-fileupload + commons-fileupload + + + commons-io + commons-io + + + de.twentyeleven.skysail + org.json-osgi + + + + org.mybatis + mybatis + + + + com.h2database + h2 + + + + + org.apache.xbean + xbean-finder + + + org.apache.xbean + xbean-bundleutils + + + + + + cz.zcu.kiv.crce + crce-core + pom + + diff --git a/pom.xml b/pom.xml index cee06dbe..0663881d 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ CRCE - Reactor - pom + build core modules diff --git a/pom/pom.xml b/pom/pom.xml index 38a92be9..42cef4a2 100644 --- a/pom/pom.xml +++ b/pom/pom.xml @@ -74,7 +74,7 @@ - + Central repository - must be listed first as a default repo for downloading of artifacts central http://uk.maven.org/maven2 @@ -86,7 +86,7 @@ http://relisa-dev.kiv.zcu.cz:8081/nexus/content/groups/public - + Fallback repositories maven.kalwi.eu.snapshots kalwi.eu snapshots repository From bfc16d3cf77be58b4f3c4584b7f5b084a0b1d1b1 Mon Sep 17 00:00:00 2001 From: rpesek Date: Mon, 19 Jun 2017 09:21:24 +0200 Subject: [PATCH 02/85] Integration of CRCE with WebUI (Vaadin) module 1.0 Stable module assembly with new UI module --- build/pom.xml | 7 +- core/crce-metadata-api/.classpath | 31 ++++ core/crce-metadata-api/.project | 24 +++ core/crce-metadata-dao-api/.classpath | 27 +++ core/crce-metadata-dao-api/.project | 49 ++++++ core/crce-metadata-dao-impl/.classpath | 32 ++++ core/crce-metadata-dao-impl/.project | 49 ++++++ core/crce-metadata-impl/.classpath | 26 +++ core/crce-metadata-impl/.project | 24 +++ core/crce-metadata-indexer-api/.classpath | 26 +++ core/crce-metadata-indexer-api/.project | 24 +++ core/crce-metadata-indexer-impl/.classpath | 26 +++ core/crce-metadata-indexer-impl/.project | 24 +++ core/crce-metadata-json-api/.classpath | 26 +++ core/crce-metadata-json-api/.project | 24 +++ core/crce-metadata-json-impl/.classpath | 26 +++ core/crce-metadata-json-impl/.project | 24 +++ core/crce-metadata-service-api/.classpath | 26 +++ core/crce-metadata-service-api/.project | 24 +++ core/crce-metadata-service-impl/.classpath | 26 +++ core/crce-metadata-service-impl/.project | 24 +++ core/crce-plugin-api/.classpath | 26 +++ core/crce-plugin-api/.project | 24 +++ core/crce-repository-api/.classpath | 27 +++ core/crce-repository-api/.project | 49 ++++++ core/crce-repository-impl/.classpath | 27 +++ core/crce-repository-impl/.project | 49 ++++++ core/crce-resolver-api/.classpath | 27 +++ core/crce-resolver-api/.project | 49 ++++++ core/crce-resolver-impl/.classpath | 27 +++ core/crce-resolver-impl/.project | 49 ++++++ modules/crce-compatibility-api/.classpath | 32 ++++ modules/crce-compatibility-api/.project | 49 ++++++ modules/crce-compatibility-dao-api/.classpath | 26 +++ modules/crce-compatibility-dao-api/.project | 24 +++ .../crce-compatibility-dao-mongodb/.classpath | 26 +++ .../crce-compatibility-dao-mongodb/.project | 24 +++ modules/crce-concurrency/.classpath | 31 ++++ modules/crce-concurrency/.project | 24 +++ modules/crce-external-repository/.classpath | 6 +- modules/crce-external-repository/pom.xml | 18 +- .../crce/external/web/inf/InfSettingsUrl.java | 16 +- modules/crce-handler-metrics/.classpath | 26 +++ modules/crce-handler-metrics/.project | 24 +++ modules/crce-integration-tests/.classpath | 31 ++++ modules/crce-integration-tests/.project | 23 +++ modules/crce-metadata-osgi-bundle/.classpath | 27 +++ modules/crce-metadata-osgi-bundle/.project | 49 ++++++ modules/crce-rest-v2/.classpath | 27 +++ modules/crce-rest-v2/.project | 44 +++++ modules/crce-target/.project | 17 ++ modules/crce-vo/.classpath | 32 ++++ modules/crce-vo/.project | 49 ++++++ modules/crce-webservices-indexer/.classpath | 26 +++ modules/crce-webservices-indexer/.project | 24 +++ modules/crce-webui-vaadin/.classpath | 10 +- modules/crce-webui-vaadin/pom.xml | 85 ++++++++- .../crce_webui_vaadin/DefinedMavenForm.java | 7 +- .../crce/crce_webui_vaadin/LoadFileForm.java | 3 +- .../classes/DefinedMaven.java | 2 +- .../crce_webui_vaadin/classes/LocalMaven.java | 7 +- .../crce_webui_vaadin/internal/Activator.java | 166 ++++++++++++++++++ modules/crce-webui/.classpath | 27 +++ modules/crce-webui/.project | 44 +++++ 64 files changed, 1911 insertions(+), 38 deletions(-) create mode 100644 core/crce-metadata-api/.classpath create mode 100644 core/crce-metadata-api/.project create mode 100644 core/crce-metadata-dao-api/.classpath create mode 100644 core/crce-metadata-dao-api/.project create mode 100644 core/crce-metadata-dao-impl/.classpath create mode 100644 core/crce-metadata-dao-impl/.project create mode 100644 core/crce-metadata-impl/.classpath create mode 100644 core/crce-metadata-impl/.project create mode 100644 core/crce-metadata-indexer-api/.classpath create mode 100644 core/crce-metadata-indexer-api/.project create mode 100644 core/crce-metadata-indexer-impl/.classpath create mode 100644 core/crce-metadata-indexer-impl/.project create mode 100644 core/crce-metadata-json-api/.classpath create mode 100644 core/crce-metadata-json-api/.project create mode 100644 core/crce-metadata-json-impl/.classpath create mode 100644 core/crce-metadata-json-impl/.project create mode 100644 core/crce-metadata-service-api/.classpath create mode 100644 core/crce-metadata-service-api/.project create mode 100644 core/crce-metadata-service-impl/.classpath create mode 100644 core/crce-metadata-service-impl/.project create mode 100644 core/crce-plugin-api/.classpath create mode 100644 core/crce-plugin-api/.project create mode 100644 core/crce-repository-api/.classpath create mode 100644 core/crce-repository-api/.project create mode 100644 core/crce-repository-impl/.classpath create mode 100644 core/crce-repository-impl/.project create mode 100644 core/crce-resolver-api/.classpath create mode 100644 core/crce-resolver-api/.project create mode 100644 core/crce-resolver-impl/.classpath create mode 100644 core/crce-resolver-impl/.project create mode 100644 modules/crce-compatibility-api/.classpath create mode 100644 modules/crce-compatibility-api/.project create mode 100644 modules/crce-compatibility-dao-api/.classpath create mode 100644 modules/crce-compatibility-dao-api/.project create mode 100644 modules/crce-compatibility-dao-mongodb/.classpath create mode 100644 modules/crce-compatibility-dao-mongodb/.project create mode 100644 modules/crce-concurrency/.classpath create mode 100644 modules/crce-concurrency/.project create mode 100644 modules/crce-handler-metrics/.classpath create mode 100644 modules/crce-handler-metrics/.project create mode 100644 modules/crce-integration-tests/.classpath create mode 100644 modules/crce-integration-tests/.project create mode 100644 modules/crce-metadata-osgi-bundle/.classpath create mode 100644 modules/crce-metadata-osgi-bundle/.project create mode 100644 modules/crce-rest-v2/.classpath create mode 100644 modules/crce-rest-v2/.project create mode 100644 modules/crce-target/.project create mode 100644 modules/crce-vo/.classpath create mode 100644 modules/crce-vo/.project create mode 100644 modules/crce-webservices-indexer/.classpath create mode 100644 modules/crce-webservices-indexer/.project create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/internal/Activator.java create mode 100644 modules/crce-webui/.classpath create mode 100644 modules/crce-webui/.project diff --git a/build/pom.xml b/build/pom.xml index 720243a9..b2415a40 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -80,7 +80,7 @@ org.apache.felix maven-bundle-plugin - 2.5.3 + 3.3.0 true @@ -118,12 +118,13 @@ maven-war-plugin - 2.5 + 2.6 org.apache.maven.plugins maven-pmd-plugin - 3.1 + 3.8 + org.codehaus.mojo diff --git a/core/crce-metadata-api/.classpath b/core/crce-metadata-api/.classpath new file mode 100644 index 00000000..698778fe --- /dev/null +++ b/core/crce-metadata-api/.classpath @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-metadata-api/.project b/core/crce-metadata-api/.project new file mode 100644 index 00000000..742c9778 --- /dev/null +++ b/core/crce-metadata-api/.project @@ -0,0 +1,24 @@ + + + crce-metadata-api + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/core/crce-metadata-dao-api/.classpath b/core/crce-metadata-dao-api/.classpath new file mode 100644 index 00000000..7755c1a8 --- /dev/null +++ b/core/crce-metadata-dao-api/.classpath @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-metadata-dao-api/.project b/core/crce-metadata-dao-api/.project new file mode 100644 index 00000000..684a2e2c --- /dev/null +++ b/core/crce-metadata-dao-api/.project @@ -0,0 +1,49 @@ + + + crce-metadata-dao-api + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + + diff --git a/core/crce-metadata-dao-impl/.classpath b/core/crce-metadata-dao-impl/.classpath new file mode 100644 index 00000000..8a297cd0 --- /dev/null +++ b/core/crce-metadata-dao-impl/.classpath @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-metadata-dao-impl/.project b/core/crce-metadata-dao-impl/.project new file mode 100644 index 00000000..bc6afb37 --- /dev/null +++ b/core/crce-metadata-dao-impl/.project @@ -0,0 +1,49 @@ + + + crce-metadata-dao-impl + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + + diff --git a/core/crce-metadata-impl/.classpath b/core/crce-metadata-impl/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/core/crce-metadata-impl/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-metadata-impl/.project b/core/crce-metadata-impl/.project new file mode 100644 index 00000000..a4af59d2 --- /dev/null +++ b/core/crce-metadata-impl/.project @@ -0,0 +1,24 @@ + + + crce-metadata-impl + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/core/crce-metadata-indexer-api/.classpath b/core/crce-metadata-indexer-api/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/core/crce-metadata-indexer-api/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-metadata-indexer-api/.project b/core/crce-metadata-indexer-api/.project new file mode 100644 index 00000000..7ce7bc92 --- /dev/null +++ b/core/crce-metadata-indexer-api/.project @@ -0,0 +1,24 @@ + + + crce-metadata-indexer-api + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/core/crce-metadata-indexer-impl/.classpath b/core/crce-metadata-indexer-impl/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/core/crce-metadata-indexer-impl/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-metadata-indexer-impl/.project b/core/crce-metadata-indexer-impl/.project new file mode 100644 index 00000000..529a3266 --- /dev/null +++ b/core/crce-metadata-indexer-impl/.project @@ -0,0 +1,24 @@ + + + crce-metadata-indexer-impl + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/core/crce-metadata-json-api/.classpath b/core/crce-metadata-json-api/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/core/crce-metadata-json-api/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-metadata-json-api/.project b/core/crce-metadata-json-api/.project new file mode 100644 index 00000000..b6466006 --- /dev/null +++ b/core/crce-metadata-json-api/.project @@ -0,0 +1,24 @@ + + + crce-metadata-json-api + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/core/crce-metadata-json-impl/.classpath b/core/crce-metadata-json-impl/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/core/crce-metadata-json-impl/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-metadata-json-impl/.project b/core/crce-metadata-json-impl/.project new file mode 100644 index 00000000..17eaab60 --- /dev/null +++ b/core/crce-metadata-json-impl/.project @@ -0,0 +1,24 @@ + + + crce-metadata-json-impl + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/core/crce-metadata-service-api/.classpath b/core/crce-metadata-service-api/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/core/crce-metadata-service-api/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-metadata-service-api/.project b/core/crce-metadata-service-api/.project new file mode 100644 index 00000000..c64b935f --- /dev/null +++ b/core/crce-metadata-service-api/.project @@ -0,0 +1,24 @@ + + + crce-metadata-service-api + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/core/crce-metadata-service-impl/.classpath b/core/crce-metadata-service-impl/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/core/crce-metadata-service-impl/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-metadata-service-impl/.project b/core/crce-metadata-service-impl/.project new file mode 100644 index 00000000..8d5ac902 --- /dev/null +++ b/core/crce-metadata-service-impl/.project @@ -0,0 +1,24 @@ + + + crce-metadata-service-impl + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/core/crce-plugin-api/.classpath b/core/crce-plugin-api/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/core/crce-plugin-api/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-plugin-api/.project b/core/crce-plugin-api/.project new file mode 100644 index 00000000..8a6a039a --- /dev/null +++ b/core/crce-plugin-api/.project @@ -0,0 +1,24 @@ + + + crce-plugin-api + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/core/crce-repository-api/.classpath b/core/crce-repository-api/.classpath new file mode 100644 index 00000000..7755c1a8 --- /dev/null +++ b/core/crce-repository-api/.classpath @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-repository-api/.project b/core/crce-repository-api/.project new file mode 100644 index 00000000..1ec320ad --- /dev/null +++ b/core/crce-repository-api/.project @@ -0,0 +1,49 @@ + + + crce-repository-api + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + + diff --git a/core/crce-repository-impl/.classpath b/core/crce-repository-impl/.classpath new file mode 100644 index 00000000..7755c1a8 --- /dev/null +++ b/core/crce-repository-impl/.classpath @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-repository-impl/.project b/core/crce-repository-impl/.project new file mode 100644 index 00000000..c0c91906 --- /dev/null +++ b/core/crce-repository-impl/.project @@ -0,0 +1,49 @@ + + + crce-repository-impl + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + + diff --git a/core/crce-resolver-api/.classpath b/core/crce-resolver-api/.classpath new file mode 100644 index 00000000..7755c1a8 --- /dev/null +++ b/core/crce-resolver-api/.classpath @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-resolver-api/.project b/core/crce-resolver-api/.project new file mode 100644 index 00000000..e96558e1 --- /dev/null +++ b/core/crce-resolver-api/.project @@ -0,0 +1,49 @@ + + + crce-resolver-api + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + + diff --git a/core/crce-resolver-impl/.classpath b/core/crce-resolver-impl/.classpath new file mode 100644 index 00000000..7755c1a8 --- /dev/null +++ b/core/crce-resolver-impl/.classpath @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/crce-resolver-impl/.project b/core/crce-resolver-impl/.project new file mode 100644 index 00000000..ee6ae75e --- /dev/null +++ b/core/crce-resolver-impl/.project @@ -0,0 +1,49 @@ + + + crce-resolver-impl + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + + diff --git a/modules/crce-compatibility-api/.classpath b/modules/crce-compatibility-api/.classpath new file mode 100644 index 00000000..303bafb0 --- /dev/null +++ b/modules/crce-compatibility-api/.classpath @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-compatibility-api/.project b/modules/crce-compatibility-api/.project new file mode 100644 index 00000000..92af28f5 --- /dev/null +++ b/modules/crce-compatibility-api/.project @@ -0,0 +1,49 @@ + + + crce-compatibility-api + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + + diff --git a/modules/crce-compatibility-dao-api/.classpath b/modules/crce-compatibility-dao-api/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/modules/crce-compatibility-dao-api/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-compatibility-dao-api/.project b/modules/crce-compatibility-dao-api/.project new file mode 100644 index 00000000..b7277b3f --- /dev/null +++ b/modules/crce-compatibility-dao-api/.project @@ -0,0 +1,24 @@ + + + crce-compatibility-dao-api + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/modules/crce-compatibility-dao-mongodb/.classpath b/modules/crce-compatibility-dao-mongodb/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/modules/crce-compatibility-dao-mongodb/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-compatibility-dao-mongodb/.project b/modules/crce-compatibility-dao-mongodb/.project new file mode 100644 index 00000000..c1baab22 --- /dev/null +++ b/modules/crce-compatibility-dao-mongodb/.project @@ -0,0 +1,24 @@ + + + crce-compatibility-dao-mongodb + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/modules/crce-concurrency/.classpath b/modules/crce-concurrency/.classpath new file mode 100644 index 00000000..698778fe --- /dev/null +++ b/modules/crce-concurrency/.classpath @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-concurrency/.project b/modules/crce-concurrency/.project new file mode 100644 index 00000000..f5348e6d --- /dev/null +++ b/modules/crce-concurrency/.project @@ -0,0 +1,24 @@ + + + crce-concurrency + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/modules/crce-external-repository/.classpath b/modules/crce-external-repository/.classpath index 71a86ecf..08d7a50f 100644 --- a/modules/crce-external-repository/.classpath +++ b/modules/crce-external-repository/.classpath @@ -22,15 +22,15 @@ - + + - + - diff --git a/modules/crce-external-repository/pom.xml b/modules/crce-external-repository/pom.xml index 9bbbaa16..81050fe7 100644 --- a/modules/crce-external-repository/pom.xml +++ b/modules/crce-external-repository/pom.xml @@ -1,12 +1,22 @@ 4.0.0 - cz.zcu.kiv.crce + + + ../pom + cz.zcu.kiv.crce + crce-modules-parent + 2.1.1-SNAPSHOT + + crce-external-repository 1.0 - 1.8 - 1.8 + 1.8 + CRCE - External Repository Support + ${namespace}.crce_external_repository + + @@ -22,7 +32,7 @@ org.apache.felix maven-bundle-plugin - 3.2.0 + true diff --git a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java index 13d237b6..7682c9f3 100644 --- a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java +++ b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java @@ -1,13 +1,13 @@ package cz.zcu.kiv.crce.external.web.inf; public interface InfSettingsUrl { - public String getLocalMavenUrl(); - public String getCentralMavenUrl(); - public String getLocalAetherUrl(); - public String getExternalAetherUrl(); + String getLocalMavenUrl(); + String getCentralMavenUrl(); + String getLocalAetherUrl(); + String getExternalAetherUrl(); - public void setLocalMavenUrl(String url); - public void setCentralMavenUrl(String url); - public void setLocalAetherUrl(String url); - public void setExternalAetherUrl(String url); + void setLocalMavenUrl(String url); + void setCentralMavenUrl(String url); + void setLocalAetherUrl(String url); + void setExternalAetherUrl(String url); } diff --git a/modules/crce-handler-metrics/.classpath b/modules/crce-handler-metrics/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/modules/crce-handler-metrics/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-handler-metrics/.project b/modules/crce-handler-metrics/.project new file mode 100644 index 00000000..e42aad3c --- /dev/null +++ b/modules/crce-handler-metrics/.project @@ -0,0 +1,24 @@ + + + crce-handler-metrics + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/modules/crce-integration-tests/.classpath b/modules/crce-integration-tests/.classpath new file mode 100644 index 00000000..b2acffc9 --- /dev/null +++ b/modules/crce-integration-tests/.classpath @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-integration-tests/.project b/modules/crce-integration-tests/.project new file mode 100644 index 00000000..9a6c3a99 --- /dev/null +++ b/modules/crce-integration-tests/.project @@ -0,0 +1,23 @@ + + + crce-integration-tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/modules/crce-metadata-osgi-bundle/.classpath b/modules/crce-metadata-osgi-bundle/.classpath new file mode 100644 index 00000000..faa90026 --- /dev/null +++ b/modules/crce-metadata-osgi-bundle/.classpath @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-metadata-osgi-bundle/.project b/modules/crce-metadata-osgi-bundle/.project new file mode 100644 index 00000000..63712ada --- /dev/null +++ b/modules/crce-metadata-osgi-bundle/.project @@ -0,0 +1,49 @@ + + + crce-metadata-osgi-bundle + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + + diff --git a/modules/crce-rest-v2/.classpath b/modules/crce-rest-v2/.classpath new file mode 100644 index 00000000..79855789 --- /dev/null +++ b/modules/crce-rest-v2/.classpath @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-rest-v2/.project b/modules/crce-rest-v2/.project new file mode 100644 index 00000000..a8444c13 --- /dev/null +++ b/modules/crce-rest-v2/.project @@ -0,0 +1,44 @@ + + + crce-rest-v2 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.jboss.tools.ws.jaxrs.metamodelBuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.jsdt.core.jsNature + org.jboss.tools.ws.jaxrs.nature + + diff --git a/modules/crce-target/.project b/modules/crce-target/.project new file mode 100644 index 00000000..d6fd71d3 --- /dev/null +++ b/modules/crce-target/.project @@ -0,0 +1,17 @@ + + + crce-target + + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + + diff --git a/modules/crce-vo/.classpath b/modules/crce-vo/.classpath new file mode 100644 index 00000000..303bafb0 --- /dev/null +++ b/modules/crce-vo/.classpath @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-vo/.project b/modules/crce-vo/.project new file mode 100644 index 00000000..d05aee05 --- /dev/null +++ b/modules/crce-vo/.project @@ -0,0 +1,49 @@ + + + crce-vo + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + + diff --git a/modules/crce-webservices-indexer/.classpath b/modules/crce-webservices-indexer/.classpath new file mode 100644 index 00000000..f619a536 --- /dev/null +++ b/modules/crce-webservices-indexer/.classpath @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-webservices-indexer/.project b/modules/crce-webservices-indexer/.project new file mode 100644 index 00000000..ac410930 --- /dev/null +++ b/modules/crce-webservices-indexer/.project @@ -0,0 +1,24 @@ + + + crce-webservices-indexer + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/modules/crce-webui-vaadin/.classpath b/modules/crce-webui-vaadin/.classpath index abbb4e7d..6c0e1a79 100644 --- a/modules/crce-webui-vaadin/.classpath +++ b/modules/crce-webui-vaadin/.classpath @@ -17,11 +17,6 @@ - - - - - @@ -35,5 +30,10 @@ + + + + + diff --git a/modules/crce-webui-vaadin/pom.xml b/modules/crce-webui-vaadin/pom.xml index 05896252..8c462eb1 100644 --- a/modules/crce-webui-vaadin/pom.xml +++ b/modules/crce-webui-vaadin/pom.xml @@ -3,23 +3,30 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - cz.zcu.kiv.crce + + ../pom + cz.zcu.kiv.crce + crce-modules-parent + 2.1.1-SNAPSHOT + + crce-webui-vaadin war 1.0 CRCE - Web UI (Vaadin) - + + CRCE - Web UI (Vaadin) + ${namespace}.crce_webui_vaadin 7.7.7 7.7.7 9.3.9.v20160517 UTF-8 - 1.8 - 1.8 + 1.8 + + local @@ -71,6 +78,16 @@ slf4j-simple 1.7.22 + + org.apache.maven + maven-artifact + 3.3.9 + + + org.codehaus.plexus + plexus-utils + 3.0.22 + @@ -125,6 +142,26 @@ crce-external-repository 1.0 + + cz.zcu.kiv.crce + crce-metadata-osgi-bundle + 2.1.1-SNAPSHOT + bundle + + + cz.zcu.kiv.crce + crce-compatibility-api + 2.1.1-SNAPSHOT + bundle + + + org.apache.maven + maven-artifact + + + org.codehaus.plexus + plexus-utils + @@ -132,13 +169,14 @@ org.apache.maven.plugins maven-war-plugin - 2.6 + false WEB-INF/classes/VAADIN/widgetsets/WEB-INF/** ${project.build.directory}/META-INF/MANIFEST.MF + WEB-INF/classes @@ -178,10 +216,40 @@ + + + + org.apache.felix maven-bundle-plugin - 3.2.0 + true @@ -205,6 +273,7 @@ cz.zcu.kiv.crce.external.web.impl + cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator ${project.artifactId} WEB-INF/classes, diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/DefinedMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/DefinedMavenForm.java index e314627f..a95fa43c 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/DefinedMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/DefinedMavenForm.java @@ -1,5 +1,6 @@ package cz.zcu.kiv.crce.crce_webui_vaadin; +import java.io.Serializable; import java.util.EnumSet; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.server.VaadinSession; @@ -18,9 +19,9 @@ import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; -@SuppressWarnings("serial") -public class DefinedMavenForm extends FormLayout { - private DefinedMaven definedMaven; +public class DefinedMavenForm extends FormLayout implements Serializable{ + private static final long serialVersionUID = 4172878715304331198L; + private transient DefinedMaven definedMaven; private TextField definedUrl = new TextField(); private Label caption = new Label("Defined Maven repository"); private TextField group = new TextField("Group Id"); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LoadFileForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LoadFileForm.java index 02acdc76..c7bd0af4 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LoadFileForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LoadFileForm.java @@ -5,6 +5,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.nio.charset.Charset; import java.nio.file.Files; import com.vaadin.server.Page; import com.vaadin.shared.Position; @@ -59,7 +60,7 @@ public void uploadSucceeded(SucceededEvent event) { notif.show(Page.getCurrent()); try { area.setCaption("Content of File " + file.getName()); - area.setValue(new String(Files.readAllBytes(file.toPath()))); + area.setValue(new String(Files.readAllBytes(file.toPath()),Charset.forName("UTF-8"))); area.setVisible(true); area.setHeight("600px"); } catch (IOException e) { diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/DefinedMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/DefinedMaven.java index 6bf436b9..e3893004 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/DefinedMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/DefinedMaven.java @@ -25,7 +25,7 @@ import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; -public class DefinedMaven { +public class DefinedMaven{ private Tree definedMavenTree = new Tree("Result Search"); private String groupText; private String artifactText; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/LocalMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/LocalMaven.java index fda0abd9..a622bcbe 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/LocalMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/LocalMaven.java @@ -1,13 +1,16 @@ package cz.zcu.kiv.crce.crce_webui_vaadin.classes; import java.io.File; +import java.io.Serializable; + import com.vaadin.server.FontAwesome; import com.vaadin.server.VaadinSession; import com.vaadin.ui.Tree; import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; -public class LocalMaven { +public class LocalMaven implements Serializable{ + private static final long serialVersionUID = 1928618487572353592L; private Tree localMavenTree = new Tree(); private String path;// = System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository"; public Tree getTree(VaadinSession session) { @@ -33,7 +36,7 @@ public Tree getTree(VaadinSession session) { private void list(File file) { File[] children = file.listFiles(); for (File child : children) { - if ((child.isDirectory()) && (child.getName().charAt(0) != '.')) { + if (child.isDirectory() && child.getName().charAt(0) != '.') { localMavenTree.addItem(child.getAbsolutePath()); localMavenTree.setItemCaption(child.getAbsolutePath(), child.getName()); localMavenTree.setParent(child.getAbsolutePath(), child.getParentFile().getAbsolutePath()); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/internal/Activator.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/internal/Activator.java new file mode 100644 index 00000000..9811c7c2 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/internal/Activator.java @@ -0,0 +1,166 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.internal; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Nonnull; +import javax.servlet.http.HttpServletRequest; + +import org.apache.felix.dm.DependencyActivatorBase; +import org.apache.felix.dm.DependencyManager; +import org.osgi.framework.BundleContext; +import org.osgi.service.blueprint.container.ServiceUnavailableException; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cz.zcu.kiv.crce.compatibility.service.CompatibilitySearchService; +import cz.zcu.kiv.crce.metadata.MetadataFactory; +import cz.zcu.kiv.crce.metadata.dao.ResourceDAO; +import cz.zcu.kiv.crce.metadata.service.MetadataService; +import cz.zcu.kiv.crce.plugin.PluginManager; +import cz.zcu.kiv.crce.repository.Buffer; +import cz.zcu.kiv.crce.repository.SessionRegister; +import cz.zcu.kiv.crce.repository.Store; + +public class Activator extends DependencyActivatorBase{ + + private static final Logger logger = LoggerFactory.getLogger(Activator.class); + + private static volatile Activator instance; + + private volatile BundleContext bundleContext; + private volatile MetadataFactory metadataFactory; + private volatile ResourceDAO resourceDAO; + private volatile PluginManager pluginManager; + private volatile SessionRegister sessionRegister; + private volatile MetadataService metadataService; + private volatile CompatibilitySearchService compatibilityService; + + public static Activator instance() { + if (instance == null) { + throw new IllegalStateException("Activator instance is null."); + } + return instance; + } + + public PluginManager getPluginManager() { + return pluginManager; + } + + public SessionRegister getSessionRegister() { + if (sessionRegister == null) { + throw new IllegalStateException("sessionRegister is null."); + } + return sessionRegister; + } + + public ResourceDAO getResourceDAO() { + return resourceDAO; + } + + public MetadataFactory getMetadataFactory() { + return metadataFactory; + } + + @Nonnull + public Map getRepositories() { + Map stores = new HashMap<>(); + + Collection> serviceReferences; + try { + serviceReferences = bundleContext.getServiceReferences(Store.class, null); + } catch (InvalidSyntaxException e) { + logger.error("Invalid filter.", e); // this should not happen + return stores; + } + + if (serviceReferences == null) { + logger.trace("No stores found."); + return stores; + } + + for (ServiceReference serviceReference : serviceReferences) { + String id = (String) serviceReference.getProperty("id"); + String name = (String) serviceReference.getProperty("name"); + if (id != null) { + stores.put(id, name != null ? name : id); + } + } + + return stores; + } + + public Store getStore(String repositoryId) { + String filter = "(id=" + repositoryId + ")"; + + Collection> serviceReferences; + try { + serviceReferences = bundleContext.getServiceReferences(Store.class, filter); + } catch (InvalidSyntaxException ex) { + logger.error("Invalid filter: " + filter); + return null; + } + + if (serviceReferences == null || serviceReferences.isEmpty()) { + logger.warn("Store not found for repository ID: {}", repositoryId); + return null; + } + + if (serviceReferences.size() > 1) { + logger.warn("More than one stores found for repository ID: {}, using the first one.", repositoryId); + } + + return bundleContext.getService(serviceReferences.iterator().next()); + } + + public CompatibilitySearchService getCompatibilityService() { + if(compatibilityService != null) { + return compatibilityService; + } else { + throw new ServiceUnavailableException("This installation does not support compatibility services!", ""); + } + } + + public boolean isCompatibilityServicePresent() { + return compatibilityService != null; + } + + public Buffer getBuffer(HttpServletRequest req) { + if (req == null) { + return null; + } + + String sid = req.getSession(true).getId(); + return sessionRegister.getSessionData(sid).getBuffer(); + } + + public MetadataService getMetadataService() { + return metadataService; + } + + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "Workaround for providing DM components.") + @Override + public void init(BundleContext context, DependencyManager manager) throws Exception { + instance = this; + + manager.add(createComponent() + .setImplementation(this) + .add(createServiceDependency().setService(SessionRegister.class).setRequired(true)) + .add(createServiceDependency().setService(PluginManager.class).setRequired(true)) + .add(createServiceDependency().setService(MetadataFactory.class).setRequired(true)) + .add(createServiceDependency().setService(MetadataService.class).setRequired(true)) + .add(createServiceDependency().setService(CompatibilitySearchService.class).setRequired(false)) + ); + + + logger.debug("WebUI activator initialized."); + } + + @Override + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + // nothing to do + } +} diff --git a/modules/crce-webui/.classpath b/modules/crce-webui/.classpath new file mode 100644 index 00000000..23e05000 --- /dev/null +++ b/modules/crce-webui/.classpath @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-webui/.project b/modules/crce-webui/.project new file mode 100644 index 00000000..fbed2b06 --- /dev/null +++ b/modules/crce-webui/.project @@ -0,0 +1,44 @@ + + + crce-webui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.jboss.tools.ws.jaxrs.metamodelBuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.jsdt.core.jsNature + org.jboss.tools.ws.jaxrs.nature + + From 8e5e0bde0da3562bb802705352ce32754dac4310 Mon Sep 17 00:00:00 2001 From: rpesek Date: Mon, 26 Jun 2017 10:20:03 +0200 Subject: [PATCH 03/85] Stable assembly (minor adjustments ) Clean pax runner, Upgrading of Vaadin version at 7.7.10, Aktivator addition (storage integration) --- modules/crce-compatibility-api/.classpath | 6 +-- modules/crce-metadata-osgi-bundle/.classpath | 6 +-- modules/crce-vo/.classpath | 6 +-- modules/crce-webui-vaadin/pom.xml | 48 +++---------------- .../kiv/crce/crce_webui_vaadin/MenuForm.java | 4 +- .../zcu/kiv/crce/crce_webui_vaadin/MyUI.java | 11 +++++ .../repository/PluginsForm.java | 24 ++++++++++ .../{ => resources}/CentralMavenForm.java | 2 +- .../{ => resources}/DefinedMavenForm.java | 2 +- .../{ => resources}/LoadFileForm.java | 2 +- .../{ => resources}/LocalMavenForm.java | 2 +- modules/provision/pom.xml | 2 +- 12 files changed, 58 insertions(+), 57 deletions(-) create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{ => resources}/CentralMavenForm.java (98%) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{ => resources}/DefinedMavenForm.java (98%) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{ => resources}/LoadFileForm.java (97%) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{ => resources}/LocalMavenForm.java (95%) diff --git a/modules/crce-compatibility-api/.classpath b/modules/crce-compatibility-api/.classpath index 303bafb0..da3f7efb 100644 --- a/modules/crce-compatibility-api/.classpath +++ b/modules/crce-compatibility-api/.classpath @@ -17,15 +17,15 @@ - + - - + + diff --git a/modules/crce-metadata-osgi-bundle/.classpath b/modules/crce-metadata-osgi-bundle/.classpath index faa90026..a6731491 100644 --- a/modules/crce-metadata-osgi-bundle/.classpath +++ b/modules/crce-metadata-osgi-bundle/.classpath @@ -12,15 +12,15 @@ - + - - + + diff --git a/modules/crce-vo/.classpath b/modules/crce-vo/.classpath index 303bafb0..da3f7efb 100644 --- a/modules/crce-vo/.classpath +++ b/modules/crce-vo/.classpath @@ -17,15 +17,15 @@ - + - - + + diff --git a/modules/crce-webui-vaadin/pom.xml b/modules/crce-webui-vaadin/pom.xml index 8c462eb1..5b6eabe0 100644 --- a/modules/crce-webui-vaadin/pom.xml +++ b/modules/crce-webui-vaadin/pom.xml @@ -20,8 +20,8 @@ CRCE - Web UI (Vaadin) ${namespace}.crce_webui_vaadin - 7.7.7 - 7.7.7 + 7.7.10 + 7.7.10 9.3.9.v20160517 UTF-8 1.8 @@ -176,7 +176,6 @@ WEB-INF/classes/VAADIN/widgetsets/WEB-INF/** ${project.build.directory}/META-INF/MANIFEST.MF - WEB-INF/classes @@ -216,36 +215,6 @@ - - - - org.apache.felix maven-bundle-plugin @@ -286,13 +255,11 @@ WEB-INF/lib/aether-util-1.1.0.jar, WEB-INF/lib/atmosphere-runtime-2.2.9.vaadin2.jar, WEB-INF/lib/commons-codec-1.6.jar, - WEB-INF/lib/commons-lang3-3.4.jar, WEB-INF/lib/crce-external-repository-1.0.jar, WEB-INF/lib/flute-1.3.0.gg2.jar, WEB-INF/lib/guava-18.0.jar, WEB-INF/lib/httpclient-4.3.5.jar, WEB-INF/lib/httpcore-4.3.2.jar, - WEB-INF/lib/jcl-over-slf4j-1.6.2.jar, WEB-INF/lib/jsoup-1.8.3.jar, WEB-INF/lib/maven-aether-provider-3.3.9.jar, WEB-INF/lib/maven-artifact-3.3.9.jar, @@ -304,15 +271,14 @@ WEB-INF/lib/plexus-interpolation-1.21.jar, WEB-INF/lib/plexus-utils-3.0.22.jar, WEB-INF/lib/sac-1.3.jar, - WEB-INF/lib/slf4j-api-1.7.22.jar, WEB-INF/lib/slf4j-simple-1.7.22.jar, - WEB-INF/lib/vaadin-client-compiled-7.7.7.jar, - WEB-INF/lib/vaadin-push-7.7.7.jar, + WEB-INF/lib/vaadin-client-compiled-7.7.10.jar, + WEB-INF/lib/vaadin-push-7.7.10.jar, WEB-INF/lib/vaadin-sass-compiler-0.9.13.jar, - WEB-INF/lib/vaadin-server-7.7.7.jar, - WEB-INF/lib/vaadin-shared-7.7.7.jar, + WEB-INF/lib/vaadin-server-7.7.10.jar, + WEB-INF/lib/vaadin-shared-7.7.10.jar, WEB-INF/lib/vaadin-slf4j-jdk14-1.6.1.jar, - WEB-INF/lib/vaadin-themes-7.7.7.jar + WEB-INF/lib/vaadin-themes-7.7.10.jar crce-vaadin crce-vaadin diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MenuForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MenuForm.java index f7c9c5f4..5ff6ebbc 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MenuForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MenuForm.java @@ -28,10 +28,10 @@ public MenuForm(MyUI myUI) { upload.addItem("File", e ->{myUI.setContentBodyLoadFile();}); // submenu repository - repository.addItem("Refresh", null); + repository.addItem("Plugins", e ->{myUI.setContentBodyPlugins();}); // submenu settings - settings.addItem("Repository", e ->{myUI.setContentSettings();}); + settings.addItem("Paths", e ->{myUI.setContentSettings();}); headHL.addComponents(logo,menu); headHL.setComponentAlignment(menu,Alignment.MIDDLE_LEFT); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MyUI.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MyUI.java index f8ceb659..c45f5cfc 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MyUI.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MyUI.java @@ -9,6 +9,12 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.PluginsForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.resources.CentralMavenForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.resources.DefinedMavenForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.resources.LoadFileForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.resources.LocalMavenForm; + /** * This UI is the application entry point. A UI may either represent a browser window * (or tab) or some part of a html page where a Vaadin application is embedded. @@ -25,6 +31,7 @@ public class MyUI extends UI { private LocalMavenForm localMavenForm = new LocalMavenForm(); private CentralMavenForm centralMavenForm = new CentralMavenForm(); private DefinedMavenForm definedMavenForm = new DefinedMavenForm(); + private PluginsForm pluginsForm = new PluginsForm(); private SettingsForm settingsForm = new SettingsForm(); @@ -72,6 +79,10 @@ public void setContentBodyLoadFile(){ body.setContent(loadFileForm); } + public void setContentBodyPlugins(){ + body.setContent(pluginsForm); + } + public void setContentSettings(){ settingsForm = new SettingsForm(this.getSession()); body.setContent(settingsForm); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java new file mode 100644 index 00000000..c110e9ce --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java @@ -0,0 +1,24 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.repository; + +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; + +@SuppressWarnings("serial") +public class PluginsForm extends FormLayout{ + private Label text = new Label(); + public PluginsForm(){ + VerticalLayout userForm = new VerticalLayout(); + HorizontalLayout content = new HorizontalLayout(); + text.setValue("Pokus"); + userForm.addComponent(text); + + userForm.setSpacing(true); + userForm.setMargin(new MarginInfo(false, true)); + content.addComponent(userForm); + content.setSpacing(true); + addComponent(content); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/CentralMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/CentralMavenForm.java similarity index 98% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/CentralMavenForm.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/CentralMavenForm.java index 10338753..f48b00bb 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/CentralMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/CentralMavenForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin; +package cz.zcu.kiv.crce.crce_webui_vaadin.resources; import java.util.EnumSet; import com.vaadin.event.ShortcutAction.KeyCode; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/DefinedMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/DefinedMavenForm.java similarity index 98% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/DefinedMavenForm.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/DefinedMavenForm.java index a95fa43c..3d6ffb45 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/DefinedMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/DefinedMavenForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin; +package cz.zcu.kiv.crce.crce_webui_vaadin.resources; import java.io.Serializable; import java.util.EnumSet; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LoadFileForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LoadFileForm.java similarity index 97% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LoadFileForm.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LoadFileForm.java index c7bd0af4..424ac0a7 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LoadFileForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LoadFileForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin; +package cz.zcu.kiv.crce.crce_webui_vaadin.resources; import java.io.File; import java.io.FileNotFoundException; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LocalMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LocalMavenForm.java similarity index 95% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LocalMavenForm.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LocalMavenForm.java index 733cec45..543a6dc3 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LocalMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LocalMavenForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin; +package cz.zcu.kiv.crce.crce_webui_vaadin.resources; import com.vaadin.server.VaadinSession; import com.vaadin.shared.ui.MarginInfo; diff --git a/modules/provision/pom.xml b/modules/provision/pom.xml index f8e848b0..ad5df4d5 100644 --- a/modules/provision/pom.xml +++ b/modules/provision/pom.xml @@ -18,7 +18,7 @@ pom - + From 039605d46ee8b0d350f78f7aa3e59d300ae45691 Mon Sep 17 00:00:00 2001 From: rpesek Date: Wed, 12 Jul 2017 10:59:55 +0200 Subject: [PATCH 04/85] Repository UI (pluginForm, creation bufferForm) Basic development of form plugins, store, buffer. Fix holding session --- .../crce_webui_vaadin/internal/Activator.java | 276 +++++++++--------- .../repository/BufferForm.java | 47 +++ .../repository/PluginsForm.java | 41 ++- .../repository/StoreForm.java | 10 + .../crce_webui_vaadin/webui/AboutForm.java | 20 ++ .../crce_webui_vaadin/webui/LoginForm.java | 67 +++++ .../{ => webui}/LogoBackground.java | 6 +- .../{ => webui}/MenuForm.java | 29 +- .../crce_webui_vaadin/{ => webui}/MyUI.java | 90 ++++-- .../{ => webui}/SettingsForm.java | 2 +- .../webapp/VAADIN/themes/mytheme/mytheme.scss | 5 + .../src/main/webapp/WEB-INF/web.xml | 2 +- 12 files changed, 421 insertions(+), 174 deletions(-) create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/StoreForm.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/AboutForm.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LoginForm.java rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{ => webui}/LogoBackground.java (69%) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{ => webui}/MenuForm.java (59%) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{ => webui}/MyUI.java (57%) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{ => webui}/SettingsForm.java (98%) diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/internal/Activator.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/internal/Activator.java index 9811c7c2..6da3f1f9 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/internal/Activator.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/internal/Activator.java @@ -5,7 +5,6 @@ import java.util.Map; import javax.annotation.Nonnull; -import javax.servlet.http.HttpServletRequest; import org.apache.felix.dm.DependencyActivatorBase; import org.apache.felix.dm.DependencyManager; @@ -16,6 +15,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.vaadin.server.WrappedSession; + import cz.zcu.kiv.crce.compatibility.service.CompatibilitySearchService; import cz.zcu.kiv.crce.metadata.MetadataFactory; import cz.zcu.kiv.crce.metadata.dao.ResourceDAO; @@ -25,142 +26,147 @@ import cz.zcu.kiv.crce.repository.SessionRegister; import cz.zcu.kiv.crce.repository.Store; -public class Activator extends DependencyActivatorBase{ - +public class Activator extends DependencyActivatorBase { + private static final Logger logger = LoggerFactory.getLogger(Activator.class); - + private static volatile Activator instance; - + private volatile BundleContext bundleContext; - private volatile MetadataFactory metadataFactory; - private volatile ResourceDAO resourceDAO; - private volatile PluginManager pluginManager; - private volatile SessionRegister sessionRegister; - private volatile MetadataService metadataService; - private volatile CompatibilitySearchService compatibilityService; - + private volatile MetadataFactory metadataFactory; + private volatile ResourceDAO resourceDAO; + private volatile PluginManager pluginManager; + private volatile SessionRegister sessionRegister; + private volatile MetadataService metadataService; + private volatile CompatibilitySearchService compatibilityService; + public static Activator instance() { - if (instance == null) { - throw new IllegalStateException("Activator instance is null."); - } - return instance; - } - - public PluginManager getPluginManager() { - return pluginManager; - } - - public SessionRegister getSessionRegister() { - if (sessionRegister == null) { - throw new IllegalStateException("sessionRegister is null."); - } - return sessionRegister; - } - - public ResourceDAO getResourceDAO() { - return resourceDAO; - } - - public MetadataFactory getMetadataFactory() { - return metadataFactory; - } - - @Nonnull - public Map getRepositories() { - Map stores = new HashMap<>(); - - Collection> serviceReferences; - try { - serviceReferences = bundleContext.getServiceReferences(Store.class, null); - } catch (InvalidSyntaxException e) { - logger.error("Invalid filter.", e); // this should not happen - return stores; - } - - if (serviceReferences == null) { - logger.trace("No stores found."); - return stores; - } - - for (ServiceReference serviceReference : serviceReferences) { - String id = (String) serviceReference.getProperty("id"); - String name = (String) serviceReference.getProperty("name"); - if (id != null) { - stores.put(id, name != null ? name : id); - } - } - - return stores; - } - - public Store getStore(String repositoryId) { - String filter = "(id=" + repositoryId + ")"; - - Collection> serviceReferences; - try { - serviceReferences = bundleContext.getServiceReferences(Store.class, filter); - } catch (InvalidSyntaxException ex) { - logger.error("Invalid filter: " + filter); - return null; - } - - if (serviceReferences == null || serviceReferences.isEmpty()) { - logger.warn("Store not found for repository ID: {}", repositoryId); - return null; - } - - if (serviceReferences.size() > 1) { - logger.warn("More than one stores found for repository ID: {}, using the first one.", repositoryId); - } - - return bundleContext.getService(serviceReferences.iterator().next()); - } - - public CompatibilitySearchService getCompatibilityService() { - if(compatibilityService != null) { - return compatibilityService; - } else { - throw new ServiceUnavailableException("This installation does not support compatibility services!", ""); - } - } - - public boolean isCompatibilityServicePresent() { - return compatibilityService != null; - } - - public Buffer getBuffer(HttpServletRequest req) { - if (req == null) { - return null; - } - - String sid = req.getSession(true).getId(); - return sessionRegister.getSessionData(sid).getBuffer(); - } - - public MetadataService getMetadataService() { - return metadataService; - } - - @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "Workaround for providing DM components.") - @Override - public void init(BundleContext context, DependencyManager manager) throws Exception { - instance = this; - - manager.add(createComponent() - .setImplementation(this) - .add(createServiceDependency().setService(SessionRegister.class).setRequired(true)) - .add(createServiceDependency().setService(PluginManager.class).setRequired(true)) - .add(createServiceDependency().setService(MetadataFactory.class).setRequired(true)) - .add(createServiceDependency().setService(MetadataService.class).setRequired(true)) - .add(createServiceDependency().setService(CompatibilitySearchService.class).setRequired(false)) - ); - - - logger.debug("WebUI activator initialized."); - } - - @Override - public void destroy(BundleContext context, DependencyManager manager) throws Exception { - // nothing to do - } + if (instance == null) { + throw new IllegalStateException("Activator instance is null."); + } + return instance; + } + + public PluginManager getPluginManager() { + return pluginManager; + } + + public SessionRegister getSessionRegister() { + if (sessionRegister == null) { + throw new IllegalStateException("sessionRegister is null."); + } + return sessionRegister; + } + + public ResourceDAO getResourceDAO() { + return resourceDAO; + } + + public MetadataFactory getMetadataFactory() { + return metadataFactory; + } + + @Nonnull + public Map getRepositories() { + Map stores = new HashMap<>(); + + Collection> serviceReferences; + try { + serviceReferences = bundleContext.getServiceReferences(Store.class, null); + } catch (InvalidSyntaxException e) { + logger.error("Invalid filter.", e); // this should not happen + return stores; + } + + if (serviceReferences == null) { + logger.trace("No stores found."); + return stores; + } + + for (ServiceReference serviceReference : serviceReferences) { + String id = (String) serviceReference.getProperty("id"); + String name = (String) serviceReference.getProperty("name"); + if (id != null) { + stores.put(id, name != null ? name : id); + } + } + + return stores; + } + + public Store getStore(String repositoryId) { + String filter = "(id=" + repositoryId + ")"; + + Collection> serviceReferences; + try { + serviceReferences = bundleContext.getServiceReferences(Store.class, filter); + } catch (InvalidSyntaxException ex) { + logger.error("Invalid filter: " + filter); + return null; + } + + if (serviceReferences == null || serviceReferences.isEmpty()) { + logger.warn("Store not found for repository ID: {}", repositoryId); + return null; + } + + if (serviceReferences.size() > 1) { + logger.warn("More than one stores found for repository ID: {}, using the first one.", repositoryId); + } + + return bundleContext.getService(serviceReferences.iterator().next()); + } + + public CompatibilitySearchService getCompatibilityService() { + if (compatibilityService != null) { + return compatibilityService; + } else { + throw new ServiceUnavailableException("This installation does not support compatibility services!", ""); + } + } + + public boolean isCompatibilityServicePresent() { + return compatibilityService != null; + } + + public Buffer getBuffer(WrappedSession wSes) { + if (wSes == null) { + return null; + } + + String sid = wSes.getId(); + return sessionRegister.getSessionData(sid).getBuffer(); + } + + /* + * public Buffer getBuffer(HttpServletRequest req) { if (req == null) { + * return null; } + * + * String sid = req.getSession(true).getId(); return + * sessionRegister.getSessionData(sid).getBuffer(); } + */ + + public MetadataService getMetadataService() { + return metadataService; + } + + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "Workaround for providing DM components.") + @Override + public void init(BundleContext context, DependencyManager manager) throws Exception { + instance = this; + + manager.add(createComponent().setImplementation(this) + .add(createServiceDependency().setService(SessionRegister.class).setRequired(true)) + .add(createServiceDependency().setService(PluginManager.class).setRequired(true)) + .add(createServiceDependency().setService(MetadataFactory.class).setRequired(true)) + .add(createServiceDependency().setService(MetadataService.class).setRequired(true)) + .add(createServiceDependency().setService(CompatibilitySearchService.class).setRequired(false))); + + logger.debug("WebUI activator initialized."); + } + + @Override + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + // nothing to do + } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java new file mode 100644 index 00000000..29fa0fb7 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java @@ -0,0 +1,47 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.repository; + +import com.vaadin.data.util.BeanItemContainer; +import com.vaadin.server.VaadinSession; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Grid; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.repository.Buffer; + +@SuppressWarnings("serial") +public class BufferForm extends FormLayout{ + private Label labelForm = new Label("Artefact in Buffer"); + private Grid gridBuffer = new Grid(); + private HorizontalLayout formLayout; + + public BufferForm(VaadinSession session){ + VerticalLayout content = new VerticalLayout(); + VerticalLayout fieldLayout = new VerticalLayout(); + + labelForm.addStyleName(ValoTheme.LABEL_BOLD); + + Buffer buffer = Activator.instance().getBuffer(session.getSession()); + + gridBuffer.setContainerDataSource(new BeanItemContainer<>(Resource.class, buffer.getResources())); + gridBuffer.addStyleName("my-style"); + + fieldLayout.addComponents(labelForm, gridBuffer); + fieldLayout.setSpacing(true); + + formLayout = new HorizontalLayout(fieldLayout); + formLayout.setSizeFull(); + gridBuffer.setSizeFull(); + formLayout.setExpandRatio(fieldLayout, 1); + + content.addComponent(formLayout); + content.setMargin(new MarginInfo(false, true)); + content.setSpacing(true); + addComponent(content); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java index c110e9ce..44f5430c 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java @@ -1,23 +1,48 @@ package cz.zcu.kiv.crce.crce_webui_vaadin.repository; +import com.vaadin.data.util.BeanItemContainer; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Grid; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; +import cz.zcu.kiv.crce.plugin.Plugin; @SuppressWarnings("serial") public class PluginsForm extends FormLayout{ - private Label text = new Label(); + private Label labelForm = new Label("Plugins"); + private Grid gridPlugins = new Grid(); + private HorizontalLayout formLayout; + public PluginsForm(){ - VerticalLayout userForm = new VerticalLayout(); - HorizontalLayout content = new HorizontalLayout(); - text.setValue("Pokus"); - userForm.addComponent(text); + VerticalLayout content = new VerticalLayout(); + VerticalLayout fieldLayout = new VerticalLayout(); + + labelForm.addStyleName(ValoTheme.LABEL_BOLD); + + gridPlugins.setContainerDataSource(new BeanItemContainer<>(Plugin.class, Activator.instance().getPluginManager().getPlugins())); + gridPlugins.getColumn("pluginKeywords").setHidden(true); + gridPlugins.getColumn("pluginId").setHidable(true); + gridPlugins.getColumn("pluginDescription").setHidable(true); + gridPlugins.getColumn("pluginPriority").setHidable(true); + gridPlugins.getColumn("pluginVersion").setHidable(true); + gridPlugins.setColumnOrder("pluginId", "pluginDescription"); + gridPlugins.addStyleName("my-style"); + + fieldLayout.addComponents(labelForm, gridPlugins); + fieldLayout.setSpacing(true); + + formLayout = new HorizontalLayout(fieldLayout); + formLayout.setSizeFull(); + gridPlugins.setSizeFull(); + formLayout.setExpandRatio(fieldLayout, 1); - userForm.setSpacing(true); - userForm.setMargin(new MarginInfo(false, true)); - content.addComponent(userForm); + content.addComponent(formLayout); + content.setMargin(new MarginInfo(false, true)); content.setSpacing(true); addComponent(content); } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/StoreForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/StoreForm.java new file mode 100644 index 00000000..02caa82d --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/StoreForm.java @@ -0,0 +1,10 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.repository; + +import com.vaadin.ui.FormLayout; + +@SuppressWarnings("serial") +public class StoreForm extends FormLayout{ + public StoreForm(){ + + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/AboutForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/AboutForm.java new file mode 100644 index 00000000..5b185de8 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/AboutForm.java @@ -0,0 +1,20 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.webui; + +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; + +@SuppressWarnings("serial") +public class AboutForm extends FormLayout{ + public AboutForm(){ + VerticalLayout content = new VerticalLayout(); + Label about = new Label("

University of West Bohemia, " + + "ReliSA research group, Version: 1.0, Build revision: 2.0

", ContentMode.HTML); + content.setSpacing(false); + content.setMargin(false); + content.addComponent(about); + addComponent(content); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LoginForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LoginForm.java new file mode 100644 index 00000000..175750cd --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LoginForm.java @@ -0,0 +1,67 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.webui; + +import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Panel; +import com.vaadin.ui.PasswordField; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +@SuppressWarnings("serial") +public class LoginForm extends FormLayout{ + private Panel panel = new Panel("CRCE - Signing in"); + private TextField login = new TextField("Name"); + private PasswordField password = new PasswordField("Password"); + private Button loginButton = new Button("Log in"); + private Label error = new Label(); + private HorizontalLayout loginFormLayout = new HorizontalLayout(); + private HorizontalLayout submitErrorLayout = new HorizontalLayout(); + private VerticalLayout panelLayout = new VerticalLayout(); + private VerticalLayout content = new VerticalLayout(); + + public LoginForm(MyUI myUI) { + + loginButton.setStyleName(ValoTheme.BUTTON_PRIMARY); + loginButton.setClickShortcut(KeyCode.ENTER); + + login.setWidth("220px"); + password.setWidth("220px"); + + loginFormLayout.addComponents(login, password); + loginFormLayout.setSpacing(true); + + submitErrorLayout.addComponents(loginButton, error); + submitErrorLayout.setSpacing(true); + + panelLayout.addComponents(loginFormLayout, submitErrorLayout); + panelLayout.setMargin(new MarginInfo(true, true)); + panelLayout.setSpacing(true); + panel.setContent(panelLayout); + panel.setWidth("500px"); + panel.setHeight("200px"); + content.setSizeFull(); + content.addComponent(panel); + content.setComponentAlignment(panel, Alignment.MIDDLE_CENTER); + + loginButton.addClickListener(e -> { + + // kontrola vstupu např. volání služby apod. + // v případě neúspěchu doplnění error hlášky např: + /*submitErrorLayout.removeComponent(error); + error = new Label("

Incorrect login

", + ContentMode.HTML); + submitErrorLayout.addComponent(error);*/ + + // v případě úspěchu: + myUI.getSession().setAttribute("singed", login.getValue()); + myUI.loginExistSession(); + }); + addComponent(content); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LogoBackground.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LogoBackground.java similarity index 69% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LogoBackground.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LogoBackground.java index 33c5173b..fc4b0243 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/LogoBackground.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LogoBackground.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin; +package cz.zcu.kiv.crce.crce_webui_vaadin.webui; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.FormLayout; @@ -7,8 +7,8 @@ @SuppressWarnings("serial") public class LogoBackground extends FormLayout{ public LogoBackground(){ - Label logoBackground = new Label("

CRCE

",ContentMode.HTML); + Label logoBackground = new Label("

CRCE

",ContentMode.HTML); addComponent(logoBackground); } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MenuForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java similarity index 59% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MenuForm.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java index 5ff6ebbc..4c0aabd9 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MenuForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java @@ -1,6 +1,7 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin; +package cz.zcu.kiv.crce.crce_webui_vaadin.webui; import com.vaadin.annotations.StyleSheet; +import com.vaadin.shared.ui.MarginInfo; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.FormLayout; @@ -14,6 +15,7 @@ public class MenuForm extends FormLayout{ public MenuForm(MyUI myUI) { HorizontalLayout headHL = new HorizontalLayout(); + HorizontalLayout menuHL = new HorizontalLayout(); Label logo = new Label("

CRCE UI

",ContentMode.HTML); MenuBar menu = new MenuBar(); @@ -28,15 +30,34 @@ public MenuForm(MyUI myUI) { upload.addItem("File", e ->{myUI.setContentBodyLoadFile();}); // submenu repository + repository.addItem("Buffer", e ->{myUI.setContentBodyBuffer();}); + repository.addItem("Store", null); repository.addItem("Plugins", e ->{myUI.setContentBodyPlugins();}); // submenu settings settings.addItem("Paths", e ->{myUI.setContentSettings();}); - headHL.addComponents(logo,menu); - headHL.setComponentAlignment(menu,Alignment.MIDDLE_LEFT); + // Menu login + MenuBar menuLogin = new MenuBar(); + MenuItem menuItemLogin = menuLogin.addItem(myUI.getSession().getAttribute("singed").toString(), null); + menuItemLogin.addItem("Logout", e ->{ + myUI.getSession().setAttribute("singed", null); + myUI.logout(); + }); + + menuHL.addComponents(logo, menu); + menuHL.setComponentAlignment(menu, Alignment.MIDDLE_LEFT); + menuHL.setSpacing(true); + + headHL.addComponents(menuHL, menuLogin); + //Alignment.BOTTOM_RIGHT + headHL.setComponentAlignment(menuHL,Alignment.MIDDLE_LEFT); + headHL.setComponentAlignment(menuLogin,Alignment.MIDDLE_RIGHT); + headHL.setSizeFull(); + + //headHL.setSpacing(true); + headHL.setMargin(new MarginInfo(false,true,false,false)); headHL.setSpacing(true); - headHL.setMargin(false); addComponent(headHL); } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MyUI.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java similarity index 57% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MyUI.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java index c45f5cfc..df32783e 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/MyUI.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java @@ -1,6 +1,7 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin; +package cz.zcu.kiv.crce.crce_webui_vaadin.webui; import javax.servlet.annotation.WebServlet; + import com.vaadin.annotations.Theme; import com.vaadin.annotations.VaadinServletConfiguration; import com.vaadin.server.VaadinRequest; @@ -9,7 +10,9 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.BufferForm; import cz.zcu.kiv.crce.crce_webui_vaadin.repository.PluginsForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.StoreForm; import cz.zcu.kiv.crce.crce_webui_vaadin.resources.CentralMavenForm; import cz.zcu.kiv.crce.crce_webui_vaadin.resources.DefinedMavenForm; import cz.zcu.kiv.crce.crce_webui_vaadin.resources.LoadFileForm; @@ -25,61 +28,104 @@ @SuppressWarnings("serial") @Theme("mytheme") public class MyUI extends UI { - private MenuForm menu = new MenuForm(this); private Panel head = new Panel(); private Panel body = new Panel(); - private LocalMavenForm localMavenForm = new LocalMavenForm(); - private CentralMavenForm centralMavenForm = new CentralMavenForm(); - private DefinedMavenForm definedMavenForm = new DefinedMavenForm(); - private PluginsForm pluginsForm = new PluginsForm(); - private SettingsForm settingsForm = new SettingsForm(); - - - private LoadFileForm loadFileForm = new LoadFileForm(); + private Panel footer = new Panel(); + private LocalMavenForm localMavenForm; + private CentralMavenForm centralMavenForm; + private DefinedMavenForm definedMavenForm; + private LoadFileForm loadFileForm; + private BufferForm bufferForm; + private StoreForm storeForm; + private PluginsForm pluginsForm; + private SettingsForm settingsForm; private VerticalLayout content = new VerticalLayout(); @Override protected void init(VaadinRequest vaadinRequest) { - // menu components + if (getSession().getAttribute("singed") != null) { + loginExistSession(); + } else { + loginNoSession(); + } + } + + @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) + @VaadinServletConfiguration(ui = MyUI.class, productionMode = false) + public static class MyUIServlet extends VaadinServlet { + } + + public void loginExistSession() { + // menu components + MenuForm menu = new MenuForm(this); menu.setMargin(false); head.setContent(menu); - + // body components LogoBackground logoBackgroung = new LogoBackground(); body.setContent(logoBackgroung); + + // about component + AboutForm about = new AboutForm(); + about.setMargin(false); + footer.setContent(about); // content components content.setMargin(true); content.setSpacing(true); - content.addComponents(head,body); - setContent(content); - } + content.addComponents(head, body, footer); + setContent(content); + } + + public void loginNoSession(){ + LoginForm loginForm = new LoginForm(this); + setContent(loginForm); + } - @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) - @VaadinServletConfiguration(ui = MyUI.class, productionMode = false) - public static class MyUIServlet extends VaadinServlet { - } + public void logout() { + // clear component + LoginForm loginForm = new LoginForm(this); + cleanupAfterLogout(); + setContent(loginForm); + } + + private void cleanupAfterLogout(){ + getSession().setAttribute("settingsUrl", null); + content.removeAllComponents(); + } public void setContentBodyLocalMaven(){ - localMavenForm = new LocalMavenForm(this.getSession()); + localMavenForm = new LocalMavenForm(getSession()); body.setContent(localMavenForm); } public void setContentBodyCentralMaven(){ - centralMavenForm = new CentralMavenForm(this.getSession()); + centralMavenForm = new CentralMavenForm(getSession()); body.setContent(centralMavenForm); } public void setContentBodyDefinedMaven(){ - definedMavenForm = new DefinedMavenForm(this.getSession()); + definedMavenForm = new DefinedMavenForm(getSession()); body.setContent(definedMavenForm); } public void setContentBodyLoadFile(){ + loadFileForm = new LoadFileForm(); body.setContent(loadFileForm); } + public void setContentBodyBuffer(){ + bufferForm = new BufferForm(getSession()); + body.setContent(bufferForm); + } + + public void setContentBodyStore(){ + storeForm = new StoreForm(); + body.setContent(storeForm); + } + public void setContentBodyPlugins(){ + pluginsForm = new PluginsForm(); body.setContent(pluginsForm); } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/SettingsForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java similarity index 98% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/SettingsForm.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java index fe976def..b62102ad 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/SettingsForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin; +package cz.zcu.kiv.crce.crce_webui_vaadin.webui; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.server.Page; diff --git a/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss b/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss index 2c5fb8b9..d40ce75d 100644 --- a/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss +++ b/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss @@ -35,4 +35,9 @@ @include valo; // Insert your own theme rules here + + .my-style { + font-family: Verdana; + //font-weight: bold; + } } diff --git a/modules/crce-webui-vaadin/src/main/webapp/WEB-INF/web.xml b/modules/crce-webui-vaadin/src/main/webapp/WEB-INF/web.xml index 6c53635f..3116477f 100644 --- a/modules/crce-webui-vaadin/src/main/webapp/WEB-INF/web.xml +++ b/modules/crce-webui-vaadin/src/main/webapp/WEB-INF/web.xml @@ -12,7 +12,7 @@ MyUIServlet - cz.zcu.kiv.crce.crce_webui_vaadin.MyUI$MyUIServlet + cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI$MyUIServlet MyUIServlet From 4c6de4e1e788658404c1bd0c8411d2e46d796c6a Mon Sep 17 00:00:00 2001 From: rpesek Date: Tue, 8 Aug 2017 11:24:05 +0200 Subject: [PATCH 05/85] Merge modules (external and UI) implementations uploadind artefact into a buffer, a list of plugins Merging modules (external and UI) under the graphical environment Basic implementation of buffer upload UI plugin list --- core/crce-metadata-dao-api/.classpath | 2 +- core/crce-metadata-dao-impl/.classpath | 2 +- core/crce-repository-api/.classpath | 2 +- core/crce-repository-impl/.classpath | 2 +- core/crce-resolver-api/.classpath | 2 +- core/crce-resolver-impl/.classpath | 2 +- modules/crce-external-repository/.classpath | 37 -------- modules/crce-external-repository/.project | 49 ----------- modules/crce-external-repository/pom.xml | 62 ------------- .../crce/external/web/inf/InfSettingsUrl.java | 13 --- modules/crce-webui-vaadin/pom.xml | 23 ++--- .../crce/crce_webui_vaadin/other/KeyWord.java | 13 +++ .../crce_webui_vaadin/other/VersionInfo.java | 46 ++++++++++ .../repository/PluginFormEdit.java | 88 +++++++++++++++++++ .../repository/PluginsForm.java | 32 ++++++- .../resources/CentralMavenForm.java | 3 +- .../resources/DefinedMavenForm.java | 5 +- .../resources/LoadFileForm.java | 88 ++++++++++++++----- .../resources/LocalMavenForm.java | 3 +- .../{ => resources}/classes/CentralMaven.java | 3 +- .../{ => resources}/classes/DefinedMaven.java | 6 +- .../{ => resources}/classes/LocalMaven.java | 7 +- .../resources/classes}/SettingsUrl.java | 14 +-- .../crce_webui_vaadin/webui/AboutForm.java | 9 +- .../crce_webui_vaadin/webui/MenuForm.java | 2 +- .../crce/crce_webui_vaadin/webui/MyUI.java | 4 +- .../crce_webui_vaadin/webui/SettingsForm.java | 3 +- modules/pom.xml | 2 +- 28 files changed, 287 insertions(+), 237 deletions(-) delete mode 100644 modules/crce-external-repository/.classpath delete mode 100644 modules/crce-external-repository/.project delete mode 100644 modules/crce-external-repository/pom.xml delete mode 100644 modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/KeyWord.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/VersionInfo.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginFormEdit.java rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{ => resources}/classes/CentralMaven.java (96%) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{ => resources}/classes/DefinedMaven.java (98%) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{ => resources}/classes/LocalMaven.java (92%) rename modules/{crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/impl => crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes}/SettingsUrl.java (79%) diff --git a/core/crce-metadata-dao-api/.classpath b/core/crce-metadata-dao-api/.classpath index 7755c1a8..faa90026 100644 --- a/core/crce-metadata-dao-api/.classpath +++ b/core/crce-metadata-dao-api/.classpath @@ -20,7 +20,7 @@ - + diff --git a/core/crce-metadata-dao-impl/.classpath b/core/crce-metadata-dao-impl/.classpath index 8a297cd0..303bafb0 100644 --- a/core/crce-metadata-dao-impl/.classpath +++ b/core/crce-metadata-dao-impl/.classpath @@ -25,7 +25,7 @@ - + diff --git a/core/crce-repository-api/.classpath b/core/crce-repository-api/.classpath index 7755c1a8..faa90026 100644 --- a/core/crce-repository-api/.classpath +++ b/core/crce-repository-api/.classpath @@ -20,7 +20,7 @@ - + diff --git a/core/crce-repository-impl/.classpath b/core/crce-repository-impl/.classpath index 7755c1a8..faa90026 100644 --- a/core/crce-repository-impl/.classpath +++ b/core/crce-repository-impl/.classpath @@ -20,7 +20,7 @@ - + diff --git a/core/crce-resolver-api/.classpath b/core/crce-resolver-api/.classpath index 7755c1a8..faa90026 100644 --- a/core/crce-resolver-api/.classpath +++ b/core/crce-resolver-api/.classpath @@ -20,7 +20,7 @@ - + diff --git a/core/crce-resolver-impl/.classpath b/core/crce-resolver-impl/.classpath index 7755c1a8..faa90026 100644 --- a/core/crce-resolver-impl/.classpath +++ b/core/crce-resolver-impl/.classpath @@ -20,7 +20,7 @@ - + diff --git a/modules/crce-external-repository/.classpath b/modules/crce-external-repository/.classpath deleted file mode 100644 index 08d7a50f..00000000 --- a/modules/crce-external-repository/.classpath +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/crce-external-repository/.project b/modules/crce-external-repository/.project deleted file mode 100644 index 0d92023e..00000000 --- a/modules/crce-external-repository/.project +++ /dev/null @@ -1,49 +0,0 @@ - - - crce-external-repository - - - - - - org.eclipse.wst.common.project.facet.core.builder - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.jboss.tools.jst.web.kb.kbbuilder - - - - - org.jboss.tools.cdi.core.cdibuilder - - - - - org.eclipse.wst.validation.validationbuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jem.workbench.JavaEMFNature - org.eclipse.wst.common.modulecore.ModuleCoreNature - org.eclipse.pde.PluginNature - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - org.eclipse.wst.common.project.facet.core.nature - org.jboss.tools.jst.web.kb.kbnature - org.jboss.tools.cdi.core.cdinature - - diff --git a/modules/crce-external-repository/pom.xml b/modules/crce-external-repository/pom.xml deleted file mode 100644 index 81050fe7..00000000 --- a/modules/crce-external-repository/pom.xml +++ /dev/null @@ -1,62 +0,0 @@ - - 4.0.0 - - - ../pom - cz.zcu.kiv.crce - crce-modules-parent - 2.1.1-SNAPSHOT - - - crce-external-repository - 1.0 - - 1.8 - CRCE - External Repository Support - ${namespace}.crce_external_repository - - - - - - - maven-jar-plugin - 3.0.2 - - - ${project.build.directory}/META-INF/MANIFEST.MF - - - - - org.apache.felix - maven-bundle-plugin - - true - - - bundle-manifest - process-classes - - manifest - - - - - ${project.build.directory}/META-INF - - jar - bundle - - - * - cz.zcu.kiv.crce.external.web.impl - ${project.artifactId} - - - - - - CRCE - External Repository Support - \ No newline at end of file diff --git a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java deleted file mode 100644 index 7682c9f3..00000000 --- a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/inf/InfSettingsUrl.java +++ /dev/null @@ -1,13 +0,0 @@ -package cz.zcu.kiv.crce.external.web.inf; - -public interface InfSettingsUrl { - String getLocalMavenUrl(); - String getCentralMavenUrl(); - String getLocalAetherUrl(); - String getExternalAetherUrl(); - - void setLocalMavenUrl(String url); - void setCentralMavenUrl(String url); - void setLocalAetherUrl(String url); - void setExternalAetherUrl(String url); -} diff --git a/modules/crce-webui-vaadin/pom.xml b/modules/crce-webui-vaadin/pom.xml index 5b6eabe0..ae08db4a 100644 --- a/modules/crce-webui-vaadin/pom.xml +++ b/modules/crce-webui-vaadin/pom.xml @@ -138,9 +138,12 @@ slf4j-simple - cz.zcu.kiv.crce - crce-external-repository - 1.0 + org.apache.maven + maven-artifact + + + org.codehaus.plexus + plexus-utils cz.zcu.kiv.crce @@ -154,14 +157,6 @@ 2.1.1-SNAPSHOT bundle - - org.apache.maven - maven-artifact - - - org.codehaus.plexus - plexus-utils - @@ -239,10 +234,8 @@ * - - cz.zcu.kiv.crce.external.web.impl - - cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator + !${bundle.namespace}.internal.* + ${bundle.namespace}.internal.Activator ${project.artifactId} WEB-INF/classes, diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/KeyWord.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/KeyWord.java new file mode 100644 index 00000000..c5efeaa1 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/KeyWord.java @@ -0,0 +1,13 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.other; + +public class KeyWord { + private String keyWord; + + public KeyWord(String keyWord){ + this.keyWord = keyWord; + } + + public String getKeyWord() { + return keyWord; + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/VersionInfo.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/VersionInfo.java new file mode 100644 index 00000000..4721a6f7 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/VersionInfo.java @@ -0,0 +1,46 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.other; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.vaadin.server.VaadinServlet; + +public class VersionInfo { + private static final Logger logger = LoggerFactory.getLogger(VersionInfo.class); + + private static final String MANIFEST = "/META-INF/MANIFEST.MF"; + private static final String PRODUCT_VERSION = "Bundle-Version"; + private static final String IMPLEMENTATION_BUILD = "Implementation-Build"; + private static final String UNKNOWN = "unknown"; + + private static VersionInfo instance = null; + private String productVersion; + private String buildRevision; + + public static synchronized VersionInfo getVersionInfo() { + if (instance == null) { + instance = new VersionInfo(); + Properties properties = new Properties(); + try (InputStream stream + = VaadinServlet.getCurrent().getServletContext().getResourceAsStream(MANIFEST)) { + properties.load(stream); + instance.productVersion = properties.getProperty(PRODUCT_VERSION); + instance.buildRevision = properties.getProperty(IMPLEMENTATION_BUILD); + } catch (IOException e) { + logger.error("Could not read version info from Manifest.", e); + } + } + return instance; + } + public String getProductVersion() { + return productVersion != null ? productVersion : UNKNOWN; + } + + public String getBuildRevision() { + return buildRevision != null ? buildRevision : UNKNOWN; + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginFormEdit.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginFormEdit.java new file mode 100644 index 00000000..912c7349 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginFormEdit.java @@ -0,0 +1,88 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.repository; + +import java.util.ArrayList; + +import com.vaadin.data.util.BeanItemContainer; +import com.vaadin.data.validator.StringLengthValidator; +import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.ui.Button; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Grid; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +import cz.zcu.kiv.crce.crce_webui_vaadin.other.KeyWord; +import cz.zcu.kiv.crce.plugin.Plugin; + +@SuppressWarnings("serial") +public class PluginFormEdit extends FormLayout{ + private int nameMaxLenght = 45; + private Label labelKeyWords = new Label("Plugin key words"); + private Grid gridKeyWords = new Grid(); + private TextField priority = new TextField("Priority"); + private TextField version = new TextField("Version"); + private Button editButton = new Button("Edit"); + private Plugin plugin; + public PluginFormEdit(PluginsForm pluginsForm){ + HorizontalLayout content = new HorizontalLayout(); + VerticalLayout editLayout = new VerticalLayout(); + VerticalLayout keyWordLayout = new VerticalLayout(); + + setSizeUndefined(); + setMargin(false); + + labelKeyWords.addStyleName(ValoTheme.LABEL_BOLD); + keyWordLayout.addComponents(labelKeyWords, gridKeyWords); + keyWordLayout.setSpacing(true); + keyWordLayout.setVisible(false); + + gridKeyWords.setWidth("200px"); + gridKeyWords.addStyleName("my-style"); + + editButton.setStyleName(ValoTheme.BUTTON_PRIMARY); + editButton.setClickShortcut(KeyCode.ENTER); + + priority.setWidth("200px"); + priority.setRequired(true); + priority.setRequiredError("Item can not be empty!"); + priority.addValidator(new StringLengthValidator("Item must have " + nameMaxLenght + " characters!", 1, + nameMaxLenght, false)); + version.setWidth("200px"); + version.setRequired(true); + version.setRequiredError("Item can not be empty!"); + version.addValidator(new StringLengthValidator("Item must have " + nameMaxLenght + " characters!", 1, + nameMaxLenght, false)); + + editLayout.addComponents(priority, version, editButton); + editLayout.setSpacing(true); + + content.addComponents(keyWordLayout, editLayout); + content.setSpacing(true); + + editButton.addClickListener(e -> { + //TODO doplnit + + pluginsForm.update(); + }); + + addComponent(content); + } + + public void setPlugin(Plugin plugin) { + this.plugin = plugin; + if(!this.plugin.getPluginKeywords().isEmpty()){ + labelKeyWords.setVisible(true); + ArrayList keyWordList = new ArrayList(); + for(String s : this.plugin.getPluginKeywords()){ + keyWordList.add(new KeyWord(s)); + } + gridKeyWords.setContainerDataSource(new BeanItemContainer<>(KeyWord.class, keyWordList)); + } + priority.setValue(plugin.getPluginPriority() + ""); + version.setValue(plugin.getPluginVersion().toString()); + setVisible(true); + } +} \ No newline at end of file diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java index 44f5430c..9b08978f 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java @@ -10,15 +10,22 @@ import com.vaadin.ui.themes.ValoTheme; import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; import cz.zcu.kiv.crce.plugin.Plugin; @SuppressWarnings("serial") public class PluginsForm extends FormLayout{ private Label labelForm = new Label("Plugins"); private Grid gridPlugins = new Grid(); + private Grid gridKeyWords = new Grid(); + private PluginFormEdit pluginFormEdit; private HorizontalLayout formLayout; + private MyUI myUI; - public PluginsForm(){ + public PluginsForm(MyUI myUI){ + this.myUI = myUI; + pluginFormEdit = new PluginFormEdit(this); + VerticalLayout content = new VerticalLayout(); VerticalLayout fieldLayout = new VerticalLayout(); @@ -30,20 +37,39 @@ public PluginsForm(){ gridPlugins.getColumn("pluginDescription").setHidable(true); gridPlugins.getColumn("pluginPriority").setHidable(true); gridPlugins.getColumn("pluginVersion").setHidable(true); - gridPlugins.setColumnOrder("pluginId", "pluginDescription"); + gridPlugins.setColumnOrder("pluginId", "pluginDescription", "pluginKeywords"); gridPlugins.addStyleName("my-style"); + gridKeyWords.setWidth("200px"); + gridKeyWords.addStyleName("my-style"); + fieldLayout.addComponents(labelForm, gridPlugins); fieldLayout.setSpacing(true); - formLayout = new HorizontalLayout(fieldLayout); + formLayout = new HorizontalLayout(fieldLayout, pluginFormEdit); + formLayout.setSpacing(true); formLayout.setSizeFull(); gridPlugins.setSizeFull(); formLayout.setExpandRatio(fieldLayout, 1); + pluginFormEdit.setVisible(false); content.addComponent(formLayout); content.setMargin(new MarginInfo(false, true)); content.setSpacing(true); + + gridPlugins.addSelectionListener(e -> { + if (e.getSelected().isEmpty()) { + pluginFormEdit.setVisible(false); + } else { + Plugin plugin = (Plugin) e.getSelected().iterator().next(); + pluginFormEdit.setPlugin(plugin); + } + }); + addComponent(content); } + + public void update(){ + myUI.setContentBodyPlugins(); + } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/CentralMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/CentralMavenForm.java index f48b00bb..db259fda 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/CentralMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/CentralMavenForm.java @@ -13,8 +13,9 @@ import com.vaadin.ui.Tree; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; -import cz.zcu.kiv.crce.crce_webui_vaadin.classes.CentralMaven; + import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; +import cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes.CentralMaven; @SuppressWarnings("serial") public class CentralMavenForm extends FormLayout { diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/DefinedMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/DefinedMavenForm.java index 3d6ffb45..619d14cc 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/DefinedMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/DefinedMavenForm.java @@ -15,9 +15,10 @@ import com.vaadin.ui.Tree; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; -import cz.zcu.kiv.crce.crce_webui_vaadin.classes.DefinedMaven; + import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; -import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; +import cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes.DefinedMaven; +import cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes.SettingsUrl; public class DefinedMavenForm extends FormLayout implements Serializable{ private static final long serialVersionUID = 4172878715304331198L; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LoadFileForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LoadFileForm.java index 424ac0a7..d689265c 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LoadFileForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LoadFileForm.java @@ -4,42 +4,92 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; -import java.nio.charset.Charset; +import java.net.URL; import java.nio.file.Files; +import java.nio.file.StandardOpenOption; + import com.vaadin.server.Page; +import com.vaadin.server.VaadinSession; import com.vaadin.shared.Position; import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.Button; import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Notification; -import com.vaadin.ui.TextArea; +import com.vaadin.ui.Panel; +import com.vaadin.ui.TextField; import com.vaadin.ui.Upload; import com.vaadin.ui.Upload.Receiver; import com.vaadin.ui.Upload.SucceededEvent; import com.vaadin.ui.Upload.SucceededListener; import com.vaadin.ui.VerticalLayout; +import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; +import cz.zcu.kiv.crce.repository.Buffer; +import cz.zcu.kiv.crce.repository.RefusedArtifactException; + @SuppressWarnings("serial") public class LoadFileForm extends FormLayout { - final TextArea area = new TextArea(); - public LoadFileForm() { - FileUploader receiver = new FileUploader(); + private VaadinSession session; + private Panel filePanel = new Panel("Upload artefact from local file system"); + private Panel urlPanel = new Panel("Upload artefact from remote url"); + + public LoadFileForm(VaadinSession session){ + this.session = session; VerticalLayout content = new VerticalLayout(); + HorizontalLayout fileLayout = new HorizontalLayout(); + HorizontalLayout urlLayout = new HorizontalLayout(); + + FileUploader receiver = new FileUploader(); Upload upload = new Upload("Directly Upload File:", receiver); upload.setButtonCaption("Browse Files"); upload.addSucceededListener(receiver); upload.setImmediate(true); - area.setVisible(false); - area.setSizeFull(); - content.addComponents(upload, area); + + TextField urlText = new TextField(); + urlText.setWidth("400px"); + Button urlButton = new Button("Load"); + urlLayout.addComponents(urlText, urlButton); + urlLayout.setSpacing(true); + urlLayout.setMargin(true); + urlLayout.setHeight("100px"); + urlPanel.setContent(urlLayout); + + fileLayout.addComponent(upload); + fileLayout.setMargin(true); + fileLayout.setHeight("300px"); + filePanel.setContent(fileLayout); + + content.addComponents(filePanel, urlPanel); content.setMargin(new MarginInfo(false, true, false, false)); content.setSpacing(true); + + urlButton.addClickListener(e -> { + File file; + try { + URL url = new URL(urlText.getValue()); + file = new File(url.toString()); + InputStream input = url.openStream(); + Buffer buffer = Activator.instance().getBuffer(session.getSession()); + buffer.put(file.getName(), input); + Notification notif = new Notification("Info", "Artefact from url upload sucess", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } catch (IOException | RefusedArtifactException ex) { + new Notification("Could not open or load file from url", ex.getMessage(), Notification.Type.ERROR_MESSAGE) + .show(Page.getCurrent()); + } + + }); + addComponent(content); } class FileUploader implements Receiver, SucceededListener { - public File file; - + private File file; public OutputStream receiveUpload(String filename, String mimeType) { FileOutputStream fos = null; try { @@ -54,17 +104,15 @@ public OutputStream receiveUpload(String filename, String mimeType) { } public void uploadSucceeded(SucceededEvent event) { - Notification notif = new Notification("Info", "File upload sucess", - Notification.Type.ASSISTIVE_NOTIFICATION); - notif.setPosition(Position.TOP_RIGHT); - notif.show(Page.getCurrent()); try { - area.setCaption("Content of File " + file.getName()); - area.setValue(new String(Files.readAllBytes(file.toPath()),Charset.forName("UTF-8"))); - area.setVisible(true); - area.setHeight("600px"); - } catch (IOException e) { - new Notification("Could not open file", e.getMessage(), Notification.Type.ERROR_MESSAGE) + Buffer buffer = Activator.instance().getBuffer(session.getSession()); + buffer.put(file.getName(), Files.newInputStream(file.toPath(), StandardOpenOption.READ)); + Notification notif = new Notification("Info", "Artefact from file upload sucess", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } catch (IOException | RefusedArtifactException e) { + new Notification("Could not open or load file", e.getMessage(), Notification.Type.ERROR_MESSAGE) .show(Page.getCurrent()); } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LocalMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LocalMavenForm.java index 543a6dc3..44b2f708 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LocalMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LocalMavenForm.java @@ -7,7 +7,8 @@ import com.vaadin.ui.Label; import com.vaadin.ui.Tree; import com.vaadin.ui.VerticalLayout; -import cz.zcu.kiv.crce.crce_webui_vaadin.classes.LocalMaven; + +import cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes.LocalMaven; @SuppressWarnings("serial") public class LocalMavenForm extends FormLayout{ diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/CentralMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/CentralMaven.java similarity index 96% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/CentralMaven.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/CentralMaven.java index 2aa60a8e..e5e81ea6 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/CentralMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/CentralMaven.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.classes; +package cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes; import java.io.IOException; import java.net.URL; @@ -7,7 +7,6 @@ import com.vaadin.server.FontAwesome; import com.vaadin.server.VaadinSession; import com.vaadin.ui.Tree; -import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; public class CentralMaven { private static String centralMavenUrl; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/DefinedMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/DefinedMaven.java similarity index 98% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/DefinedMaven.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/DefinedMaven.java index e3893004..855de3af 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/DefinedMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/DefinedMaven.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.classes; +package cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes; import java.util.Arrays; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; @@ -23,8 +23,6 @@ import com.vaadin.server.FontAwesome; import com.vaadin.ui.Tree; -import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; - public class DefinedMaven{ private Tree definedMavenTree = new Tree("Result Search"); private String groupText; @@ -138,3 +136,5 @@ private static RepositorySystemSession newSession(RepositorySystem system, Strin return session; } } + + diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/LocalMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/LocalMaven.java similarity index 92% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/LocalMaven.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/LocalMaven.java index a622bcbe..42027f1d 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/classes/LocalMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/LocalMaven.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.classes; +package cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes; import java.io.File; import java.io.Serializable; @@ -7,10 +7,8 @@ import com.vaadin.server.VaadinSession; import com.vaadin.ui.Tree; -import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; - +@SuppressWarnings("serial") public class LocalMaven implements Serializable{ - private static final long serialVersionUID = 1928618487572353592L; private Tree localMavenTree = new Tree(); private String path;// = System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository"; public Tree getTree(VaadinSession session) { @@ -60,3 +58,4 @@ else if(child.getName().endsWith(".xml") || child.getName().endsWith(".pom")){ } } } + diff --git a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/impl/SettingsUrl.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/SettingsUrl.java similarity index 79% rename from modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/impl/SettingsUrl.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/SettingsUrl.java index e0f9429f..a7f8536a 100644 --- a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/external/web/impl/SettingsUrl.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/SettingsUrl.java @@ -1,52 +1,42 @@ -package cz.zcu.kiv.crce.external.web.impl; +package cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes; import java.io.File; -import cz.zcu.kiv.crce.external.web.inf.InfSettingsUrl; - -public class SettingsUrl implements InfSettingsUrl { +public class SettingsUrl{ private String localMavenUrl = System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository"; private String centralMavenUrl = "http://repo.maven.apache.org/maven2/"; private String localAetherUrl = "target/local-repo"; private String externalAetherUrl = "http://repo.maven.apache.org/maven2/"; - @Override public String getLocalMavenUrl() { return localMavenUrl; } - @Override public String getCentralMavenUrl() { return centralMavenUrl; } - @Override public String getLocalAetherUrl() { return localAetherUrl; } - @Override public String getExternalAetherUrl() { return externalAetherUrl; } - @Override public void setLocalMavenUrl(String url) { this.localMavenUrl = url; } - @Override public void setCentralMavenUrl(String url) { this.centralMavenUrl = url; } - @Override public void setLocalAetherUrl(String url) { this.localAetherUrl = url; } - @Override public void setExternalAetherUrl(String url) { this.externalAetherUrl = url; } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/AboutForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/AboutForm.java index 5b185de8..08d6fd71 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/AboutForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/AboutForm.java @@ -4,14 +4,19 @@ import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; +import cz.zcu.kiv.crce.crce_webui_vaadin.other.VersionInfo; @SuppressWarnings("serial") -public class AboutForm extends FormLayout{ +public class AboutForm extends FormLayout{ public AboutForm(){ VerticalLayout content = new VerticalLayout(); + VersionInfo versionInfo = VersionInfo.getVersionInfo(); + Label about = new Label("

University of West Bohemia, " - + "ReliSA research group, Version: 1.0, Build revision: 2.0

", ContentMode.HTML); + + "ReliSA research group, Version: " + versionInfo.getProductVersion() + + ", Build revision: " + versionInfo.getBuildRevision() + "

", ContentMode.HTML); + content.setSpacing(false); content.setMargin(false); content.addComponent(about); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java index 4c0aabd9..0ddac8d0 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java @@ -27,7 +27,7 @@ public MenuForm(MyUI myUI) { upload.addItem("Local", e ->{myUI.setContentBodyLocalMaven();}); upload.addItem("Central", e ->{myUI.setContentBodyCentralMaven();}); upload.addItem("Defined", e ->{myUI.setContentBodyDefinedMaven();}); - upload.addItem("File", e ->{myUI.setContentBodyLoadFile();}); + upload.addItem("File/url", e ->{myUI.setContentBodyLoadFile();}); // submenu repository repository.addItem("Buffer", e ->{myUI.setContentBodyBuffer();}); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java index df32783e..224e487c 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java @@ -110,7 +110,7 @@ public void setContentBodyDefinedMaven(){ } public void setContentBodyLoadFile(){ - loadFileForm = new LoadFileForm(); + loadFileForm = new LoadFileForm(this.getSession()); body.setContent(loadFileForm); } @@ -125,7 +125,7 @@ public void setContentBodyStore(){ } public void setContentBodyPlugins(){ - pluginsForm = new PluginsForm(); + pluginsForm = new PluginsForm(this); body.setContent(pluginsForm); } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java index b62102ad..a4f1ad45 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java @@ -12,7 +12,8 @@ import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; -import cz.zcu.kiv.crce.external.web.impl.SettingsUrl; + +import cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes.SettingsUrl; @SuppressWarnings("serial") public class SettingsForm extends FormLayout { diff --git a/modules/pom.xml b/modules/pom.xml index 54450c2a..5918364e 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -83,7 +83,7 @@ crce-webservices-indexer - crce-external-repository + crce-webui-vaadin provision From e0ef7340687205fed411e8ee2931f8fd2b9dc1bd Mon Sep 17 00:00:00 2001 From: rpesek Date: Tue, 29 Aug 2017 14:06:51 +0200 Subject: [PATCH 06/85] Completed acquisition with support Aether, store artefact to buffer - Completed WebUI environment for uploading artifacts from a local, central and user-defined repository. - Uploaded to temporary storage (buffer) --- build/pom.xml | 2 +- .../CentralMavenForm.java | 4 +- .../outer/DefinedMavenForm.java | 239 ++++++++++++++++++ .../{resources => outer}/LoadFileForm.java | 10 +- .../outer/LocalMavenForm.java | 177 +++++++++++++ .../classes/CentralMaven.java | 2 +- .../classes/DefinedMaven.java | 132 ++++++---- .../classes/LocalMaven.java | 8 +- .../classes/SettingsUrl.java | 16 +- .../repository/BufferForm.java | 112 +++++++- .../repository/classes/ResourceBean.java | 60 +++++ .../repository/services/ResourceService.java | 93 +++++++ .../resources/DefinedMavenForm.java | 145 ----------- .../resources/LocalMavenForm.java | 37 --- .../crce/crce_webui_vaadin/webui/MyUI.java | 18 +- .../crce_webui_vaadin/webui/SettingsForm.java | 10 +- 16 files changed, 775 insertions(+), 290 deletions(-) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{resources => outer}/CentralMavenForm.java (95%) create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{resources => outer}/LoadFileForm.java (90%) create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{resources => outer}/classes/CentralMaven.java (97%) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{resources => outer}/classes/DefinedMaven.java (51%) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{resources => outer}/classes/LocalMaven.java (88%) rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/{resources => outer}/classes/SettingsUrl.java (61%) create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/ResourceBean.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java delete mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/DefinedMavenForm.java delete mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LocalMavenForm.java diff --git a/build/pom.xml b/build/pom.xml index b2415a40..6b079fb9 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -27,7 +27,7 @@ 0.8.1-incubator 4.3.1 - 6.0.4 + 6.0.6 3.2.0 2.6.1 1.9.13 diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/CentralMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java similarity index 95% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/CentralMavenForm.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java index db259fda..5d9a38ec 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/CentralMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.resources; +package cz.zcu.kiv.crce.crce_webui_vaadin.outer; import java.util.EnumSet; import com.vaadin.event.ShortcutAction.KeyCode; @@ -15,7 +15,7 @@ import com.vaadin.ui.themes.ValoTheme; import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; -import cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes.CentralMaven; +import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.CentralMaven; @SuppressWarnings("serial") public class CentralMavenForm extends FormLayout { diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java new file mode 100644 index 00000000..1f4f89e7 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java @@ -0,0 +1,239 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.outer; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.EnumSet; +import com.vaadin.event.ShortcutListener; +import com.vaadin.server.Page; +import com.vaadin.server.VaadinSession; +import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.shared.Position; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.NativeSelect; +import com.vaadin.ui.Notification; +import com.vaadin.ui.TextField; +import com.vaadin.ui.Tree; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; +import com.vaadin.ui.themes.ValoTheme; + +import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; +import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.DefinedMaven; +import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.SettingsUrl; +import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.repository.RefusedArtifactException; + +public class DefinedMavenForm extends FormLayout implements Serializable { + private static final long serialVersionUID = 4172878715304331198L; + private transient DefinedMaven definedMaven; + private TextField definedUrl = new TextField(); + private Label caption = new Label("Defined Maven repository"); + private TextField group = new TextField("Group Id"); + private TextField artifact = new TextField("Artifact Id"); + private TextField version = new TextField("Version"); + private NativeSelect packaging = new NativeSelect("Packaging"); + private Button searchButton = new Button("Search"); + private Button clearButton = new Button("Clear"); + private Label notFound = new Label("No artifact found"); + private Tree tree; + + public DefinedMavenForm() { + HorizontalLayout content = new HorizontalLayout(); + addComponent(content); + } + + @SuppressWarnings("serial") + public DefinedMavenForm(MyUI myUI) { + // settings url + if (myUI.getSession().getAttribute("settingsUrl") == null) { + SettingsUrl settings = new SettingsUrl(); + definedUrl.setValue(settings.getExternalAetherUrl()); + } else { + definedUrl.setValue(((SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).getExternalAetherUrl()); + } + + VerticalLayout fieldLayout = new VerticalLayout(); + HorizontalLayout treeLayout = new HorizontalLayout(); + VerticalLayout formLayout = new VerticalLayout(); + HorizontalLayout content = new HorizontalLayout(); + + definedUrl.setWidth("450px"); + + packaging.addItems(EnumSet.allOf(TypePackaging.class)); + packaging.select(TypePackaging.jar); + packaging.setNullSelectionAllowed(false); + + searchButton.setStyleName(ValoTheme.BUTTON_PRIMARY); + + HorizontalLayout buttons = new HorizontalLayout(searchButton, clearButton); + buttons.setSpacing(true); + + Button setUrl = new Button("Set"); + CssLayout definedCss = new CssLayout(); + definedCss.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); + definedCss.addComponents(definedUrl, setUrl); + + fieldLayout.addComponents(group, artifact, version, packaging, buttons); + fieldLayout.setSpacing(true); + fieldLayout.setMargin(new MarginInfo(false, true, false, false)); + + treeLayout.addComponent(fieldLayout); + treeLayout.setSpacing(true); + + formLayout.addComponents(caption, definedCss, treeLayout); + formLayout.setSpacing(true); + formLayout.setMargin(new MarginInfo(false, true)); + + content.addComponents(formLayout); + + // Setting url defined repository + setUrl.addClickListener(e -> { + SettingsUrl settings; + if (myUI.getSession().getAttribute("settingsUrl") == null) { + settings = new SettingsUrl(); + settings.setExternalAetherUrl(definedUrl.getValue()); + getSession().setAttribute("settingsUrl", settings); + } else { + settings = (SettingsUrl) myUI.getSession().getAttribute("settingsUrl"); + settings.setExternalAetherUrl(definedUrl.getValue()); + getSession().setAttribute("settingsUrl", settings); + } + }); + + // clear form + clearButton.addClickListener(e -> { + group.clear(); + artifact.clear(); + version.clear(); + packaging.select(TypePackaging.jar); + // erasing any previous components shown + if (treeLayout.getComponentIndex(notFound) != -1) { + treeLayout.removeComponent(notFound); + } + if (treeLayout.getComponentIndex(tree) != -1) { + treeLayout.removeComponent(tree); + } + }); + + // search artefact from defined repository + searchButton.addClickListener(e -> { + SettingsUrl settings; + if (myUI.getSession().getAttribute("settingsUrl") == null) { + settings = new SettingsUrl(); + } else { + settings = (SettingsUrl) myUI.getSession().getAttribute("settingsUrl"); + } + // erasing any previous components shown + if (treeLayout.getComponentIndex(notFound) != -1) { + treeLayout.removeComponent(notFound); + } + if (treeLayout.getComponentIndex(tree) != -1) { + treeLayout.removeComponent(tree); + } + + // předání hodnot - doplnit + definedMaven = new DefinedMaven(settings); + tree = definedMaven.getTree(group.getValue(), artifact.getValue(), version.getValue(), + packaging.getValue()); + if (tree == null) { + treeLayout.addComponent(notFound); + } else { + treeLayout.addComponent(tree); + tree.addShortcutListener(new ShortcutListener("", KeyCode.ENTER, null) { + @Override + public void handleAction(Object sender, Object target) { + if (tree.getValue() != null && !(tree.areChildrenAllowed((Object) tree.getValue())) + && myUI.getWindows().isEmpty()) { + myUI.addWindow(new CheckUploadModal(tree.getValue().toString(), settings, myUI.getSession())); + } + } + }); + } + }); + + content.setSpacing(true); + addComponent(content); + } + + @SuppressWarnings("serial") + private static class CheckUploadModal extends Window { + public CheckUploadModal(String artifactText, SettingsUrl settings, VaadinSession session) { + super("What to do next with " + artifactText.split(":")[1] + "-" + artifactText.split(":")[2] + "." + + artifactText.split(":")[3] + " ?"); + VerticalLayout content = new VerticalLayout(); + content.setWidth("500px"); + content.setHeight("100px"); + + HorizontalLayout buttonLayout = new HorizontalLayout(); + + Button uploadButton = new Button("Upload"); + uploadButton.setStyleName(ValoTheme.BUTTON_PRIMARY); + Button resolveButton = new Button("Resolve"); + Button cancelButton = new Button("Cancel"); + + buttonLayout.addComponents(uploadButton, resolveButton, cancelButton); + + buttonLayout.setSpacing(true); + buttonLayout.setMargin(true); + + content.addComponent(buttonLayout); + content.setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER); + + center(); + setClosable(false); + setResizable(false); + + resolveButton.addClickListener(e -> { + if (DefinedMaven.resolveArtefact(artifactText, settings)) { + Notification notif = new Notification("Info", "Artefact sucess resolved to Maven local repository.", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } else { + new Notification("Problem with resolving artifact", Notification.Type.WARNING_MESSAGE) + .show(Page.getCurrent()); + } + close(); + }); + + uploadButton.addClickListener(e -> { + // First check the artifact storage in the local repository + if (DefinedMaven.resolveArtefact(artifactText, settings)) { + File file = new File(settings.getLocalAetherUrl() + "/" + artifactText.split(":")[0].replace('.', '/') + "/" + + artifactText.split(":")[1] + "/" + artifactText.split(":")[2] + "/" + artifactText.split(":")[1] + + "-" + artifactText.split(":")[2] +"." + artifactText.split(":")[3]); + try { + Activator.instance().getBuffer(session.getSession()).put(file.getName(), Files.newInputStream(file.toPath(), StandardOpenOption.READ)); + Notification notif = new Notification("Info", "Artifact to buffer upload sucess", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } catch (IOException | RefusedArtifactException ex) { + new Notification("Could not open file", ex.getMessage(), Notification.Type.ERROR_MESSAGE) + .show(Page.getCurrent()); + } + } else { + new Notification("Problem with resolving artifact", Notification.Type.WARNING_MESSAGE) + .show(Page.getCurrent()); + } + close(); + }); + + cancelButton.addClickListener(e -> { + close(); + }); + + setContent(content); + } + } +} \ No newline at end of file diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LoadFileForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LoadFileForm.java similarity index 90% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LoadFileForm.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LoadFileForm.java index d689265c..e5a73c09 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LoadFileForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LoadFileForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.resources; +package cz.zcu.kiv.crce.crce_webui_vaadin.outer; import java.io.File; import java.io.FileNotFoundException; @@ -27,7 +27,6 @@ import com.vaadin.ui.VerticalLayout; import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; -import cz.zcu.kiv.crce.repository.Buffer; import cz.zcu.kiv.crce.repository.RefusedArtifactException; @SuppressWarnings("serial") @@ -72,8 +71,7 @@ public LoadFileForm(VaadinSession session){ URL url = new URL(urlText.getValue()); file = new File(url.toString()); InputStream input = url.openStream(); - Buffer buffer = Activator.instance().getBuffer(session.getSession()); - buffer.put(file.getName(), input); + Activator.instance().getBuffer(session.getSession()).put(file.getName(), input); Notification notif = new Notification("Info", "Artefact from url upload sucess", Notification.Type.ASSISTIVE_NOTIFICATION); notif.setPosition(Position.TOP_RIGHT); @@ -105,8 +103,8 @@ public OutputStream receiveUpload(String filename, String mimeType) { public void uploadSucceeded(SucceededEvent event) { try { - Buffer buffer = Activator.instance().getBuffer(session.getSession()); - buffer.put(file.getName(), Files.newInputStream(file.toPath(), StandardOpenOption.READ)); + Activator.instance().getBuffer(session.getSession()) + .put(file.getName(), Files.newInputStream(file.toPath(), StandardOpenOption.READ)); Notification notif = new Notification("Info", "Artefact from file upload sucess", Notification.Type.ASSISTIVE_NOTIFICATION); notif.setPosition(Position.TOP_RIGHT); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java new file mode 100644 index 00000000..752bc82b --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java @@ -0,0 +1,177 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.outer; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardOpenOption; +import java.nio.file.attribute.BasicFileAttributes; + +import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.server.Page; +import com.vaadin.server.VaadinSession; +import com.vaadin.event.ShortcutListener; +import com.vaadin.shared.Position; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Tree; +import com.vaadin.ui.themes.ValoTheme; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; + +import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.LocalMaven; +import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.repository.RefusedArtifactException; + +@SuppressWarnings("serial") +public class LocalMavenForm extends FormLayout { + private LocalMaven localMaven = new LocalMaven(); + private Label caption = new Label("Local Maven repository"); + + public LocalMavenForm() { + HorizontalLayout content = new HorizontalLayout(); + addComponent(content); + } + + public LocalMavenForm(MyUI myUI) { + VerticalLayout content = new VerticalLayout(); + // Tree of Maven local repository + Tree localMavenTree = localMaven.getTree(myUI.getSession()); + content.setMargin(new MarginInfo(false, true)); + if (localMavenTree == null) { + content.addComponent(new Label("Local Maven repository not found")); + } else { + content.addComponents(caption, localMavenTree); + content.setSpacing(true); + + localMavenTree.addShortcutListener(new ShortcutListener("", KeyCode.ENTER, null) { + @Override + public void handleAction(Object sender, Object target) { + if (localMavenTree.getValue() != null && myUI.getWindows().isEmpty()){ + if(localMavenTree.areChildrenAllowed((Object) localMavenTree.getValue())){ + myUI.addWindow(new RemovePathModal(new File(localMavenTree.getValue().toString()), myUI)); + } + else{ + myUI.addWindow(new CheckUploadModal(new File(localMavenTree.getValue().toString()), myUI.getSession())); + } + } + } + }); + } + addComponent(content); + } + + private static class CheckUploadModal extends Window { + public CheckUploadModal(File file, VaadinSession session) { + super("Upload " + file.getName() + " to buffer?"); + VerticalLayout content = new VerticalLayout(); + content.setWidth("400px"); + content.setHeight("100px"); + + HorizontalLayout buttonLayout = new HorizontalLayout(); + + Button acceptButton = new Button("OK"); + acceptButton.setStyleName(ValoTheme.BUTTON_PRIMARY); + Button cancelButton = new Button("Cancel"); + + buttonLayout.addComponents(acceptButton, cancelButton); + + buttonLayout.setSpacing(true); + buttonLayout.setMargin(true); + + content.addComponent(buttonLayout); + content.setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER); + + center(); + setClosable(false); + setResizable(false); + + acceptButton.addClickListener(e ->{ + try { + Activator.instance().getBuffer(session.getSession()).put(file.getName(), Files.newInputStream(file.toPath(), StandardOpenOption.READ)); + Notification notif = new Notification("Info", "Artifact to buffer upload sucess", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } catch (IOException | RefusedArtifactException ex) { + new Notification("Could not open file", ex.getMessage(), Notification.Type.ERROR_MESSAGE) + .show(Page.getCurrent()); + } finally { + close(); + } + }); + + cancelButton.addClickListener(e -> { + close(); + }); + + setContent(content); + } + } + + private static class RemovePathModal extends Window { + public RemovePathModal(File file, MyUI myUI){ + super("Remove path " + file.getName() + "?"); + VerticalLayout content = new VerticalLayout(); + content.setWidth("400px"); + content.setHeight("100px"); + + HorizontalLayout buttonLayout = new HorizontalLayout(); + + Button removeButton = new Button("Remove"); + removeButton.setStyleName(ValoTheme.BUTTON_DANGER); + Button cancelButton = new Button("Cancel"); + + buttonLayout.addComponents(removeButton, cancelButton); + + buttonLayout.setSpacing(true); + buttonLayout.setMargin(true); + + content.addComponent(buttonLayout); + content.setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER); + + center(); + setClosable(false); + setResizable(false); + + removeButton.addClickListener(e ->{ + Path directory = file.toPath(); + try { + Files.walkFileTree(directory, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException ex) { + new Notification("Could not remove path!", ex.getMessage(), Notification.Type.ERROR_MESSAGE) + .show(Page.getCurrent()); + } finally{ + close(); + myUI.setContentBodyLocalMaven(); + } + }); + + cancelButton.addClickListener(e -> { + close(); + }); + + setContent(content); + } + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/CentralMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java similarity index 97% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/CentralMaven.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java index e5e81ea6..b61b7c83 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/CentralMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes; +package cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes; import java.io.IOException; import java.net.URL; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/DefinedMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/DefinedMaven.java similarity index 51% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/DefinedMaven.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/DefinedMaven.java index 855de3af..a1229a08 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/DefinedMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/DefinedMaven.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes; +package cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes; import java.util.Arrays; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; @@ -11,6 +11,9 @@ import org.eclipse.aether.impl.DefaultServiceLocator; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.ArtifactResult; import org.eclipse.aether.resolution.VersionRangeRequest; import org.eclipse.aether.resolution.VersionRangeResolutionException; import org.eclipse.aether.resolution.VersionRangeResult; @@ -23,28 +26,27 @@ import com.vaadin.server.FontAwesome; import com.vaadin.ui.Tree; -public class DefinedMaven{ +public class DefinedMaven { private Tree definedMavenTree = new Tree("Result Search"); private String groupText; - private String artifactText; + private String idText; private String versionText; private String packagingText; private SettingsUrl settings; - - public DefinedMaven(SettingsUrl settings){ + + public DefinedMaven(SettingsUrl settings) { this.settings = settings; } - public Tree getTree(String group, String artifact, String version, Object packaging) { + public Tree getTree(String group, String idText, String version, Object packaging) { // validator empty entries - if(group.equals("") || artifact.equals("")){ + if (group.equals("") || idText.equals("")) { return null; - } - else{ + } else { // reset tree definedMavenTree.removeAllItems(); this.groupText = group; - this.artifactText = artifact; + this.idText = idText; this.versionText = version; this.packagingText = packaging.toString(); callAetherLib(); @@ -53,72 +55,92 @@ public Tree getTree(String group, String artifact, String version, Object packag } private void callAetherLib() { - RemoteRepository central = new RemoteRepository.Builder("nexus", "default", settings.getExternalAetherUrl()).build(); + RemoteRepository central = new RemoteRepository.Builder("central", "default", settings.getExternalAetherUrl()) + .build(); RepositorySystem repoSystem = newRepositorySystem(); RepositorySystemSession session = newSession(repoSystem, settings.getLocalAetherUrl()); // Artifact artifact = new DefaultArtifact("groupId:artifactId:(0,]"); Artifact artifact; - if(!versionText.equals("")){ - artifact = new DefaultArtifact(groupText + ":" + artifactText + ":" + "[" + versionText + "]"); - } - else{ - artifact = new DefaultArtifact(groupText + ":" + artifactText + ":" + "(0,]"); + if (!versionText.equals("")) { + artifact = new DefaultArtifact(groupText + ":" + idText + ":" + "[" + versionText + "]"); + } else { + artifact = new DefaultArtifact(groupText + ":" + idText + ":" + "(0,]"); } VersionRangeRequest request = new VersionRangeRequest(artifact, Arrays.asList(central), null); try { VersionRangeResult versionResult = repoSystem.resolveVersionRange(session, request); - if(versionResult.getHighestVersion() == null) { + if (versionResult.getVersions().isEmpty()) { definedMavenTree = null; - } - else { + } else { String[] pom = artifact.getGroupId().split("\\."); definedMavenTree.addItem(pom[0]); - for(int i=1; i< pom.length; i++){ + for (int i = 1; i < pom.length; i++) { definedMavenTree.addItem(pom[i]); - definedMavenTree.setParent(pom[i], pom[i-1]); + definedMavenTree.setParent(pom[i], pom[i - 1]); } - - if(versionResult.getVersions().size() > 1){ - for(Version v : versionResult.getVersions()){ - addArtefactToTree(artifact, v, pom[pom.length-1]); + + if (versionResult.getVersions().size() > 1) { + for (Version v : versionResult.getVersions()) { + addArtefactToTree(artifact, v, pom[pom.length - 1]); } - } - else{ - addArtefactToTree(artifact, versionResult.getHighestVersion(), pom[pom.length-1]); + } else { + addArtefactToTree(artifact, versionResult.getHighestVersion(), pom[pom.length - 1]); } } - + } catch (VersionRangeResolutionException e) { e.printStackTrace(); } } - - private void addArtefactToTree(Artifact artifact, Version version, String parent){ + + private void addArtefactToTree(Artifact artifact, Version version, String parent) { definedMavenTree.addItem(artifact.getArtifactId()); definedMavenTree.setParent(artifact.getArtifactId(), parent); definedMavenTree.addItem(version.toString()); - definedMavenTree.setParent(version.toString(),artifact.getArtifactId()); - - //end artefact - //konečný artefact je komplet url link např. pro wget - UPRAVIT DLE POTŘEBY - String urlArtefact = settings.getExternalAetherUrl() + "/" + groupText + "/" + artifactText + - "/" + version + "." + packagingText; - - definedMavenTree.addItem(urlArtefact); - definedMavenTree.setParent(urlArtefact, version.toString()); - definedMavenTree.setItemCaption(urlArtefact, artifact.getArtifactId() + - "-" + version.toString() + "." + packagingText); - definedMavenTree.setChildrenAllowed(urlArtefact, false); - if(packagingText.equals("jar") || packagingText.equals("war")){ - definedMavenTree.setItemIcon(urlArtefact, FontAwesome.GIFT); - } - else if(packagingText.equals("xml") || packagingText.equals("pom")){ - definedMavenTree.setItemIcon(urlArtefact, FontAwesome.CODE); - } - else{ - definedMavenTree.setItemIcon(urlArtefact, FontAwesome.FILE); - } + definedMavenTree.setParent(version.toString(), artifact.getArtifactId()); + + // konečný artefact je komplet url link např. pro wget - UPRAVIT DLE + // POTŘEBY + /* + * String artifactText = settings.getExternalAetherUrl() + "/" + + * groupText + "/" + idText + "/" + version + "." + packagingText; + */ + String artifactText = groupText + ":" + idText + ":" + version + ":" + packagingText; + + definedMavenTree.addItem(artifactText); + definedMavenTree.setParent(artifactText, version.toString()); + definedMavenTree.setItemCaption(artifactText, + artifact.getArtifactId() + "-" + version.toString() + "." + packagingText); + definedMavenTree.setChildrenAllowed(artifactText, false); + if (packagingText.equals("jar") || packagingText.equals("war")) { + definedMavenTree.setItemIcon(artifactText, FontAwesome.GIFT); + } else if (packagingText.equals("xml") || packagingText.equals("pom")) { + definedMavenTree.setItemIcon(artifactText, FontAwesome.CODE); + } else { + definedMavenTree.setItemIcon(artifactText, FontAwesome.FILE); + } + } + + public static boolean resolveArtefact(String artifactText, SettingsUrl settings) { + RepositorySystem repoSystem = newRepositorySystem(); + RepositorySystemSession session = newSession(repoSystem, settings.getLocalAetherUrl()); + + ArtifactRequest artifactRequest = new ArtifactRequest(); + Artifact artifact = new DefaultArtifact(artifactText.split(":")[0] + ":" + artifactText.split(":")[1] + ":" + + artifactText.split(":")[2]); + + artifactRequest.setArtifact(artifact); + + artifactRequest.addRepository(newCentralRepository(settings.getExternalAetherUrl())); + ArtifactResult artifactResult; + try { + artifactResult = repoSystem.resolveArtifact(session, artifactRequest); + artifactResult.getArtifact(); + } catch (ArtifactResolutionException e) { + return false; + } + return true; } private static RepositorySystem newRepositorySystem() { @@ -135,6 +157,8 @@ private static RepositorySystemSession newSession(RepositorySystem system, Strin session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)); return session; } -} - + public static RemoteRepository newCentralRepository(String centralAetherUrl) { + return new RemoteRepository.Builder("central", "default", centralAetherUrl).build(); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/LocalMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/LocalMaven.java similarity index 88% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/LocalMaven.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/LocalMaven.java index 42027f1d..629d323d 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/LocalMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/LocalMaven.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes; +package cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes; import java.io.File; import java.io.Serializable; @@ -10,15 +10,15 @@ @SuppressWarnings("serial") public class LocalMaven implements Serializable{ private Tree localMavenTree = new Tree(); - private String path;// = System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository"; + private String path; public Tree getTree(VaadinSession session) { // get local Maven path if(session.getAttribute("settingsUrl") == null){ SettingsUrl settings = new SettingsUrl(); - path = settings.getLocalMavenUrl(); + path = settings.getLocalAetherUrl(); } else{ - path = ((SettingsUrl)session.getAttribute("settingsUrl")).getLocalMavenUrl(); + path = ((SettingsUrl)session.getAttribute("settingsUrl")).getLocalAetherUrl(); } File f = new File(path); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/SettingsUrl.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/SettingsUrl.java similarity index 61% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/SettingsUrl.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/SettingsUrl.java index a7f8536a..98e0aea0 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/classes/SettingsUrl.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/SettingsUrl.java @@ -1,18 +1,10 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes; - -import java.io.File; +package cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes; public class SettingsUrl{ - - private String localMavenUrl = System.getProperty("user.home") + File.separator + ".m2" + File.separator + "repository"; private String centralMavenUrl = "http://repo.maven.apache.org/maven2/"; - private String localAetherUrl = "target/local-repo"; + private String localAetherUrl = "aether-local-repo"; private String externalAetherUrl = "http://repo.maven.apache.org/maven2/"; - public String getLocalMavenUrl() { - return localMavenUrl; - } - public String getCentralMavenUrl() { return centralMavenUrl; } @@ -25,10 +17,6 @@ public String getExternalAetherUrl() { return externalAetherUrl; } - public void setLocalMavenUrl(String url) { - this.localMavenUrl = url; - } - public void setCentralMavenUrl(String url) { this.centralMavenUrl = url; } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java index 29fa0fb7..0df0863b 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java @@ -1,47 +1,139 @@ package cz.zcu.kiv.crce.crce_webui_vaadin.repository; +import java.io.IOException; + import com.vaadin.data.util.BeanItemContainer; -import com.vaadin.server.VaadinSession; +import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.server.FontAwesome; +import com.vaadin.server.Page; +import com.vaadin.shared.Position; import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.CssLayout; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Grid; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Panel; +import com.vaadin.ui.PopupView; +import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.services.ResourceService; +import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; import cz.zcu.kiv.crce.metadata.Resource; -import cz.zcu.kiv.crce.repository.Buffer; @SuppressWarnings("serial") public class BufferForm extends FormLayout{ private Label labelForm = new Label("Artefact in Buffer"); + private TextField idText = new TextField(); private Grid gridBuffer = new Grid(); - private HorizontalLayout formLayout; + private PopupView popup; + private Resource resourceSelect; + private ResourceService resourceService; - public BufferForm(VaadinSession session){ + public BufferForm(MyUI myUI){ VerticalLayout content = new VerticalLayout(); VerticalLayout fieldLayout = new VerticalLayout(); + HorizontalLayout buttonLayout = new HorizontalLayout(); - labelForm.addStyleName(ValoTheme.LABEL_BOLD); + resourceService = new ResourceService(Activator.instance().getMetadataService()); + + Button buttonDetail = new Button("Detail"); + Button buttonRemove = new Button("Remove"); + + buttonDetail.setStyleName(ValoTheme.BUTTON_PRIMARY); + buttonDetail.setClickShortcut(KeyCode.ENTER); - Buffer buffer = Activator.instance().getBuffer(session.getSession()); + labelForm.addStyleName(ValoTheme.LABEL_BOLD); - gridBuffer.setContainerDataSource(new BeanItemContainer<>(Resource.class, buffer.getResources())); + gridBuffer.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, resourceService.getAllResourceBean(myUI.getSession().getSession()))); + gridBuffer.getColumn("resource").setHidden(true); + gridBuffer.setColumnOrder("presentationName", "symbolicName", "version", "categories"); gridBuffer.addStyleName("my-style"); - fieldLayout.addComponents(labelForm, gridBuffer); + idText.setInputPrompt("search by name..."); + + Button findButton = new Button(FontAwesome.CHECK); + findButton.addClickListener(e ->{ + gridBuffer.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, + resourceService.getFindResourceBean(myUI.getSession().getSession(), idText.getValue()))); + }); + Button clearButton = new Button(FontAwesome.TIMES); + clearButton.addClickListener(e -> { + myUI.setContentBodyBuffer(); + }); + + CssLayout filtering = new CssLayout(); + filtering.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); + filtering.addComponents(idText, findButton, clearButton); + + + fieldLayout.addComponents(labelForm, filtering, gridBuffer); fieldLayout.setSpacing(true); - formLayout = new HorizontalLayout(fieldLayout); + HorizontalLayout formLayout = new HorizontalLayout(fieldLayout); formLayout.setSizeFull(); gridBuffer.setSizeFull(); formLayout.setExpandRatio(fieldLayout, 1); - content.addComponent(formLayout); + // Popup verification of artifact remove + VerticalLayout buttonPopupLayout = new VerticalLayout(); + Panel panel = new Panel("Really remove the artifact?"); + Button yesRemoveButton = new Button("Confirm"); + yesRemoveButton.setStyleName(ValoTheme.BUTTON_DANGER); + buttonPopupLayout.addComponents(yesRemoveButton); + buttonPopupLayout.setMargin(true); + buttonPopupLayout.setSizeFull(); + buttonPopupLayout.setComponentAlignment(yesRemoveButton, Alignment.BOTTOM_CENTER); + panel.setContent(buttonPopupLayout); + + popup = new PopupView(null, panel); + popup.setWidth("150px"); + + buttonLayout.addComponents(buttonDetail, buttonRemove); + buttonLayout.setSpacing(true); + buttonLayout.setVisible(false); + + content.addComponents(formLayout, buttonLayout, popup); + content.setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER); + content.setComponentAlignment(popup, Alignment.MIDDLE_CENTER); content.setMargin(new MarginInfo(false, true)); content.setSpacing(true); + + gridBuffer.addSelectionListener(e ->{ + buttonLayout.setVisible(true); + resourceSelect = ((ResourceBean)e.getSelected().iterator().next()).getResource(); + }); + + buttonRemove.addClickListener(e ->{ + popup.setPopupVisible(true); + yesRemoveButton.addClickListener(ev -> { + try { + boolean result = Activator.instance().getBuffer(myUI.getSession().getSession()).remove(resourceSelect); + if(result){ + Notification notif = new Notification("Info", "Artefact sucess removed", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } + else{ + new Notification("Could not remove artefact from buffer", Notification.Type.WARNING_MESSAGE) + .show(Page.getCurrent()); + } + myUI.setContentBodyBuffer(); + } catch (IOException ex) { + new Notification("Error while removing the artifact", ex.getMessage(), Notification.Type.ERROR_MESSAGE) + .show(Page.getCurrent()); + } + }); + }); + addComponent(content); } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/ResourceBean.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/ResourceBean.java new file mode 100644 index 00000000..bb6a5a81 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/ResourceBean.java @@ -0,0 +1,60 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes; + +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.metadata.type.Version; + +public class ResourceBean{ + private String presentationName; + private String symbolicName; + private String version; + private String categories; + private Resource resource; + + public ResourceBean(String presentationName, String symbolicName, Version version, + String[] categories, Resource resource) { + this.presentationName = presentationName; + this.symbolicName = symbolicName; + if(version == null){ + this.version = "unknown-version"; + } + else{ + this.version = version.toString(); + } + for(String s : categories){ + this.categories = s + ","; + } + if(!(categories.length == 0)){ + this.categories = this.categories.substring(0, this.categories.length() - 1); + } + else{ + this.categories = "unknown-categories"; + } + this.resource = resource; + } + + public String getPresentationName() { + return presentationName; + } + + public String getSymbolicName() { + return symbolicName; + } + + public Resource getResource() { + return resource; + } + + public String getVersion() { + return version; + } + + public String getCategories() { + return categories; + } + + @Override + public String toString(){ + return presentationName; + } + +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java new file mode 100644 index 00000000..85aeb3ca --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java @@ -0,0 +1,93 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.repository.services; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import com.vaadin.server.WrappedSession; +import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.metadata.Capability; +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiBundle; +import cz.zcu.kiv.crce.metadata.service.MetadataService; +import cz.zcu.kiv.crce.metadata.type.Version; + +public class ResourceService implements Serializable{ + private static final long serialVersionUID = 6161700434751771631L; + private Resource resource; + private transient MetadataService metadataService; + + public ResourceService(MetadataService metadataService){ + this.metadataService = metadataService; + } + + public ResourceService(Resource resource, MetadataService metadataService){ + this.resource = resource; + this.metadataService = metadataService; + } + + public void setResource(Resource resource){ + this.resource = resource; + } + + public String getPresentationName() { + return metadataService.getPresentationName(resource); + } + + public String getSymbolicName() { + String name = "unknown-symbolic-name"; + List capabilities = resource.getCapabilities(NsOsgiBundle.NAMESPACE__OSGI_BUNDLE); + if (!capabilities.isEmpty()) { + name = capabilities.get(0).getAttributeValue(NsOsgiBundle.ATTRIBUTE__SYMBOLIC_NAME); + } + return name; + } + + public String[] getCategories() { + return metadataService.getCategories(resource).toArray(new String[0]); + } + + public Version getVersion() { + Version version = null; + List capabilities = resource.getCapabilities(NsOsgiBundle.NAMESPACE__OSGI_BUNDLE); + if (!capabilities.isEmpty()) { + version = capabilities.get(0).getAttributeValue(NsOsgiBundle.ATTRIBUTE__VERSION); + } + return version; + } + + public List getAllResourceBean(WrappedSession session){ + List resources = new ArrayList(); + for(Resource resource : Activator.instance().getBuffer(session).getResources()){ + setResource(resource); + resources.add(new ResourceBean(getPresentationName(), getSymbolicName(), getVersion(), getCategories(), resource)); + } + return resources; + } + + public List getFindResourceBean(WrappedSession session, String stringFilter){ + boolean passesFilter = false; + ArrayList arrayList = new ArrayList<>(); + for (ResourceBean resourceBean : getAllResourceBean(session)){ + if(stringFilter == null || stringFilter.isEmpty()){ + passesFilter = true; + } + else{ + passesFilter = resourceBean.toString().toLowerCase().contains(stringFilter.toLowerCase()); + } + if (passesFilter) { + arrayList.add(resourceBean); + } + } + Collections.sort(arrayList, new Comparator() { + @Override + public int compare(ResourceBean o1, ResourceBean o2) { + return (int) (o2.hashCode() - o1.hashCode()); + } + }); + return arrayList; + } + +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/DefinedMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/DefinedMavenForm.java deleted file mode 100644 index 619d14cc..00000000 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/DefinedMavenForm.java +++ /dev/null @@ -1,145 +0,0 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.resources; - -import java.io.Serializable; -import java.util.EnumSet; -import com.vaadin.event.ShortcutAction.KeyCode; -import com.vaadin.server.VaadinSession; -import com.vaadin.shared.ui.MarginInfo; -import com.vaadin.ui.Button; -import com.vaadin.ui.CssLayout; -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.NativeSelect; -import com.vaadin.ui.TextField; -import com.vaadin.ui.Tree; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.themes.ValoTheme; - -import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; -import cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes.DefinedMaven; -import cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes.SettingsUrl; - -public class DefinedMavenForm extends FormLayout implements Serializable{ - private static final long serialVersionUID = 4172878715304331198L; - private transient DefinedMaven definedMaven; - private TextField definedUrl = new TextField(); - private Label caption = new Label("Defined Maven repository"); - private TextField group = new TextField("Group Id"); - private TextField artifact = new TextField("Artifact Id"); - private TextField version = new TextField("Version"); - private NativeSelect packaging = new NativeSelect("Packaging"); - private Button searchButton = new Button("Search"); - private Button clearButton = new Button("Clear"); - private Label notFound = new Label("No artifact found"); - private Tree tree; - - public DefinedMavenForm() { - HorizontalLayout content = new HorizontalLayout(); - addComponent(content); - } - - public DefinedMavenForm(VaadinSession session) { - // settings url - if (session.getAttribute("settingsUrl") == null) { - SettingsUrl settings = new SettingsUrl(); - definedUrl.setValue(settings.getExternalAetherUrl()); - } else { - definedUrl.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getExternalAetherUrl()); - } - - VerticalLayout fieldLayout = new VerticalLayout(); - HorizontalLayout treeLayout = new HorizontalLayout(); - VerticalLayout formLayout = new VerticalLayout(); - HorizontalLayout content = new HorizontalLayout(); - - definedUrl.setWidth("450px"); - - packaging.addItems(EnumSet.allOf(TypePackaging.class)); - packaging.select(TypePackaging.jar); - packaging.setNullSelectionAllowed(false); - - searchButton.setStyleName(ValoTheme.BUTTON_PRIMARY); - searchButton.setClickShortcut(KeyCode.ENTER); - - HorizontalLayout buttons = new HorizontalLayout(searchButton, clearButton); - buttons.setSpacing(true); - - Button setUrl = new Button("Set"); - CssLayout definedCss = new CssLayout(); - definedCss.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); - definedCss.addComponents(definedUrl, setUrl); - - fieldLayout.addComponents(group, artifact, version, packaging, buttons); - fieldLayout.setSpacing(true); - fieldLayout.setMargin(new MarginInfo(false, true, false, false)); - - treeLayout.addComponent(fieldLayout); - treeLayout.setSpacing(true); - - formLayout.addComponents(caption, definedCss, treeLayout); - formLayout.setSpacing(true); - formLayout.setMargin(new MarginInfo(false, true)); - - content.addComponents(formLayout); - - // Setting url defined repository - setUrl.addClickListener(e -> { - SettingsUrl settings; - if (session.getAttribute("settingsUrl") == null) { - settings = new SettingsUrl(); - settings.setExternalAetherUrl(definedUrl.getValue()); - getSession().setAttribute("settingsUrl", settings); - } else { - settings = (SettingsUrl) session.getAttribute("settingsUrl"); - settings.setExternalAetherUrl(definedUrl.getValue()); - getSession().setAttribute("settingsUrl", settings); - } - }); - - // clear form - clearButton.addClickListener(e -> { - group.clear(); - artifact.clear(); - version.clear(); - packaging.select(TypePackaging.jar); - // erasing any previous components shown - if (treeLayout.getComponentIndex(notFound) != -1) { - treeLayout.removeComponent(notFound); - } - if (treeLayout.getComponentIndex(tree) != -1) { - treeLayout.removeComponent(tree); - } - }); - - // search artefact from defined repository - searchButton.addClickListener(e -> { - SettingsUrl settings; - if (session.getAttribute("settingsUrl") == null) { - settings = new SettingsUrl(); - } else { - settings = (SettingsUrl) session.getAttribute("settingsUrl"); - } - // erasing any previous components shown - if (treeLayout.getComponentIndex(notFound) != -1) { - treeLayout.removeComponent(notFound); - } - if (treeLayout.getComponentIndex(tree) != -1) { - treeLayout.removeComponent(tree); - } - - // předání hodnot - doplnit - definedMaven = new DefinedMaven(settings); - tree = definedMaven.getTree(group.getValue(), artifact.getValue(), version.getValue(), - packaging.getValue()); - if (tree == null) { - treeLayout.addComponent(notFound); - } else { - treeLayout.addComponent(tree); - } - }); - - content.setSpacing(true); - addComponent(content); - } -} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LocalMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LocalMavenForm.java deleted file mode 100644 index 44b2f708..00000000 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/resources/LocalMavenForm.java +++ /dev/null @@ -1,37 +0,0 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.resources; - -import com.vaadin.server.VaadinSession; -import com.vaadin.shared.ui.MarginInfo; -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.Tree; -import com.vaadin.ui.VerticalLayout; - -import cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes.LocalMaven; - -@SuppressWarnings("serial") -public class LocalMavenForm extends FormLayout{ - private LocalMaven localMaven = new LocalMaven(); - private Label caption = new Label("Local Maven repository"); - - public LocalMavenForm() { - HorizontalLayout content = new HorizontalLayout(); - addComponent(content); - } - - public LocalMavenForm(VaadinSession session){ - VerticalLayout content = new VerticalLayout(); - // Tree of Maven local repository - Tree localMavenTree = localMaven.getTree(session); - content.setMargin(new MarginInfo(false, true)); - if(localMavenTree == null){ - content.addComponent(new Label("Local Maven repository not found")); - } - else{ - content.addComponents(caption, localMavenTree); - content.setSpacing(true); - } - addComponent(content); - } -} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java index 224e487c..50779ce9 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java @@ -1,22 +1,22 @@ package cz.zcu.kiv.crce.crce_webui_vaadin.webui; import javax.servlet.annotation.WebServlet; - import com.vaadin.annotations.Theme; import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.server.Page; import com.vaadin.server.VaadinRequest; import com.vaadin.server.VaadinServlet; import com.vaadin.ui.Panel; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; +import cz.zcu.kiv.crce.crce_webui_vaadin.outer.CentralMavenForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.outer.DefinedMavenForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.outer.LoadFileForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.outer.LocalMavenForm; import cz.zcu.kiv.crce.crce_webui_vaadin.repository.BufferForm; import cz.zcu.kiv.crce.crce_webui_vaadin.repository.PluginsForm; import cz.zcu.kiv.crce.crce_webui_vaadin.repository.StoreForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.resources.CentralMavenForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.resources.DefinedMavenForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.resources.LoadFileForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.resources.LocalMavenForm; /** * This UI is the application entry point. A UI may either represent a browser window @@ -91,11 +91,13 @@ public void logout() { private void cleanupAfterLogout(){ getSession().setAttribute("settingsUrl", null); + getSession().getSession().invalidate(); + Page.getCurrent().setLocation(VaadinServlet.getCurrent().getServletContext().getContextPath()); content.removeAllComponents(); } public void setContentBodyLocalMaven(){ - localMavenForm = new LocalMavenForm(getSession()); + localMavenForm = new LocalMavenForm(this); body.setContent(localMavenForm); } @@ -105,7 +107,7 @@ public void setContentBodyCentralMaven(){ } public void setContentBodyDefinedMaven(){ - definedMavenForm = new DefinedMavenForm(getSession()); + definedMavenForm = new DefinedMavenForm(this); body.setContent(definedMavenForm); } @@ -115,7 +117,7 @@ public void setContentBodyLoadFile(){ } public void setContentBodyBuffer(){ - bufferForm = new BufferForm(getSession()); + bufferForm = new BufferForm(this); body.setContent(bufferForm); } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java index a4f1ad45..8ac2ee45 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java @@ -13,7 +13,7 @@ import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; -import cz.zcu.kiv.crce.crce_webui_vaadin.resources.classes.SettingsUrl; +import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.SettingsUrl; @SuppressWarnings("serial") public class SettingsForm extends FormLayout { @@ -24,11 +24,9 @@ public SettingsForm() { } public SettingsForm(VaadinSession session) { - TextField localMavenUrl = new TextField("Local Maven path"); TextField centralMavenUrl = new TextField("Central Maven url"); TextField localAetherRepo = new TextField("Local Aether repository"); - localMavenUrl.setWidth("400px"); centralMavenUrl.setWidth("400px"); localAetherRepo.setWidth("400px"); @@ -36,11 +34,9 @@ public SettingsForm(VaadinSession session) { if (session.getAttribute("settingsUrl") == null) { SettingsUrl settingsUrl = new SettingsUrl(); - localMavenUrl.setValue(settingsUrl.getLocalMavenUrl()); centralMavenUrl.setValue(settingsUrl.getCentralMavenUrl()); localAetherRepo.setValue(settingsUrl.getLocalAetherUrl()); } else { - localMavenUrl.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getLocalMavenUrl()); centralMavenUrl.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getCentralMavenUrl()); localAetherRepo.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getLocalAetherUrl()); } @@ -55,7 +51,7 @@ public SettingsForm(VaadinSession session) { saveButton.setClickShortcut(KeyCode.ENTER); VerticalLayout content = new VerticalLayout(); - content.addComponents(localMavenUrl, centralMavenUrl, localAetherRepo, buttonsLayout); + content.addComponents(centralMavenUrl, localAetherRepo, buttonsLayout); content.setSpacing(true); HorizontalLayout formLayout = new HorizontalLayout(); @@ -70,7 +66,6 @@ public SettingsForm(VaadinSession session) { else{ settingsUrl = (SettingsUrl) getSession().getAttribute("settingsUrl"); } - settingsUrl.setLocalMavenUrl(localMavenUrl.getValue()); settingsUrl.setCentralMavenUrl(centralMavenUrl.getValue()); settingsUrl.setLocalAetherUrl(localAetherRepo.getValue()); getSession().setAttribute("settingsUrl", settingsUrl); @@ -83,7 +78,6 @@ public SettingsForm(VaadinSession session) { defaultButton.addClickListener(e ->{ SettingsUrl settingsUrl = new SettingsUrl(); getSession().setAttribute("settingsUrl", settingsUrl); - localMavenUrl.setValue(settingsUrl.getLocalMavenUrl()); centralMavenUrl.setValue(settingsUrl.getCentralMavenUrl()); localAetherRepo.setValue(settingsUrl.getLocalAetherUrl()); }); From 4eb1a11003808c3142fb439cf0e5f75cb7ec011e Mon Sep 17 00:00:00 2001 From: rpesek Date: Thu, 31 Aug 2017 07:45:38 +0200 Subject: [PATCH 07/85] Group listing from Central Maven Repository Added group listing feature from Central Maven repositories. Enabling the function in the settings menu. --- .../outer/CentralMavenForm.java | 107 +++++++++++++--- .../outer/DefinedMavenForm.java | 28 +++-- .../crce_webui_vaadin/outer/LoadFileForm.java | 1 - .../outer/LocalMavenForm.java | 77 ++++++------ .../outer/classes/CentralMaven.java | 119 +++++++++++------- .../outer/classes/SettingsUrl.java | 8 ++ .../crce/crce_webui_vaadin/webui/MyUI.java | 2 +- .../crce_webui_vaadin/webui/SettingsForm.java | 8 +- 8 files changed, 239 insertions(+), 111 deletions(-) diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java index 5d9a38ec..6407f390 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java @@ -1,21 +1,35 @@ package cz.zcu.kiv.crce.crce_webui_vaadin.outer; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; import java.util.EnumSet; + +import com.vaadin.event.ShortcutListener; import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.server.Page; import com.vaadin.server.VaadinSession; +import com.vaadin.shared.Position; import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.FormLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.NativeSelect; +import com.vaadin.ui.Notification; import com.vaadin.ui.TextField; import com.vaadin.ui.Tree; import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; +import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.CentralMaven; +import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.repository.RefusedArtifactException; @SuppressWarnings("serial") public class CentralMavenForm extends FormLayout { @@ -28,21 +42,20 @@ public class CentralMavenForm extends FormLayout { private Button clearButton = new Button("Clear"); private Label notFound = new Label("No artifact found"); private Tree tree; - + public CentralMavenForm() { HorizontalLayout content = new HorizontalLayout(); addComponent(content); } - public CentralMavenForm(VaadinSession session){ + public CentralMavenForm(MyUI myUI) { VerticalLayout userForm = new VerticalLayout(); HorizontalLayout content = new HorizontalLayout(); packaging.addItems(EnumSet.allOf(TypePackaging.class)); packaging.select(TypePackaging.jar); packaging.setNullSelectionAllowed(false); - + searchButton.setStyleName(ValoTheme.BUTTON_PRIMARY); - searchButton.setClickShortcut(KeyCode.ENTER); HorizontalLayout buttons = new HorizontalLayout(searchButton, clearButton); buttons.setSpacing(true); @@ -50,30 +63,37 @@ public CentralMavenForm(VaadinSession session){ userForm.setSpacing(true); userForm.setMargin(new MarginInfo(false, true)); content.addComponent(userForm); - + // Add tree - searchButton.addClickListener(e ->{ + searchButton.addClickListener(e -> { // erasing any previous components shown - if(content.getComponentIndex(notFound) != -1){ + if (content.getComponentIndex(notFound) != -1) { content.removeComponent(notFound); } - if(content.getComponentIndex(tree) != -1){ + if (content.getComponentIndex(tree) != -1) { content.removeComponent(tree); } - // check exist component from central Maven repository - tree = new CentralMaven(session).getTree(group.getValue(),artifact.getValue(), - version.getValue(),packaging.getValue()); - if(tree == null){ + // check exist component from central Maven repository + tree = new CentralMaven(myUI.getSession()).getTree(group.getValue(), artifact.getValue(), version.getValue(), + packaging.getValue()); + if (tree == null) { content.addComponent(notFound); - } - else{ + } else { + tree.addShortcutListener(new ShortcutListener("", KeyCode.ENTER, null) { + @Override + public void handleAction(Object sender, Object target) { + if (tree.getValue() != null && !(tree.areChildrenAllowed((Object) tree.getValue())) + && myUI.getWindows().isEmpty()) { + myUI.addWindow(new CheckUploadModal(tree.getValue().toString(), myUI.getSession())); + } + } + }); content.addComponent(tree); } }); - // Clear user form - clearButton.addClickListener(e ->{ + clearButton.addClickListener(e -> { content.removeAllComponents(); group.clear(); artifact.clear(); @@ -81,10 +101,59 @@ public CentralMavenForm(VaadinSession session){ packaging.select(TypePackaging.jar); content.addComponent(userForm); }); - + content.setSpacing(true); addComponent(content); } - - + + private static class CheckUploadModal extends Window { + public CheckUploadModal(String urlText, VaadinSession session) { + super("Upload " + urlText.substring(urlText.lastIndexOf('/') + 1) + " to buffer?"); + VerticalLayout content = new VerticalLayout(); + content.setWidth("500px"); + content.setHeight("100px"); + + HorizontalLayout buttonLayout = new HorizontalLayout(); + + Button uploadButton = new Button("Upload"); + uploadButton.setStyleName(ValoTheme.BUTTON_PRIMARY); + Button cancelButton = new Button("Cancel"); + + buttonLayout.addComponents(uploadButton, cancelButton); + + buttonLayout.setSpacing(true); + buttonLayout.setMargin(true); + + content.addComponent(buttonLayout); + content.setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER); + + center(); + setClosable(false); + setResizable(false); + + uploadButton.addClickListener(e -> { + File file; + try { + URL url = new URL(urlText); + file = new File(url.toString()); + InputStream input = url.openStream(); + Activator.instance().getBuffer(session.getSession()).put(file.getName(), input); + Notification notif = new Notification("Info", "Artefact from central maven upload sucess", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } catch (IOException | RefusedArtifactException ex) { + new Notification("Could not open or load file from url", ex.getMessage(), Notification.Type.ERROR_MESSAGE) + .show(Page.getCurrent()); + } + close(); + }); + + cancelButton.addClickListener(e -> { + close(); + }); + + setContent(content); + } + } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java index 1f4f89e7..ebf82025 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; import java.nio.file.Files; import java.nio.file.StandardOpenOption; @@ -154,7 +155,8 @@ public DefinedMavenForm(MyUI myUI) { public void handleAction(Object sender, Object target) { if (tree.getValue() != null && !(tree.areChildrenAllowed((Object) tree.getValue())) && myUI.getWindows().isEmpty()) { - myUI.addWindow(new CheckUploadModal(tree.getValue().toString(), settings, myUI.getSession())); + myUI.addWindow( + new CheckUploadModal(tree.getValue().toString(), settings, myUI.getSession())); } } }); @@ -209,18 +211,24 @@ public CheckUploadModal(String artifactText, SettingsUrl settings, VaadinSession uploadButton.addClickListener(e -> { // First check the artifact storage in the local repository if (DefinedMaven.resolveArtefact(artifactText, settings)) { - File file = new File(settings.getLocalAetherUrl() + "/" + artifactText.split(":")[0].replace('.', '/') + "/" + - artifactText.split(":")[1] + "/" + artifactText.split(":")[2] + "/" + artifactText.split(":")[1] + - "-" + artifactText.split(":")[2] +"." + artifactText.split(":")[3]); + File file = new File(settings.getLocalAetherUrl() + "/" + + artifactText.split(":")[0].replace('.', '/') + "/" + artifactText.split(":")[1] + "/" + + artifactText.split(":")[2] + "/" + artifactText.split(":")[1] + "-" + + artifactText.split(":")[2] + "." + artifactText.split(":")[3]); try { - Activator.instance().getBuffer(session.getSession()).put(file.getName(), Files.newInputStream(file.toPath(), StandardOpenOption.READ)); - Notification notif = new Notification("Info", "Artifact to buffer upload sucess", - Notification.Type.ASSISTIVE_NOTIFICATION); - notif.setPosition(Position.TOP_RIGHT); - notif.show(Page.getCurrent()); + InputStream is = Files.newInputStream(file.toPath(), StandardOpenOption.READ); + try { + Activator.instance().getBuffer(session.getSession()).put(file.getName(), is); + Notification notif = new Notification("Info", "Artifact to buffer upload sucess", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } finally { + is.close(); + } } catch (IOException | RefusedArtifactException ex) { new Notification("Could not open file", ex.getMessage(), Notification.Type.ERROR_MESSAGE) - .show(Page.getCurrent()); + .show(Page.getCurrent()); } } else { new Notification("Problem with resolving artifact", Notification.Type.WARNING_MESSAGE) diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LoadFileForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LoadFileForm.java index e5a73c09..f82b51e9 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LoadFileForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LoadFileForm.java @@ -80,7 +80,6 @@ public LoadFileForm(VaadinSession session){ new Notification("Could not open or load file from url", ex.getMessage(), Notification.Type.ERROR_MESSAGE) .show(Page.getCurrent()); } - }); addComponent(content); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java index 752bc82b..b1cf006a 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; @@ -55,12 +56,12 @@ public LocalMavenForm(MyUI myUI) { localMavenTree.addShortcutListener(new ShortcutListener("", KeyCode.ENTER, null) { @Override public void handleAction(Object sender, Object target) { - if (localMavenTree.getValue() != null && myUI.getWindows().isEmpty()){ - if(localMavenTree.areChildrenAllowed((Object) localMavenTree.getValue())){ + if (localMavenTree.getValue() != null && myUI.getWindows().isEmpty()) { + if (localMavenTree.areChildrenAllowed((Object) localMavenTree.getValue())) { myUI.addWindow(new RemovePathModal(new File(localMavenTree.getValue().toString()), myUI)); - } - else{ - myUI.addWindow(new CheckUploadModal(new File(localMavenTree.getValue().toString()), myUI.getSession())); + } else { + myUI.addWindow(new CheckUploadModal(new File(localMavenTree.getValue().toString()), + myUI.getSession())); } } } @@ -68,7 +69,7 @@ public void handleAction(Object sender, Object target) { } addComponent(content); } - + private static class CheckUploadModal extends Window { public CheckUploadModal(File file, VaadinSession session) { super("Upload " + file.getName() + " to buffer?"); @@ -77,7 +78,7 @@ public CheckUploadModal(File file, VaadinSession session) { content.setHeight("100px"); HorizontalLayout buttonLayout = new HorizontalLayout(); - + Button acceptButton = new Button("OK"); acceptButton.setStyleName(ValoTheme.BUTTON_PRIMARY); Button cancelButton = new Button("Cancel"); @@ -93,19 +94,23 @@ public CheckUploadModal(File file, VaadinSession session) { center(); setClosable(false); setResizable(false); - - acceptButton.addClickListener(e ->{ + + acceptButton.addClickListener(e -> { try { - Activator.instance().getBuffer(session.getSession()).put(file.getName(), Files.newInputStream(file.toPath(), StandardOpenOption.READ)); - Notification notif = new Notification("Info", "Artifact to buffer upload sucess", - Notification.Type.ASSISTIVE_NOTIFICATION); - notif.setPosition(Position.TOP_RIGHT); - notif.show(Page.getCurrent()); + InputStream is = Files.newInputStream(file.toPath(), StandardOpenOption.READ); + try { + Activator.instance().getBuffer(session.getSession()).put(file.getName(), is); + Notification notif = new Notification("Info", "Artifact to buffer upload sucess", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } finally { + is.close(); + close(); + } } catch (IOException | RefusedArtifactException ex) { new Notification("Could not open file", ex.getMessage(), Notification.Type.ERROR_MESSAGE) - .show(Page.getCurrent()); - } finally { - close(); + .show(Page.getCurrent()); } }); @@ -116,16 +121,16 @@ public CheckUploadModal(File file, VaadinSession session) { setContent(content); } } - + private static class RemovePathModal extends Window { - public RemovePathModal(File file, MyUI myUI){ + public RemovePathModal(File file, MyUI myUI) { super("Remove path " + file.getName() + "?"); VerticalLayout content = new VerticalLayout(); content.setWidth("400px"); content.setHeight("100px"); HorizontalLayout buttonLayout = new HorizontalLayout(); - + Button removeButton = new Button("Remove"); removeButton.setStyleName(ValoTheme.BUTTON_DANGER); Button cancelButton = new Button("Cancel"); @@ -141,32 +146,32 @@ public RemovePathModal(File file, MyUI myUI){ center(); setClosable(false); setResizable(false); - - removeButton.addClickListener(e ->{ + + removeButton.addClickListener(e -> { Path directory = file.toPath(); try { Files.walkFileTree(directory, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } }); } catch (IOException ex) { new Notification("Could not remove path!", ex.getMessage(), Notification.Type.ERROR_MESSAGE) - .show(Page.getCurrent()); - } finally{ + .show(Page.getCurrent()); + } finally { close(); myUI.setContentBodyLocalMaven(); } }); - + cancelButton.addClickListener(e -> { close(); }); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java index b61b7c83..ecd9560c 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java @@ -4,81 +4,114 @@ import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; import com.vaadin.server.FontAwesome; import com.vaadin.server.VaadinSession; import com.vaadin.ui.Tree; public class CentralMaven { - private static String centralMavenUrl; + private String centralMavenUrl; + private boolean enableGroupSearch; private Tree resultSearchTree = new Tree("Result Search"); private VaadinSession session; - - public CentralMaven(VaadinSession session){ + + public CentralMaven(VaadinSession session) { this.session = session; } - + public Tree getTree(String group, String artifact, String version, Object packaging) { + if (session.getAttribute("settingsUrl") == null) { + SettingsUrl settings = new SettingsUrl(); + centralMavenUrl = settings.getCentralMavenUrl(); + enableGroupSearch = settings.isEnableGroupSearch(); + } else { + centralMavenUrl = ((SettingsUrl) session.getAttribute("settingsUrl")).getCentralMavenUrl(); + enableGroupSearch = ((SettingsUrl) session.getAttribute("settingsUrl")).isEnableGroupSearch(); + } // reset tree resultSearchTree.removeAllItems(); - directSearch(group, artifact, version, packaging.toString()); - // is tree empty? - if(resultSearchTree.size() == 0){ - return null; + if (!artifact.isEmpty() || !version.isEmpty()) { + directSearch(group, artifact, version, packaging.toString()); + } else if (enableGroupSearch && !group.isEmpty()) { + onlyGroupSearch(group); } - else{ + if (resultSearchTree.size() == 0) { + return null; + } else { return resultSearchTree; } } - - private void directSearch(String group, String artifact, String version, String packaging){ + + private void directSearch(String group, String artifact, String version, String packaging) { URL website; - if(session.getAttribute("settingsUrl") == null){ - SettingsUrl settings = new SettingsUrl(); - centralMavenUrl = settings.getCentralMavenUrl(); - } - else{ - centralMavenUrl = ((SettingsUrl)session.getAttribute("settingsUrl")).getCentralMavenUrl(); - } try { - website = new URL(centralMavenUrl + group.replace('.', '/') + "/" + artifact + "/" + version - + "/" + artifact + "-" + version + "." + packaging); + website = new URL(centralMavenUrl + group.replace('.', '/') + "/" + artifact + "/" + version + "/" + + artifact + "-" + version + "." + packaging); ReadableByteChannel rbc = Channels.newChannel(website.openStream()); - if(rbc.isOpen()){ + if (rbc.isOpen()) { String[] pom = group.split("\\."); // adding group resultSearchTree.addItem(pom[0]); - for(int i=1; i< pom.length; i++){ + for (int i = 1; i < pom.length; i++) { resultSearchTree.addItem(pom[i]); - resultSearchTree.setParent(pom[i], pom[i-1]); + resultSearchTree.setParent(pom[i], pom[i - 1]); } resultSearchTree.addItem(artifact); - resultSearchTree.setParent(artifact, pom[pom.length-1]); + resultSearchTree.setParent(artifact, pom[pom.length - 1]); resultSearchTree.addItem(version); - resultSearchTree.setParent(version,artifact); - //end artifact + resultSearchTree.setParent(version, artifact); + // end artifact resultSearchTree.addItem(website.toString()); - resultSearchTree.setParent(website.toString(),version); + resultSearchTree.setParent(website.toString(), version); resultSearchTree.setItemCaption(website.toString(), artifact + "-" + version + "." + packaging); - resultSearchTree.setChildrenAllowed(website.toString(),false); - if(packaging.equals("jar") || packaging.equals("war")){ - resultSearchTree.setItemIcon(website.toString(), FontAwesome.GIFT); - } - else if(packaging.equals("xml") || packaging.equals("pom")){ - resultSearchTree.setItemIcon(website.toString(), FontAwesome.CODE); - } - else{ - resultSearchTree.setItemIcon(website.toString(), FontAwesome.FILE); - } - + resultSearchTree.setChildrenAllowed(website.toString(), false); + if (packaging.equals("jar") || packaging.equals("war")) { + resultSearchTree.setItemIcon(website.toString(), FontAwesome.GIFT); + } else if (packaging.equals("xml") || packaging.equals("pom")) { + resultSearchTree.setItemIcon(website.toString(), FontAwesome.CODE); + } else { + resultSearchTree.setItemIcon(website.toString(), FontAwesome.FILE); + } rbc.close(); - - // real download from url - /*FileOutputStream fos = new FileOutputStream("information.html"); - fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);*/ - } } catch (IOException e) { resultSearchTree.clear(); } } + + private void onlyGroupSearch(String group) { + try { + list(new URL(centralMavenUrl + group.replace('.', '/') + "/")); + } catch (IOException e) { + //resultSearchTree.addItem(centralMavenUrl + group.replace('.', '/')); + resultSearchTree.clear(); + } + } + + private void list(URL path) throws IOException { + Document doc = Jsoup.connect(path.toString()).get(); + for (Element file : doc.select("a").not("[href=../]")) { + if (file.text().endsWith("/")) { + resultSearchTree.addItem(path.toString() + file.text()); + resultSearchTree.setItemCaption(path.toString() + file.text(), + file.text().substring(0, (file.text().length() - 1))); + resultSearchTree.setParent(path.toString() + file.text(), path.toString()); + list(new URL(path.toString() + file.text())); + } else { + resultSearchTree.addItem(path.toString() + file.text()); + resultSearchTree.setItemCaption(path.toString() + file.text(), file.text()); + resultSearchTree.setParent(path.toString() + file.text(), path.toString()); + resultSearchTree.setChildrenAllowed(path.toString() + file.text(), false); + if (file.text().endsWith(".jar") || file.text().endsWith(".war")) { + resultSearchTree.setItemIcon(path.toString() + file.text(), FontAwesome.GIFT); + } else if (file.text().endsWith(".xml") || file.text().endsWith(".pom")) { + resultSearchTree.setItemIcon(path.toString() + file.text(), FontAwesome.CODE); + } else { + resultSearchTree.setItemIcon(path.toString() + file.text(), FontAwesome.FILE); + } + } + } + } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/SettingsUrl.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/SettingsUrl.java index 98e0aea0..99ae929c 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/SettingsUrl.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/SettingsUrl.java @@ -4,6 +4,7 @@ public class SettingsUrl{ private String centralMavenUrl = "http://repo.maven.apache.org/maven2/"; private String localAetherUrl = "aether-local-repo"; private String externalAetherUrl = "http://repo.maven.apache.org/maven2/"; + private boolean enableGroupSearch = false; public String getCentralMavenUrl() { return centralMavenUrl; @@ -29,4 +30,11 @@ public void setExternalAetherUrl(String url) { this.externalAetherUrl = url; } + public boolean isEnableGroupSearch() { + return enableGroupSearch; + } + + public void setEnableGroupSearch(boolean enableGroupSearch) { + this.enableGroupSearch = enableGroupSearch; + } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java index 50779ce9..e6fb02f4 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java @@ -102,7 +102,7 @@ public void setContentBodyLocalMaven(){ } public void setContentBodyCentralMaven(){ - centralMavenForm = new CentralMavenForm(getSession()); + centralMavenForm = new CentralMavenForm(this); body.setContent(centralMavenForm); } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java index 8ac2ee45..12ce9e1d 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java @@ -6,6 +6,7 @@ import com.vaadin.shared.Position; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.ui.Button; +import com.vaadin.ui.CheckBox; import com.vaadin.ui.FormLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Notification; @@ -26,6 +27,7 @@ public SettingsForm() { public SettingsForm(VaadinSession session) { TextField centralMavenUrl = new TextField("Central Maven url"); TextField localAetherRepo = new TextField("Local Aether repository"); + CheckBox enableGroupSearch = new CheckBox("Enable only group search"); centralMavenUrl.setWidth("400px"); localAetherRepo.setWidth("400px"); @@ -36,9 +38,11 @@ public SettingsForm(VaadinSession session) { SettingsUrl settingsUrl = new SettingsUrl(); centralMavenUrl.setValue(settingsUrl.getCentralMavenUrl()); localAetherRepo.setValue(settingsUrl.getLocalAetherUrl()); + enableGroupSearch.setValue(false); } else { centralMavenUrl.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getCentralMavenUrl()); localAetherRepo.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getLocalAetherUrl()); + enableGroupSearch.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).isEnableGroupSearch()); } HorizontalLayout buttonsLayout = new HorizontalLayout(); @@ -51,7 +55,7 @@ public SettingsForm(VaadinSession session) { saveButton.setClickShortcut(KeyCode.ENTER); VerticalLayout content = new VerticalLayout(); - content.addComponents(centralMavenUrl, localAetherRepo, buttonsLayout); + content.addComponents(centralMavenUrl, localAetherRepo, enableGroupSearch, buttonsLayout); content.setSpacing(true); HorizontalLayout formLayout = new HorizontalLayout(); @@ -68,6 +72,7 @@ public SettingsForm(VaadinSession session) { } settingsUrl.setCentralMavenUrl(centralMavenUrl.getValue()); settingsUrl.setLocalAetherUrl(localAetherRepo.getValue()); + settingsUrl.setEnableGroupSearch(enableGroupSearch.getValue()); getSession().setAttribute("settingsUrl", settingsUrl); Notification notif = new Notification("Info", "Settings saved successfully" , Notification.Type.ASSISTIVE_NOTIFICATION); @@ -80,6 +85,7 @@ public SettingsForm(VaadinSession session) { getSession().setAttribute("settingsUrl", settingsUrl); centralMavenUrl.setValue(settingsUrl.getCentralMavenUrl()); localAetherRepo.setValue(settingsUrl.getLocalAetherUrl()); + enableGroupSearch.setValue(settingsUrl.isEnableGroupSearch()); }); addComponent(formLayout); From 30c3e2cc92bdaaa2242840d66ae65a1e1bd87749 Mon Sep 17 00:00:00 2001 From: rpesek Date: Thu, 31 Aug 2017 10:06:20 +0200 Subject: [PATCH 08/85] Fix of recognition extension artefact by resolving and uploading functions. --- .../kiv/crce/crce_webui_vaadin/outer/classes/DefinedMaven.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/DefinedMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/DefinedMaven.java index a1229a08..7d4db89d 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/DefinedMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/DefinedMaven.java @@ -128,7 +128,7 @@ public static boolean resolveArtefact(String artifactText, SettingsUrl settings) ArtifactRequest artifactRequest = new ArtifactRequest(); Artifact artifact = new DefaultArtifact(artifactText.split(":")[0] + ":" + artifactText.split(":")[1] + ":" + - artifactText.split(":")[2]); + artifactText.split(":")[3] + ":" + artifactText.split(":")[2]); artifactRequest.setArtifact(artifact); From a8e67dcb1c3316f9888a2ee314541ccff749b7c7 Mon Sep 17 00:00:00 2001 From: rpesek Date: Mon, 11 Sep 2017 10:59:25 +0200 Subject: [PATCH 09/85] Indexing function of the central Maven repository Added the artifact indexing and index search feature in the Maven repository index. --- build/pom.xml | 4 +- modules/crce-webui-vaadin/pom.xml | 94 ++++++-- .../outer/CentralMavenForm.java | 62 +++++- .../outer/CheckMavenIndexForm.java | 79 +++++++ .../outer/classes/CentralMaven.java | 104 ++++++++- .../outer/classes/MavenIndex.java | 210 ++++++++++++++++++ .../crce_webui_vaadin/webui/MenuForm.java | 1 + .../crce/crce_webui_vaadin/webui/MyUI.java | 10 + 8 files changed, 529 insertions(+), 35 deletions(-) create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CheckMavenIndexForm.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/MavenIndex.java diff --git a/build/pom.xml b/build/pom.xml index 6b079fb9..b9e085e0 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -456,7 +456,7 @@ - + org.codehaus.plexus plexus-utils @@ -470,7 +470,6 @@ jar provided - commons-beanutils commons-beanutils @@ -483,7 +482,6 @@ 3.3.2 provided - org.apache.felix org.apache.felix.utils diff --git a/modules/crce-webui-vaadin/pom.xml b/modules/crce-webui-vaadin/pom.xml index ae08db4a..0623a2cc 100644 --- a/modules/crce-webui-vaadin/pom.xml +++ b/modules/crce-webui-vaadin/pom.xml @@ -4,11 +4,11 @@ 4.0.0 - ../pom - cz.zcu.kiv.crce - crce-modules-parent - 2.1.1-SNAPSHOT - + ../pom + cz.zcu.kiv.crce + crce-modules-parent + 2.1.1-SNAPSHOT + crce-webui-vaadin war @@ -19,7 +19,7 @@ CRCE - Web UI (Vaadin) - ${namespace}.crce_webui_vaadin + ${namespace}.crce_webui_vaadin 7.7.10 7.7.10 9.3.9.v20160517 @@ -73,11 +73,6 @@ maven-aether-provider 3.3.9 - - org.slf4j - slf4j-simple - 1.7.22 - org.apache.maven maven-artifact @@ -88,6 +83,36 @@ plexus-utils 3.0.22 + + org.apache.maven.indexer + indexer-core + 5.1.2-4333789 + + + org.apache.maven.wagon + wagon-http-lightweight + 2.3 + + + org.eclipse.sisu + org.eclipse.sisu.plexus + 0.3.3 + + + org.eclipse.aether + aether-util + 1.1.0 + + + org.slf4j + slf4j-simple + 1.7.22 + + + org.sonatype.sisu + sisu-guice + 3.2.6 + @@ -133,10 +158,6 @@ org.apache.maven maven-aether-provider - - org.slf4j - slf4j-simple - org.apache.maven maven-artifact @@ -145,6 +166,30 @@ org.codehaus.plexus plexus-utils + + org.apache.maven.indexer + indexer-core + + + org.apache.maven.wagon + wagon-http-lightweight + + + org.eclipse.sisu + org.eclipse.sisu.plexus + + + org.eclipse.aether + aether-util + + + org.slf4j + slf4j-simple + + + org.sonatype.sisu + sisu-guice + cz.zcu.kiv.crce crce-metadata-osgi-bundle @@ -158,7 +203,7 @@ bundle - + @@ -239,13 +284,13 @@ ${project.artifactId} WEB-INF/classes, - WEB-INF/lib/aether-api-1.1.0.jar, + WEB-INF/lib/aether-api-1.13.1.jar, WEB-INF/lib/aether-connector-basic-1.1.0.jar, WEB-INF/lib/aether-impl-1.1.0.jar, WEB-INF/lib/aether-spi-1.1.0.jar, WEB-INF/lib/aether-transport-file-1.1.0.jar, WEB-INF/lib/aether-transport-http-1.1.0.jar, - WEB-INF/lib/aether-util-1.1.0.jar, + WEB-INF/lib/aether-util-1.13.1.jar, WEB-INF/lib/atmosphere-runtime-2.2.9.vaadin2.jar, WEB-INF/lib/commons-codec-1.6.jar, WEB-INF/lib/crce-external-repository-1.0.jar, @@ -271,7 +316,18 @@ WEB-INF/lib/vaadin-server-7.7.10.jar, WEB-INF/lib/vaadin-shared-7.7.10.jar, WEB-INF/lib/vaadin-slf4j-jdk14-1.6.1.jar, - WEB-INF/lib/vaadin-themes-7.7.10.jar + WEB-INF/lib/vaadin-themes-7.7.10.jar, + WEB-INF/lib/org.eclipse.sisu.plexus-0.3.3.jar, + WEB-INF/lib/org.eclipse.sisu.inject-0.3.3.jar, + WEB-INF/lib/wagon-provider-api-2.3.jar, + WEB-INF/lib/wagon-http-shared4-2.3.jar, + WEB-INF/lib/wagon-http-lightweight-2.3.jar, + WEB-INF/lib/indexer-core-5.1.2-4333789.jar, + WEB-INF/lib/indexer-artifact-5.1.2-4333789.jar, + WEB-INF/lib/lucene-core-3.6.2.jar, + WEB-INF/lib/lucene-queries-3.6.2.jar, + WEB-INF/lib/lucene-memory-3.6.2.jar, + WEB-INF/lib/lucene-highlighter-3.6.2.jar crce-vaadin crce-vaadin diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java index 6407f390..ef86cb96 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java @@ -19,6 +19,7 @@ import com.vaadin.ui.Label; import com.vaadin.ui.NativeSelect; import com.vaadin.ui.Notification; +import com.vaadin.ui.OptionGroup; import com.vaadin.ui.TextField; import com.vaadin.ui.Tree; import com.vaadin.ui.VerticalLayout; @@ -38,6 +39,8 @@ public class CentralMavenForm extends FormLayout { private TextField artifact = new TextField("Artifact Id"); private TextField version = new TextField("Version"); private NativeSelect packaging = new NativeSelect("Packaging"); + private OptionGroup directIndexOption = new OptionGroup("Direct or search index"); + private NativeSelect rangeOption = new NativeSelect("Range"); private Button searchButton = new Button("Search"); private Button clearButton = new Button("Clear"); private Label notFound = new Label("No artifact found"); @@ -51,15 +54,32 @@ public CentralMavenForm() { public CentralMavenForm(MyUI myUI) { VerticalLayout userForm = new VerticalLayout(); HorizontalLayout content = new HorizontalLayout(); + HorizontalLayout versionLayout = new HorizontalLayout(); packaging.addItems(EnumSet.allOf(TypePackaging.class)); packaging.select(TypePackaging.jar); packaging.setNullSelectionAllowed(false); + + group.setWidth("250px"); + artifact.setWidth("250px"); + + directIndexOption.addItems("Direct", "Index"); + directIndexOption.setValue("Direct"); + + rangeOption.addItem("<="); + rangeOption.addItem("="); + rangeOption.addItem(">="); + rangeOption.select("="); + rangeOption.setNullSelectionAllowed(false); + rangeOption.setEnabled(false); + + versionLayout.addComponents(version, rangeOption); + versionLayout.setSpacing(true); searchButton.setStyleName(ValoTheme.BUTTON_PRIMARY); HorizontalLayout buttons = new HorizontalLayout(searchButton, clearButton); buttons.setSpacing(true); - userForm.addComponents(caption, group, artifact, version, packaging, buttons); + userForm.addComponents(caption, group, artifact, versionLayout, packaging, directIndexOption, buttons); userForm.setSpacing(true); userForm.setMargin(new MarginInfo(false, true)); content.addComponent(userForm); @@ -74,8 +94,29 @@ public CentralMavenForm(MyUI myUI) { content.removeComponent(tree); } // check exist component from central Maven repository - tree = new CentralMaven(myUI.getSession()).getTree(group.getValue(), artifact.getValue(), version.getValue(), - packaging.getValue()); + if(directIndexOption.getValue().equals("Direct")){ + tree = new CentralMaven(myUI.getSession()).getTree(group.getValue(), artifact.getValue(), version.getValue(), + packaging.getValue(), directIndexOption.getValue(), null); + } + else{ + if(group.getValue().trim().isEmpty() || artifact.getValue().trim().isEmpty()){ + Notification notif = new Notification("Incomplete assignment!", + Notification.Type.WARNING_MESSAGE); + notif.setDelayMsec(5000); + notif.show(Page.getCurrent()); + } + else if(group.getValue().charAt(0) == '*' || group.getValue().charAt(0) == '?' || artifact.getValue().charAt(0) == '*' + || artifact.getValue().charAt(0) == '?'){ + Notification notif = new Notification("Can not start a search term with '*' or '?'", + Notification.Type.WARNING_MESSAGE); + notif.setDelayMsec(5000); + notif.show(Page.getCurrent()); + } + else{ + tree = new CentralMaven(myUI.getSession()).getTree(group.getValue(), artifact.getValue(), version.getValue(), + packaging.getValue(), directIndexOption.getValue(), rangeOption.getValue().toString()); + } + } if (tree == null) { content.addComponent(notFound); } else { @@ -91,6 +132,21 @@ public void handleAction(Object sender, Object target) { content.addComponent(tree); } }); + + directIndexOption.addValueChangeListener(e ->{ + if(directIndexOption.getValue().equals("Direct")){ + rangeOption.setEnabled(false); + group.setRequired(false); + artifact.setRequired(false); + } + else{ + rangeOption.setEnabled(true); + group.setRequired(true); + group.setRequiredError("The item can not be empty!"); + artifact.setRequired(true); + artifact.setRequiredError("The item can not be empty!"); + } + }); // Clear user form clearButton.addClickListener(e -> { diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CheckMavenIndexForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CheckMavenIndexForm.java new file mode 100644 index 00000000..e6c30936 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CheckMavenIndexForm.java @@ -0,0 +1,79 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.outer; + +import com.vaadin.server.VaadinSession; +import com.vaadin.ui.Button; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.ProgressBar; +import com.vaadin.ui.VerticalLayout; +import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.MavenIndex; +import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; + +@SuppressWarnings("serial") +public class CheckMavenIndexForm extends FormLayout { + private Button checkButton = new Button("Check index"); + private ProgressBar bar = new ProgressBar(); + private Label statusLabel = new Label("This might take a while on first run, so please be patient!"); + private MyUI myUI; + private String result; + + public CheckMavenIndexForm(MyUI myUI) { + this.myUI = myUI; + VerticalLayout content = new VerticalLayout(); + HorizontalLayout progressLayout = new HorizontalLayout(); + bar.setVisible(false); + + checkButton.addClickListener(e -> { + statusLabel.setValue("Please waiting..."); + checkButton.setEnabled(false); + bar.setIndeterminate(true); + bar.setVisible(true); + new HelperIndexingThread(myUI.getSession()).start(); + }); + + progressLayout.addComponents(checkButton, bar); + progressLayout.setSpacing(true); + content.addComponents(statusLabel, progressLayout); + content.setSpacing(true); + addComponent(content); + } + + class HelperIndexingThread extends Thread { + VaadinSession session; + public HelperIndexingThread(VaadinSession session){ + this.session = session; + } + public void run() { + try { + MavenIndex check = new MavenIndex(); + result = check.checkIndex(session); + } catch (Exception e) { + e.printStackTrace(); + } finally { + myUI.access(() -> checkButton.setEnabled(true)); + myUI.access(() -> bar.setVisible(false)); + myUI.access(() -> bar.setIndeterminate(false)); + if (result != null) { + myUI.access(() -> statusLabel.setValue(result)); + } + else{ + myUI.access(() -> statusLabel.setValue("Error when creating index!")); + } + } + // Inform that we have stopped running + + /*// Another way without using lambda expressions + myUI.access(new Runnable() { + @Override + public void run() { + statusLabel.setValue("Done!"); + checkButton.setEnabled(true); + bar.setIndeterminate(false); + bar.setVisible(false); + } + });*/ + + } + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java index ecd9560c..997ca7ec 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java @@ -4,11 +4,16 @@ import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; +import java.util.List; + +import org.apache.maven.index.ArtifactInfo; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import com.vaadin.server.FontAwesome; +import com.vaadin.server.Page; import com.vaadin.server.VaadinSession; +import com.vaadin.ui.Notification; import com.vaadin.ui.Tree; public class CentralMaven { @@ -21,7 +26,8 @@ public CentralMaven(VaadinSession session) { this.session = session; } - public Tree getTree(String group, String artifact, String version, Object packaging) { + public Tree getTree(String group, String artifact, String version, Object packaging, Object directIndex, + String range) { if (session.getAttribute("settingsUrl") == null) { SettingsUrl settings = new SettingsUrl(); centralMavenUrl = settings.getCentralMavenUrl(); @@ -32,15 +38,36 @@ public Tree getTree(String group, String artifact, String version, Object packag } // reset tree resultSearchTree.removeAllItems(); - if (!artifact.isEmpty() || !version.isEmpty()) { - directSearch(group, artifact, version, packaging.toString()); - } else if (enableGroupSearch && !group.isEmpty()) { - onlyGroupSearch(group); + // direct search + if (directIndex.equals("Direct")) { + if (!artifact.isEmpty() || !version.isEmpty()) { + directSearch(group, artifact, version, packaging.toString()); + } else if (enableGroupSearch && !group.isEmpty()) { + onlyGroupSearch(group); + } + if (resultSearchTree.size() == 0) { + return null; + } else { + return resultSearchTree; + } } - if (resultSearchTree.size() == 0) { - return null; - } else { - return resultSearchTree; + // index search + else { + if (session.getAttribute("mavenIndex") != null) { + indexSearch(group, artifact, version, packaging.toString(), range); + if (resultSearchTree.size() == 0) { + return null; + } else { + return resultSearchTree; + } + } else { + Notification notif = new Notification( + "The central maven repository index is not created. Check its creation in the settings menu", + Notification.Type.WARNING_MESSAGE); + notif.setDelayMsec(5000); + notif.show(Page.getCurrent()); + return null; + } } } @@ -85,7 +112,8 @@ private void onlyGroupSearch(String group) { try { list(new URL(centralMavenUrl + group.replace('.', '/') + "/")); } catch (IOException e) { - //resultSearchTree.addItem(centralMavenUrl + group.replace('.', '/')); + // resultSearchTree.addItem(centralMavenUrl + group.replace('.', + // '/')); resultSearchTree.clear(); } } @@ -114,4 +142,60 @@ private void list(URL path) throws IOException { } } } + + private void indexSearch(String group, String artifact, String version, String packaging, String range){ + MavenIndex mavenIndex = null; + try { + mavenIndex = new MavenIndex(); + List artifactInfoList = mavenIndex.searchArtefact(session, group, artifact, version, + packaging, range); + for (ArtifactInfo ai : artifactInfoList) { + URL website; + try { + website = new URL(centralMavenUrl + ai.groupId.replace('.', '/') + "/" + ai.artifactId + "/" + ai.version + "/" + + ai.artifactId + "-" + ai.version + "." + ai.packaging); + ReadableByteChannel rbc = Channels.newChannel(website.openStream()); + if (rbc.isOpen()) { + String[] pom = ai.groupId.split("\\."); + if(resultSearchTree.getItem(pom[0]) == null){ + resultSearchTree.addItem(pom[0]); + } + // adding group + for (int i = 1; i < pom.length; i++) { + if(resultSearchTree.getItem(pom[i]) == null){ + resultSearchTree.addItem(pom[i]); + resultSearchTree.setParent(pom[i], pom[i - 1]); + } + } + // adding artefact and version + resultSearchTree.addItem(ai.artifactId); + resultSearchTree.setParent(ai.artifactId, pom[pom.length - 1]); + resultSearchTree.addItem(ai.version + "-" + ai.artifactId); + resultSearchTree.setItemCaption(ai.version + "-" + ai.artifactId, ai.version); + resultSearchTree.setParent(ai.version + "-" + ai.artifactId , ai.artifactId); + resultSearchTree.addItem(website.toString()); + resultSearchTree.setParent(website.toString(), ai.version + "-" + ai.artifactId); + resultSearchTree.setItemCaption(website.toString(), ai.artifactId + "-" + ai.version + "." + ai.packaging); + resultSearchTree.setChildrenAllowed(website.toString(), false); + if (packaging.equals("jar") || packaging.equals("war")) { + resultSearchTree.setItemIcon(website.toString(), FontAwesome.GIFT); + } else if (packaging.equals("xml") || packaging.equals("pom")) { + resultSearchTree.setItemIcon(website.toString(), FontAwesome.CODE); + } else { + resultSearchTree.setItemIcon(website.toString(), FontAwesome.FILE); + } + rbc.close(); + } + } catch (IOException e) { + resultSearchTree.clear(); + } + } + } + catch (Exception e) { + e.printStackTrace(); + Notification notif = new Notification("Error retrieving artifact from maven index context!", + Notification.Type.ERROR_MESSAGE); + notif.show(Page.getCurrent()); + } + } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/MavenIndex.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/MavenIndex.java new file mode 100644 index 00000000..cffe16d9 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/MavenIndex.java @@ -0,0 +1,210 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.BooleanClause.Occur; +import org.eclipse.aether.version.InvalidVersionSpecificationException; +import org.apache.maven.index.ArtifactInfo; +import org.apache.maven.index.ArtifactInfoFilter; +import org.apache.maven.index.Field; +import org.apache.maven.index.Indexer; +import org.apache.maven.index.IteratorSearchRequest; +import org.apache.maven.index.IteratorSearchResponse; +import org.apache.maven.index.MAVEN; +import org.apache.maven.index.context.IndexCreator; +import org.apache.maven.index.context.IndexingContext; +import org.apache.maven.index.expr.SourcedSearchExpression; +import org.apache.maven.index.updater.IndexUpdateRequest; +import org.apache.maven.index.updater.IndexUpdateResult; +import org.apache.maven.index.updater.IndexUpdater; +import org.apache.maven.index.updater.ResourceFetcher; +import org.apache.maven.index.updater.WagonHelper; +import org.apache.maven.wagon.Wagon; +import org.apache.maven.wagon.events.TransferEvent; +import org.apache.maven.wagon.events.TransferListener; +import org.apache.maven.wagon.observers.AbstractTransferListener; +import org.codehaus.plexus.DefaultPlexusContainer; +import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.PlexusContainerException; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.eclipse.aether.util.version.GenericVersionScheme; +import org.eclipse.aether.version.Version; + +import com.vaadin.server.VaadinSession; + +public class MavenIndex { + private String centralCachePath = "repository-index/central-cache"; + private String centralIndexPath = "repository-index/central-index"; + + public String checkIndex(VaadinSession session) throws Exception { + final MavenIndex indexCentralRepository = new MavenIndex(); + return indexCentralRepository.perform(session); + } + + public List searchArtefact(VaadinSession session, String group, String artifact, + String version, String packaging, String range) throws Exception { + final MavenIndex indexCentralRepository = new MavenIndex(); + return indexCentralRepository.getArtefact(session, group, artifact, version, packaging, range); + } + + private final PlexusContainer plexusContainer; + private final Indexer indexer; + private final IndexUpdater indexUpdater; + private final Wagon httpWagon; + private IndexingContext centralContext; + + public MavenIndex() throws PlexusContainerException, ComponentLookupException { + this.plexusContainer = new DefaultPlexusContainer(); + this.indexer = plexusContainer.lookup(Indexer.class); + this.indexUpdater = plexusContainer.lookup(IndexUpdater.class); + this.httpWagon = plexusContainer.lookup(Wagon.class, "http"); + } + + private String perform(VaadinSession session) + throws IOException, ComponentLookupException, InvalidVersionSpecificationException { + File centralLocalCache = new File(centralCachePath); + File centralIndexDir = new File(centralIndexPath); + + List indexers = new ArrayList(); + + indexers.add(plexusContainer.lookup(IndexCreator.class, "min")); + indexers.add(plexusContainer.lookup(IndexCreator.class, "jarContent")); + indexers.add(plexusContainer.lookup(IndexCreator.class, "maven-plugin")); + + // Create context for central repository index + + if (session.getAttribute("settingsUrl") == null) { + SettingsUrl settingsUrl = new SettingsUrl(); + centralContext = indexer.createIndexingContext("central-context", "central", centralLocalCache, + centralIndexDir, settingsUrl.getCentralMavenUrl(), null, true, true, indexers); + } else { + centralContext = indexer.createIndexingContext("central-context", "central", centralLocalCache, + centralIndexDir, ((SettingsUrl) session.getAttribute("settingsUrl")).getCentralMavenUrl(), null, + true, true, indexers); + } + + System.out.println("Updating Maven Index..."); + + TransferListener listener = new AbstractTransferListener() { + public void transferStarted(TransferEvent transferEvent) { + System.out.print(" Downloading " + transferEvent.getResource().getName()); + } + + public void transferProgress(TransferEvent transferEvent, byte[] buffer, int length) { + + } + + public void transferCompleted(TransferEvent transferEvent) { + System.out.println(" - Done"); + } + }; + + ResourceFetcher resourceFetcher = new WagonHelper.WagonFetcher(httpWagon, listener, null, null); + Date centralContextCurrentTimestamp = centralContext.getTimestamp(); + + IndexUpdateRequest updateRequest = new IndexUpdateRequest(centralContext, resourceFetcher); + IndexUpdateResult updateResult = indexUpdater.fetchAndUpdateIndex(updateRequest); + + closeIndexer(); + + session.setAttribute("mavenIndex", true); + if (updateResult.isFullUpdate()) { + return "Full update happened!"; + } else if (updateResult.getTimestamp().equals(centralContextCurrentTimestamp)) { + return "No update needed, index is up to date!"; + } else { + return "Incremental update happened, change covered " + centralContextCurrentTimestamp + " - " + + updateResult.getTimestamp() + " period."; + } + } + + private List getArtefact(VaadinSession session, String group, String artifact, String version, String packaging, String range) + throws IOException, ComponentLookupException, InvalidVersionSpecificationException { + + File centralLocalCache = new File(centralCachePath); + File centralIndexDir = new File(centralIndexPath); + + List indexers = new ArrayList(); + + indexers.add(plexusContainer.lookup(IndexCreator.class, "min")); + indexers.add(plexusContainer.lookup(IndexCreator.class, "jarContent")); + indexers.add(plexusContainer.lookup(IndexCreator.class, "maven-plugin")); + + // Create context for central repository index + + if (session.getAttribute("settingsUrl") == null) { + SettingsUrl settingsUrl = new SettingsUrl(); + centralContext = indexer.createIndexingContext("central-context", "central", centralLocalCache, + centralIndexDir, settingsUrl.getCentralMavenUrl(), null, true, true, indexers); + } else { + centralContext = indexer.createIndexingContext("central-context", "central", centralLocalCache, + centralIndexDir, ((SettingsUrl) session.getAttribute("settingsUrl")).getCentralMavenUrl(), null, + true, true, indexers); + } + + final GenericVersionScheme versionScheme = new GenericVersionScheme(); + + Version versionIndex = versionScheme.parseVersion(version); + + // construct the query for known GA + final Query groupIdQ = indexer.constructQuery(MAVEN.GROUP_ID, new SourcedSearchExpression(group)); + + final Query artifactIdQ = indexer.constructQuery(MAVEN.ARTIFACT_ID, + new SourcedSearchExpression(artifact)); + + final BooleanQuery query = new BooleanQuery(); + query.add(groupIdQ, Occur.MUST); + query.add(artifactIdQ, Occur.MUST); + // we want custom packaging artifacts only + query.add(indexer.constructQuery(MAVEN.PACKAGING, new SourcedSearchExpression(packaging)), Occur.MUST); + // we want main artifacts only (no classifier) + // Note: this below is unfinished API, needs fixing + query.add(indexer.constructQuery(MAVEN.CLASSIFIER, new SourcedSearchExpression(Field.NOT_PRESENT)), + Occur.MUST_NOT); + + // construct the filter to express "V greater than" + final ArtifactInfoFilter versionFilter = new ArtifactInfoFilter() { + public boolean accepts(final IndexingContext ctx, final ArtifactInfo ai) { + try { + final Version aiV = versionScheme.parseVersion(ai.version); + // Use ">=" if you are INCLUSIVE + if(range.equals("<=")){ + return aiV.compareTo(versionIndex) <= 0; + } + else if(range.equals(">=")){ + return aiV.compareTo(versionIndex) >= 0; + } + else{ + return aiV.compareTo(versionIndex) == 0; + } + + } catch (InvalidVersionSpecificationException e) { + return true; + } + } + }; + + final IteratorSearchRequest request = new IteratorSearchRequest(query, + Collections.singletonList(centralContext), versionFilter); + final IteratorSearchResponse response = indexer.searchIterator(request); + List artifactInfoList = new ArrayList(); + for (ArtifactInfo ai : response) { + artifactInfoList.add(ai); + } + + closeIndexer(); + + return artifactInfoList; + } + + public void closeIndexer() throws IOException{ + indexer.closeIndexingContext(centralContext, false); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java index 0ddac8d0..d3bc1083 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java @@ -35,6 +35,7 @@ public MenuForm(MyUI myUI) { repository.addItem("Plugins", e ->{myUI.setContentBodyPlugins();}); // submenu settings + settings.addItem("Index", e ->{myUI.setContentBodyCheckMavenIndexForm();}); settings.addItem("Paths", e ->{myUI.setContentSettings();}); // Menu login diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java index e6fb02f4..9563df5f 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java @@ -1,6 +1,8 @@ package cz.zcu.kiv.crce.crce_webui_vaadin.webui; import javax.servlet.annotation.WebServlet; + +import com.vaadin.annotations.Push; import com.vaadin.annotations.Theme; import com.vaadin.annotations.VaadinServletConfiguration; import com.vaadin.server.Page; @@ -11,6 +13,7 @@ import com.vaadin.ui.VerticalLayout; import cz.zcu.kiv.crce.crce_webui_vaadin.outer.CentralMavenForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.outer.CheckMavenIndexForm; import cz.zcu.kiv.crce.crce_webui_vaadin.outer.DefinedMavenForm; import cz.zcu.kiv.crce.crce_webui_vaadin.outer.LoadFileForm; import cz.zcu.kiv.crce.crce_webui_vaadin.outer.LocalMavenForm; @@ -27,12 +30,14 @@ */ @SuppressWarnings("serial") @Theme("mytheme") +@Push public class MyUI extends UI { private Panel head = new Panel(); private Panel body = new Panel(); private Panel footer = new Panel(); private LocalMavenForm localMavenForm; private CentralMavenForm centralMavenForm; + private CheckMavenIndexForm checkMavenIndexFrom; private DefinedMavenForm definedMavenForm; private LoadFileForm loadFileForm; private BufferForm bufferForm; @@ -106,6 +111,11 @@ public void setContentBodyCentralMaven(){ body.setContent(centralMavenForm); } + public void setContentBodyCheckMavenIndexForm(){ + checkMavenIndexFrom = new CheckMavenIndexForm(this); + body.setContent(checkMavenIndexFrom); + } + public void setContentBodyDefinedMaven(){ definedMavenForm = new DefinedMavenForm(this); body.setContent(definedMavenForm); From 6b18d755b14d02f39927035a3e4cf394ee8d07c2 Mon Sep 17 00:00:00 2001 From: rpesek Date: Mon, 25 Sep 2017 10:02:20 +0200 Subject: [PATCH 10/85] Repository Web UI (Buffer Form, Store Form, Resource details) Supported User Forms Store, Buffer, and Resource Details (properties, capability, requirements) --- .../outer/CentralMavenForm.java | 2 + .../outer/DefinedMavenForm.java | 2 + .../outer/LocalMavenForm.java | 2 + .../repository/ArtefactDetailForm.java | 177 ++++++++++++++++++ .../repository/BufferForm.java | 85 ++++++--- .../repository/NewCapabilityForm.java | 44 +++++ ...luginFormEdit.java => PluginEditForm.java} | 4 +- .../repository/PluginsForm.java | 12 +- .../repository/StoreForm.java | 132 ++++++++++++- .../classes/CapabilityAttributeBean.java | 52 +++++ .../classes/RequirementAttributeBean.java | 52 +++++ .../repository/classes/ResourceBean.java | 8 +- .../repository/services/ResourceService.java | 93 ++++++++- .../crce_webui_vaadin/webui/MenuForm.java | 2 +- .../crce/crce_webui_vaadin/webui/MyUI.java | 17 +- 15 files changed, 642 insertions(+), 42 deletions(-) create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/ArtefactDetailForm.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/NewCapabilityForm.java rename modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/{PluginFormEdit.java => PluginEditForm.java} (96%) create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/CapabilityAttributeBean.java create mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/RequirementAttributeBean.java diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java index ef86cb96..13efabc4 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java @@ -59,6 +59,8 @@ public CentralMavenForm(MyUI myUI) { packaging.select(TypePackaging.jar); packaging.setNullSelectionAllowed(false); + caption.addStyleName(ValoTheme.LABEL_BOLD); + group.setWidth("250px"); artifact.setWidth("250px"); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java index ebf82025..cf313771 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java @@ -67,6 +67,8 @@ public DefinedMavenForm(MyUI myUI) { HorizontalLayout treeLayout = new HorizontalLayout(); VerticalLayout formLayout = new VerticalLayout(); HorizontalLayout content = new HorizontalLayout(); + + caption.addStyleName(ValoTheme.LABEL_BOLD); definedUrl.setWidth("450px"); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java index b1cf006a..5d3a0f79 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java @@ -44,6 +44,8 @@ public LocalMavenForm() { public LocalMavenForm(MyUI myUI) { VerticalLayout content = new VerticalLayout(); + caption.addStyleName(ValoTheme.LABEL_BOLD); + // Tree of Maven local repository Tree localMavenTree = localMaven.getTree(myUI.getSession()); content.setMargin(new MarginInfo(false, true)); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/ArtefactDetailForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/ArtefactDetailForm.java new file mode 100644 index 00000000..8e4aeaa8 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/ArtefactDetailForm.java @@ -0,0 +1,177 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.repository; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.data.util.BeanItemContainer; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Grid; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.TabSheet; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.CapabilityAttributeBean; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.RequirementAttributeBean; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.metadata.Attribute; +import cz.zcu.kiv.crce.metadata.Capability; +import cz.zcu.kiv.crce.metadata.Requirement; + +@SuppressWarnings("serial") +public class ArtefactDetailForm extends FormLayout{ + private Label resourceLabel = new Label(); + private TabSheet tabsheet = new TabSheet(); + private Button buttonBackProperties = new Button("Back"); + private Button buttonBackCapabilities = new Button("Back"); + private Button buttonBackRequirements = new Button("Back"); + private Button buttonAddCapability = new Button("Add capability"); + private Button buttonAddRequirements = new Button("Add requirement"); + private Grid gridCapabilities = new Grid(); + private Grid gridRequirements = new Grid(); + + public ArtefactDetailForm(MyUI myUI, ResourceBean resourceBean, boolean isFromStore){ + VerticalLayout content = new VerticalLayout(); + + resourceLabel.setValue("Details of artefact: " + resourceBean.getPresentationName()); + resourceLabel.addStyleName(ValoTheme.LABEL_BOLD); + + // display property + VerticalLayout propertyContentLayout = new VerticalLayout(); + HorizontalLayout buttonPropertyLayout = new HorizontalLayout(); + + Label propertiesValues = new Label("
    "+ + "
  • Id: " + resourceBean.getResource().getId() + "
  • " + + "
  • Symbolic name: "+ resourceBean.getSymbolicName() + "
  • " + + "
  • Size: " + resourceBean.getSize() + "
  • " + + "
", ContentMode.HTML); + + buttonBackProperties.setWidth("130px"); + buttonPropertyLayout.addComponent(buttonBackProperties); + + propertyContentLayout.addComponents(propertiesValues, buttonPropertyLayout); + propertyContentLayout.setComponentAlignment(buttonPropertyLayout, Alignment.BOTTOM_CENTER); + propertyContentLayout.setSpacing(true); + propertyContentLayout.setMargin(new MarginInfo(true, false)); + propertyContentLayout.setHeight("450px"); + + // display capability + VerticalLayout capabilityContentLayout = new VerticalLayout(); + VerticalLayout capabilityTabLayout = new VerticalLayout(); + HorizontalLayout buttonCapabilityLayout = new HorizontalLayout(); + buttonCapabilityLayout.addComponents(buttonAddCapability, buttonBackCapabilities); + buttonCapabilityLayout.setSpacing(true); + + buttonBackCapabilities.setWidth("130px"); + + List capabilityAttributeBeanList = new ArrayList(); + for(Capability capability : resourceBean.getResource().getCapabilities()){ + for(Attribute a : capability.getAttributes()){ + CapabilityAttributeBean capabilityAttributeBean = new CapabilityAttributeBean(); + capabilityAttributeBean.setNameSpace(capability.getNamespace()); + capabilityAttributeBean.setDesignation(a.getName()); + capabilityAttributeBean.setType(a.getType().toString()); + capabilityAttributeBean.setValue(a.getStringValue()); + capabilityAttributeBeanList.add(capabilityAttributeBean); + } + } + + gridCapabilities.setContainerDataSource(new BeanItemContainer<>(CapabilityAttributeBean.class, capabilityAttributeBeanList)); + gridCapabilities.setColumnOrder("nameSpace", "designation", "value"); + gridCapabilities.addStyleName("my-style"); + HorizontalLayout capabilityFormLayout = new HorizontalLayout(capabilityTabLayout); + capabilityFormLayout.setSizeFull(); + gridCapabilities.setSizeFull(); + capabilityTabLayout.addComponents(gridCapabilities); + capabilityFormLayout.setExpandRatio(capabilityTabLayout, 1); + + capabilityContentLayout.addComponents(capabilityFormLayout, buttonCapabilityLayout); + capabilityContentLayout.setComponentAlignment(buttonCapabilityLayout, Alignment.BOTTOM_CENTER); + capabilityContentLayout.setSpacing(true); + capabilityContentLayout.setMargin(new MarginInfo(true, false)); + + buttonAddCapability.addClickListener(e ->{ + myUI.setContentNewCapabilityForm(resourceBean, isFromStore); + }); + + // display requirement + VerticalLayout requirementContentLayout = new VerticalLayout(); + VerticalLayout requirementTabLayout = new VerticalLayout(); + HorizontalLayout buttonRequirementLayout = new HorizontalLayout(); + buttonRequirementLayout.addComponents(buttonAddRequirements, buttonBackRequirements); + buttonRequirementLayout.setSpacing(true); + + buttonBackRequirements.setWidth("130px"); + + List requirementAttributeBeanList = new ArrayList(); + for(Requirement requirement : resourceBean.getResource().getRequirements()){ + for(Attribute a : requirement.getAttributes()){ + RequirementAttributeBean requirementAttributeBean = new RequirementAttributeBean(); + requirementAttributeBean.setNameSpace(requirement.getNamespace()); + requirementAttributeBean.setDesignation(a.getName()); + requirementAttributeBean.setType(a.getType().toString()); + requirementAttributeBean.setValue(a.getStringValue()); + requirementAttributeBeanList.add(requirementAttributeBean); + } + } + + gridRequirements.setContainerDataSource(new BeanItemContainer<>(RequirementAttributeBean.class, requirementAttributeBeanList)); + gridRequirements.setColumnOrder("nameSpace", "designation", "value"); + gridRequirements.addStyleName("my-style"); + HorizontalLayout requirementFormLayout = new HorizontalLayout(requirementTabLayout); + requirementFormLayout.setSizeFull(); + gridRequirements.setSizeFull(); + requirementTabLayout.addComponents(gridRequirements); + requirementFormLayout.setExpandRatio(requirementTabLayout, 1); + + requirementContentLayout.addComponents(requirementFormLayout, buttonRequirementLayout); + requirementContentLayout.setComponentAlignment(buttonRequirementLayout, Alignment.BOTTOM_CENTER); + requirementContentLayout.setSpacing(true); + requirementContentLayout.setMargin(new MarginInfo(true, false)); + + + + tabsheet.addTab(propertyContentLayout).setCaption("Properties"); + tabsheet.addTab(capabilityContentLayout).setCaption("Capability"); + tabsheet.addTab(requirementContentLayout).setCaption("Requirement"); + + buttonBackProperties.addClickListener(e ->{ + if(isFromStore){ + myUI.setContentBodyStore(); + } + else{ + myUI.setContentBodyBuffer(); + } + }); + + buttonBackCapabilities.addClickListener(e ->{ + if(isFromStore){ + myUI.setContentBodyStore(); + } + else{ + myUI.setContentBodyBuffer(); + } + }); + + buttonBackRequirements.addClickListener(e ->{ + if(isFromStore){ + myUI.setContentBodyStore(); + } + else{ + myUI.setContentBodyBuffer(); + } + }); + + content.addComponents(resourceLabel, tabsheet); + content.setSpacing(true); + content.setMargin(new MarginInfo(false, true)); + + addComponent(content); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java index 0df0863b..2db16fca 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java @@ -1,6 +1,6 @@ package cz.zcu.kiv.crce.crce_webui_vaadin.repository; -import java.io.IOException; +import java.util.List; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.event.ShortcutAction.KeyCode; @@ -26,15 +26,14 @@ import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; import cz.zcu.kiv.crce.crce_webui_vaadin.repository.services.ResourceService; import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; -import cz.zcu.kiv.crce.metadata.Resource; -@SuppressWarnings("serial") public class BufferForm extends FormLayout{ + private static final long serialVersionUID = 6675695008606881678L; private Label labelForm = new Label("Artefact in Buffer"); private TextField idText = new TextField(); private Grid gridBuffer = new Grid(); private PopupView popup; - private Resource resourceSelect; + private transient ResourceBean resourceBeanSelect; private ResourceService resourceService; public BufferForm(MyUI myUI){ @@ -45,24 +44,33 @@ public BufferForm(MyUI myUI){ resourceService = new ResourceService(Activator.instance().getMetadataService()); Button buttonDetail = new Button("Detail"); + buttonDetail.setWidth("100px"); Button buttonRemove = new Button("Remove"); + buttonRemove.setWidth("100px"); + Button buttonPush = new Button("Push to Store"); + buttonPush.setDescription("Push all artefact from Buffer to Store"); + buttonPush.setStyleName(ValoTheme.BUTTON_FRIENDLY); buttonDetail.setStyleName(ValoTheme.BUTTON_PRIMARY); buttonDetail.setClickShortcut(KeyCode.ENTER); labelForm.addStyleName(ValoTheme.LABEL_BOLD); - gridBuffer.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, resourceService.getAllResourceBean(myUI.getSession().getSession()))); + List resourceBeanList = resourceService.getAllResourceBeanFromBuffer(myUI.getSession().getSession()); + + gridBuffer.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, resourceBeanList)); gridBuffer.getColumn("resource").setHidden(true); + gridBuffer.getColumn("size").setHidden(true); gridBuffer.setColumnOrder("presentationName", "symbolicName", "version", "categories"); gridBuffer.addStyleName("my-style"); - idText.setInputPrompt("search by name..."); + idText.setInputPrompt("search by presentation name..."); + idText.setWidth("270px"); Button findButton = new Button(FontAwesome.CHECK); findButton.addClickListener(e ->{ gridBuffer.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, - resourceService.getFindResourceBean(myUI.getSession().getSession(), idText.getValue()))); + resourceService.getFindResourceBeanFromBuffer(myUI.getSession().getSession(), idText.getValue()))); }); Button clearButton = new Button(FontAwesome.TIMES); clearButton.addClickListener(e -> { @@ -73,8 +81,20 @@ public BufferForm(MyUI myUI){ filtering.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); filtering.addComponents(idText, findButton, clearButton); - - fieldLayout.addComponents(labelForm, filtering, gridBuffer); + HorizontalLayout filteringPushLayout = new HorizontalLayout(); + filteringPushLayout.addComponents(filtering, buttonPush); + filteringPushLayout.setSpacing(true); + filteringPushLayout.setSizeFull(); + filteringPushLayout.setComponentAlignment(buttonPush, Alignment.MIDDLE_RIGHT); + + if(resourceBeanList.isEmpty()){ + buttonPush.setVisible(false); + } + else{ + buttonPush.setVisible(true); + } + + fieldLayout.addComponents(labelForm, filteringPushLayout, gridBuffer); fieldLayout.setSpacing(true); HorizontalLayout formLayout = new HorizontalLayout(fieldLayout); @@ -108,32 +128,47 @@ public BufferForm(MyUI myUI){ gridBuffer.addSelectionListener(e ->{ buttonLayout.setVisible(true); - resourceSelect = ((ResourceBean)e.getSelected().iterator().next()).getResource(); + resourceBeanSelect = (ResourceBean)e.getSelected().iterator().next(); + }); + + buttonDetail.addClickListener(e ->{ + myUI.setContentArtefactDetailForm(resourceBeanSelect, false); }); buttonRemove.addClickListener(e ->{ popup.setPopupVisible(true); yesRemoveButton.addClickListener(ev -> { - try { - boolean result = Activator.instance().getBuffer(myUI.getSession().getSession()).remove(resourceSelect); - if(result){ - Notification notif = new Notification("Info", "Artefact sucess removed", - Notification.Type.ASSISTIVE_NOTIFICATION); - notif.setPosition(Position.TOP_RIGHT); - notif.show(Page.getCurrent()); - } - else{ - new Notification("Could not remove artefact from buffer", Notification.Type.WARNING_MESSAGE) - .show(Page.getCurrent()); - } - myUI.setContentBodyBuffer(); - } catch (IOException ex) { - new Notification("Error while removing the artifact", ex.getMessage(), Notification.Type.ERROR_MESSAGE) + boolean result = resourceService.removeResourceFromBuffer(myUI.getSession().getSession(), + resourceBeanSelect.getResource()); + if(result){ + Notification notif = new Notification("Info", "Artifact sucess removed", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } + else{ + new Notification("Could not remove artefact from buffer", Notification.Type.WARNING_MESSAGE) .show(Page.getCurrent()); } + myUI.setContentBodyBuffer(); }); }); + buttonPush.addClickListener(e ->{ + boolean result = resourceService.pushResourcesToStore(myUI.getSession()); + if(result){ + Notification notif = new Notification("Info", "All artifacts have been successfully moved to the Store.", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } + else{ + new Notification("Could not commit artifacts to Store", Notification.Type.WARNING_MESSAGE) + .show(Page.getCurrent()); + } + myUI.setContentBodyBuffer(); + }); + addComponent(content); } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/NewCapabilityForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/NewCapabilityForm.java new file mode 100644 index 00000000..af771fb7 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/NewCapabilityForm.java @@ -0,0 +1,44 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.repository; + +import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.Button; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; + +@SuppressWarnings("serial") +public class NewCapabilityForm extends FormLayout{ + private Label labelForm = new Label("Add new capability"); + private Button buttonSave = new Button("Save"); + private Button buttonCancel = new Button("Cancel"); + public NewCapabilityForm(MyUI myUI, ResourceBean resourceBean, boolean isFromStore){ + VerticalLayout content = new VerticalLayout(); + HorizontalLayout buttonLayout = new HorizontalLayout(); + + labelForm.addStyleName(ValoTheme.LABEL_BOLD); + + buttonSave.setStyleName(ValoTheme.BUTTON_PRIMARY); + buttonSave.setClickShortcut(KeyCode.ENTER); + buttonLayout.addComponents(buttonSave, buttonCancel); + buttonLayout.setSpacing(true); + + buttonSave.addClickListener(e ->{ + + }); + + buttonCancel.addClickListener(e ->{ + myUI.setContentArtefactDetailForm(resourceBean, isFromStore); + }); + + content.addComponents(labelForm, buttonLayout); + content.setSpacing(true); + content.setMargin(new MarginInfo(true, false)); + addComponent(content); + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginFormEdit.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginEditForm.java similarity index 96% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginFormEdit.java rename to modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginEditForm.java index 912c7349..c737156c 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginFormEdit.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginEditForm.java @@ -18,7 +18,7 @@ import cz.zcu.kiv.crce.plugin.Plugin; @SuppressWarnings("serial") -public class PluginFormEdit extends FormLayout{ +public class PluginEditForm extends FormLayout{ private int nameMaxLenght = 45; private Label labelKeyWords = new Label("Plugin key words"); private Grid gridKeyWords = new Grid(); @@ -26,7 +26,7 @@ public class PluginFormEdit extends FormLayout{ private TextField version = new TextField("Version"); private Button editButton = new Button("Edit"); private Plugin plugin; - public PluginFormEdit(PluginsForm pluginsForm){ + public PluginEditForm(PluginsForm pluginsForm){ HorizontalLayout content = new HorizontalLayout(); VerticalLayout editLayout = new VerticalLayout(); VerticalLayout keyWordLayout = new VerticalLayout(); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java index 9b08978f..30d5c978 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java @@ -18,13 +18,13 @@ public class PluginsForm extends FormLayout{ private Label labelForm = new Label("Plugins"); private Grid gridPlugins = new Grid(); private Grid gridKeyWords = new Grid(); - private PluginFormEdit pluginFormEdit; + private PluginEditForm pluginEditForm; private HorizontalLayout formLayout; private MyUI myUI; public PluginsForm(MyUI myUI){ this.myUI = myUI; - pluginFormEdit = new PluginFormEdit(this); + pluginEditForm = new PluginEditForm(this); VerticalLayout content = new VerticalLayout(); VerticalLayout fieldLayout = new VerticalLayout(); @@ -46,12 +46,12 @@ public PluginsForm(MyUI myUI){ fieldLayout.addComponents(labelForm, gridPlugins); fieldLayout.setSpacing(true); - formLayout = new HorizontalLayout(fieldLayout, pluginFormEdit); + formLayout = new HorizontalLayout(fieldLayout, pluginEditForm); formLayout.setSpacing(true); formLayout.setSizeFull(); gridPlugins.setSizeFull(); formLayout.setExpandRatio(fieldLayout, 1); - pluginFormEdit.setVisible(false); + pluginEditForm.setVisible(false); content.addComponent(formLayout); content.setMargin(new MarginInfo(false, true)); @@ -59,10 +59,10 @@ public PluginsForm(MyUI myUI){ gridPlugins.addSelectionListener(e -> { if (e.getSelected().isEmpty()) { - pluginFormEdit.setVisible(false); + pluginEditForm.setVisible(false); } else { Plugin plugin = (Plugin) e.getSelected().iterator().next(); - pluginFormEdit.setPlugin(plugin); + pluginEditForm.setPlugin(plugin); } }); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/StoreForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/StoreForm.java index 02caa82d..36f5169b 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/StoreForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/StoreForm.java @@ -1,10 +1,138 @@ package cz.zcu.kiv.crce.crce_webui_vaadin.repository; +import com.vaadin.data.util.BeanItemContainer; +import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.server.FontAwesome; +import com.vaadin.server.Page; +import com.vaadin.shared.Position; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.CssLayout; import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Grid; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Panel; +import com.vaadin.ui.PopupView; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.services.ResourceService; +import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; -@SuppressWarnings("serial") public class StoreForm extends FormLayout{ - public StoreForm(){ + private static final long serialVersionUID = 7439970261502810719L; + private Label labelForm = new Label("Artefact in Store"); + private TextField idText = new TextField(); + private Grid gridStore = new Grid(); + private PopupView popup; + private transient ResourceBean resourceBeanSelect; + private ResourceService resourceService; + + public StoreForm(MyUI myUI){ + VerticalLayout content = new VerticalLayout(); + VerticalLayout fieldLayout = new VerticalLayout(); + HorizontalLayout buttonLayout = new HorizontalLayout(); + + resourceService = new ResourceService(Activator.instance().getMetadataService()); + + Button buttonDetail = new Button("Detail"); + buttonDetail.setWidth("100px"); + Button buttonRemove = new Button("Remove"); + buttonRemove.setWidth("100px"); + + buttonDetail.setStyleName(ValoTheme.BUTTON_PRIMARY); + buttonDetail.setClickShortcut(KeyCode.ENTER); + + labelForm.addStyleName(ValoTheme.LABEL_BOLD); + + gridStore.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, resourceService.getAllResourceBeanFromStore(myUI.getSession()))); + gridStore.getColumn("resource").setHidden(true); + gridStore.getColumn("size").setHidden(true); + gridStore.setColumnOrder("presentationName", "symbolicName", "version", "categories"); + gridStore.addStyleName("my-style"); + + idText.setInputPrompt("search by presentation name..."); + idText.setWidth("270px"); + + Button findButton = new Button(FontAwesome.CHECK); + findButton.addClickListener(e ->{ + gridStore.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, + resourceService.getFindResourceBeanFromStore(myUI.getSession(), idText.getValue()))); + }); + Button clearButton = new Button(FontAwesome.TIMES); + clearButton.addClickListener(e -> { + myUI.setContentBodyStore(); + }); + + CssLayout filtering = new CssLayout(); + filtering.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); + filtering.addComponents(idText, findButton, clearButton); + + fieldLayout.addComponents(labelForm, filtering, gridStore); + fieldLayout.setSpacing(true); + + HorizontalLayout formLayout = new HorizontalLayout(fieldLayout); + formLayout.setSizeFull(); + gridStore.setSizeFull(); + formLayout.setExpandRatio(fieldLayout, 1); + + // Popup verification of artifact remove + VerticalLayout buttonPopupLayout = new VerticalLayout(); + Panel panel = new Panel("Really remove the artifact?"); + Button yesRemoveButton = new Button("Confirm"); + yesRemoveButton.setStyleName(ValoTheme.BUTTON_DANGER); + buttonPopupLayout.addComponents(yesRemoveButton); + buttonPopupLayout.setMargin(true); + buttonPopupLayout.setSizeFull(); + buttonPopupLayout.setComponentAlignment(yesRemoveButton, Alignment.BOTTOM_CENTER); + panel.setContent(buttonPopupLayout); + + popup = new PopupView(null, panel); + popup.setWidth("150px"); + + buttonLayout.addComponents(buttonDetail, buttonRemove); + buttonLayout.setSpacing(true); + buttonLayout.setVisible(false); + + content.addComponents(formLayout, buttonLayout, popup); + content.setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER); + content.setComponentAlignment(popup, Alignment.MIDDLE_CENTER); + content.setMargin(new MarginInfo(false, true)); + content.setSpacing(true); + + gridStore.addSelectionListener(e ->{ + buttonLayout.setVisible(true); + resourceBeanSelect = (ResourceBean)e.getSelected().iterator().next(); + }); + + buttonDetail.addClickListener(e ->{ + myUI.setContentArtefactDetailForm(resourceBeanSelect, true); + }); + + buttonRemove.addClickListener(e ->{ + popup.setPopupVisible(true); + yesRemoveButton.addClickListener(ev -> { + boolean result = resourceService.removeResorceFromStore(myUI.getSession(), resourceBeanSelect.getResource()); + if(result){ + Notification notif = new Notification("Info", "Artifact sucess removed", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } + else{ + new Notification("Could not remove artefact from store", Notification.Type.WARNING_MESSAGE) + .show(Page.getCurrent()); + } + myUI.setContentBodyStore(); + }); + }); + addComponent(content); } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/CapabilityAttributeBean.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/CapabilityAttributeBean.java new file mode 100644 index 00000000..fa6c19c8 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/CapabilityAttributeBean.java @@ -0,0 +1,52 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes; + +public class CapabilityAttributeBean { + private String designation; + private String nameSpace; + private String type; + private String value; + public String getDesignation() { + if (designation == null){ + return "unknown"; + } + else{ + return designation; + } + } + public void setDesignation(String designation) { + this.designation = designation; + } + public String getNameSpace() { + if (nameSpace == null){ + return "unknown"; + } + else{ + return nameSpace; + } + } + public void setNameSpace(String nameSpace) { + this.nameSpace = nameSpace; + } + public String getType() { + if (type == null){ + return "unknown"; + } + else{ + return type; + } + } + public void setType(String type) { + this.type = type; + } + public String getValue() { + if (value == null){ + return "unknown"; + } + else{ + return value; + } + } + public void setValue(String value) { + this.value = value; + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/RequirementAttributeBean.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/RequirementAttributeBean.java new file mode 100644 index 00000000..4a77f0a2 --- /dev/null +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/RequirementAttributeBean.java @@ -0,0 +1,52 @@ +package cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes; + +public class RequirementAttributeBean { + private String designation; + private String nameSpace; + private String type; + private String value; + public String getDesignation() { + if (designation == null){ + return "unknown"; + } + else{ + return designation; + } + } + public void setDesignation(String designation) { + this.designation = designation; + } + public String getNameSpace() { + if (nameSpace == null){ + return "unknown"; + } + else{ + return nameSpace; + } + } + public void setNameSpace(String nameSpace) { + this.nameSpace = nameSpace; + } + public String getType() { + if (type == null){ + return "unknown"; + } + else{ + return type; + } + } + public void setType(String type) { + this.type = type; + } + public String getValue() { + if (value == null){ + return "unknown"; + } + else{ + return value; + } + } + public void setValue(String value) { + this.value = value; + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/ResourceBean.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/ResourceBean.java index bb6a5a81..297c1788 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/ResourceBean.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/ResourceBean.java @@ -8,10 +8,11 @@ public class ResourceBean{ private String symbolicName; private String version; private String categories; + private long size; private Resource resource; public ResourceBean(String presentationName, String symbolicName, Version version, - String[] categories, Resource resource) { + String[] categories, long size, Resource resource) { this.presentationName = presentationName; this.symbolicName = symbolicName; if(version == null){ @@ -29,6 +30,7 @@ public ResourceBean(String presentationName, String symbolicName, Version versio else{ this.categories = "unknown-categories"; } + this.size = size; this.resource = resource; } @@ -51,6 +53,10 @@ public String getVersion() { public String getCategories() { return categories; } + + public long getSize() { + return size; + } @Override public String toString(){ diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java index 85aeb3ca..861ffc26 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java @@ -1,10 +1,14 @@ package cz.zcu.kiv.crce.crce_webui_vaadin.repository.services; +import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Map; + +import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedSession; import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; @@ -58,19 +62,77 @@ public Version getVersion() { return version; } - public List getAllResourceBean(WrappedSession session){ + public long getSize() { + return metadataService.getSize(resource); + } + + public List getAllResourceBeanFromBuffer(WrappedSession session){ List resources = new ArrayList(); for(Resource resource : Activator.instance().getBuffer(session).getResources()){ setResource(resource); - resources.add(new ResourceBean(getPresentationName(), getSymbolicName(), getVersion(), getCategories(), resource)); + resources.add(new ResourceBean(getPresentationName(), getSymbolicName(), getVersion(), getCategories(), getSize(), resource)); } return resources; } - public List getFindResourceBean(WrappedSession session, String stringFilter){ + public boolean removeResourceFromBuffer(WrappedSession wSession, Resource resource){ + boolean result; + try { + result = Activator.instance().getBuffer(wSession).remove(resource); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + return result; + } + + public List getFindResourceBeanFromBuffer(WrappedSession session, String stringFilter){ + boolean passesFilter = false; + ArrayList arrayList = new ArrayList<>(); + for (ResourceBean resourceBean : getAllResourceBeanFromBuffer(session)){ + if(stringFilter == null || stringFilter.isEmpty()){ + passesFilter = true; + } + else{ + passesFilter = resourceBean.toString().toLowerCase().contains(stringFilter.toLowerCase()); + } + if (passesFilter) { + arrayList.add(resourceBean); + } + } + Collections.sort(arrayList, new Comparator() { + @Override + public int compare(ResourceBean o1, ResourceBean o2) { + return (int) (o2.hashCode() - o1.hashCode()); + } + }); + return arrayList; + } + + // for store + public boolean pushResourcesToStore(VaadinSession session){ + try { + Activator.instance().getBuffer(session.getSession()).commit(true); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + return true; + } + + public List getAllResourceBeanFromStore(VaadinSession session) { + List resourceBeanList = new ArrayList(); + for(Resource resource : Activator.instance().getStore(getRepositoryId(session)).getResources()){ + setResource(resource); + resourceBeanList.add(new ResourceBean(getPresentationName(), getSymbolicName(), getVersion(), getCategories(), getSize(), resource)); + } + return resourceBeanList ; + } + + public List getFindResourceBeanFromStore(VaadinSession session, String stringFilter){ boolean passesFilter = false; ArrayList arrayList = new ArrayList<>(); - for (ResourceBean resourceBean : getAllResourceBean(session)){ + for (ResourceBean resourceBean : getAllResourceBeanFromStore(session)){ if(stringFilter == null || stringFilter.isEmpty()){ passesFilter = true; } @@ -90,4 +152,27 @@ public int compare(ResourceBean o1, ResourceBean o2) { return arrayList; } + public boolean removeResorceFromStore(VaadinSession session, Resource resource){ + boolean result; + try { + result = Activator.instance().getStore(getRepositoryId(session)).remove(resource); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + return result; + } + + private String getRepositoryId(VaadinSession session) { + String id = (String) session.getAttribute("repositoryId"); + if (id == null) { + Map stores = Activator.instance().getRepositories(); + if (stores.isEmpty()) { + return null; + } + id = stores.keySet().iterator().next(); + session.setAttribute("repositoryId", id); + } + return id; + } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java index d3bc1083..284299f4 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java @@ -31,7 +31,7 @@ public MenuForm(MyUI myUI) { // submenu repository repository.addItem("Buffer", e ->{myUI.setContentBodyBuffer();}); - repository.addItem("Store", null); + repository.addItem("Store", e->{myUI.setContentBodyStore();}); repository.addItem("Plugins", e ->{myUI.setContentBodyPlugins();}); // submenu settings diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java index 9563df5f..ad4d161a 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java @@ -17,9 +17,12 @@ import cz.zcu.kiv.crce.crce_webui_vaadin.outer.DefinedMavenForm; import cz.zcu.kiv.crce.crce_webui_vaadin.outer.LoadFileForm; import cz.zcu.kiv.crce.crce_webui_vaadin.outer.LocalMavenForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.ArtefactDetailForm; import cz.zcu.kiv.crce.crce_webui_vaadin.repository.BufferForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.NewCapabilityForm; import cz.zcu.kiv.crce.crce_webui_vaadin.repository.PluginsForm; import cz.zcu.kiv.crce.crce_webui_vaadin.repository.StoreForm; +import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; /** * This UI is the application entry point. A UI may either represent a browser window @@ -42,6 +45,8 @@ public class MyUI extends UI { private LoadFileForm loadFileForm; private BufferForm bufferForm; private StoreForm storeForm; + private ArtefactDetailForm artefactDetailForm; + private NewCapabilityForm newCapabilityForm; private PluginsForm pluginsForm; private SettingsForm settingsForm; private VerticalLayout content = new VerticalLayout(); @@ -132,10 +137,20 @@ public void setContentBodyBuffer(){ } public void setContentBodyStore(){ - storeForm = new StoreForm(); + storeForm = new StoreForm(this); body.setContent(storeForm); } + public void setContentArtefactDetailForm(ResourceBean resourceBean, boolean isFromStore){ + artefactDetailForm = new ArtefactDetailForm(this, resourceBean, isFromStore); + body.setContent(artefactDetailForm); + } + + public void setContentNewCapabilityForm(ResourceBean resourceBean, boolean isFromStore){ + newCapabilityForm = new NewCapabilityForm(this, resourceBean, isFromStore); + body.setContent(newCapabilityForm); + } + public void setContentBodyPlugins(){ pluginsForm = new PluginsForm(this); body.setContent(pluginsForm); From 41b041bf36c1829e80bb53e9fa21b66bda6f3925 Mon Sep 17 00:00:00 2001 From: crce_external_repository_webui Date: Fri, 2 Mar 2018 12:01:49 +0100 Subject: [PATCH 11/85] webui and support_external_repository with self-contained modules separating the module external_repository_support from the web application and reworking the module interface for use by other components --- build/pom.xml | 5 +- core/crce-metadata-api/.classpath | 2 +- core/crce-metadata-api/.project | 6 + core/crce-metadata-dao-api/.classpath | 2 +- core/crce-metadata-dao-api/.project | 6 + core/crce-metadata-dao-impl/.classpath | 2 +- core/crce-metadata-dao-impl/.project | 6 + core/crce-metadata-impl/.classpath | 2 +- core/crce-metadata-impl/.project | 6 + core/crce-metadata-indexer-api/.classpath | 2 +- core/crce-metadata-indexer-api/.project | 6 + core/crce-metadata-indexer-impl/.classpath | 2 +- core/crce-metadata-indexer-impl/.project | 6 + core/crce-metadata-json-api/.classpath | 2 +- core/crce-metadata-json-api/.project | 6 + core/crce-metadata-json-impl/.classpath | 2 +- core/crce-metadata-json-impl/.project | 6 + core/crce-metadata-service-api/.classpath | 2 +- core/crce-metadata-service-api/.project | 6 + core/crce-metadata-service-impl/.classpath | 2 +- core/crce-metadata-service-impl/.project | 6 + core/crce-plugin-api/.classpath | 2 +- core/crce-plugin-api/.project | 6 + core/crce-repository-api/.classpath | 2 +- core/crce-repository-api/.project | 6 + core/crce-repository-impl/.classpath | 2 +- core/crce-repository-impl/.project | 6 + core/crce-resolver-api/.classpath | 2 +- core/crce-resolver-api/.project | 6 + core/crce-resolver-impl/.classpath | 2 +- core/crce-resolver-impl/.project | 6 + modules/crce-compatibility-api/.classpath | 2 +- modules/crce-compatibility-api/.project | 6 + modules/crce-compatibility-dao-api/.classpath | 2 +- modules/crce-compatibility-dao-api/.project | 6 + .../crce-compatibility-dao-mongodb/.classpath | 2 +- .../crce-compatibility-dao-mongodb/.project | 6 + modules/crce-concurrency/.classpath | 2 +- modules/crce-concurrency/.project | 6 + modules/crce-external-repository/.classpath | 37 ++ modules/crce-external-repository/.project | 55 +++ .../META-INF/MANIFEST.MF | 118 ++++++ modules/crce-external-repository/pom.xml | 397 ++++++++++++++++++ .../api/ArtifactTree.java | 45 ++ .../api/CentralMaven.java | 148 +++++++ .../api}/DefinedMaven.java | 84 ++-- .../api}/MavenIndex.java | 28 +- .../api/ResultSearchArtifactTree.java | 19 + .../api}/SettingsUrl.java | 3 +- .../internal/Activator.java | 35 ++ modules/crce-handler-metrics/.classpath | 2 +- modules/crce-handler-metrics/.project | 6 + modules/crce-integration-tests/.project | 6 + modules/crce-metadata-osgi-bundle/.classpath | 2 +- modules/crce-metadata-osgi-bundle/.project | 6 + modules/crce-rest-v2/.classpath | 2 +- modules/crce-rest-v2/.project | 6 + modules/crce-vo/.classpath | 2 +- modules/crce-vo/.project | 6 + modules/crce-webservices-indexer/.classpath | 2 +- modules/crce-webservices-indexer/.project | 6 + modules/crce-webui-vaadin/.classpath | 2 +- modules/crce-webui-vaadin/.project | 6 + modules/crce-webui-vaadin/pom.xml | 27 +- .../outer/CentralMavenForm.java | 317 ++++++++++---- .../outer/CheckMavenIndexForm.java | 7 +- .../outer/DefinedMavenForm.java | 225 ++++++---- .../outer/LocalMavenForm.java | 195 ++++----- .../outer/classes/CentralMaven.java | 201 --------- .../outer/classes/LocalMaven.java | 2 + .../repository/services/ResourceService.java | 2 + .../crce_webui_vaadin/webui/LoginForm.java | 16 +- .../crce/crce_webui_vaadin/webui/MyUI.java | 1 + .../crce_webui_vaadin/webui/SettingsForm.java | 4 +- modules/crce-webui/.classpath | 2 +- modules/crce-webui/.project | 6 + modules/pom.xml | 2 +- 77 files changed, 1573 insertions(+), 614 deletions(-) create mode 100644 modules/crce-external-repository/.classpath create mode 100644 modules/crce-external-repository/.project create mode 100644 modules/crce-external-repository/META-INF/MANIFEST.MF create mode 100644 modules/crce-external-repository/pom.xml create mode 100644 modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/ArtifactTree.java create mode 100644 modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/CentralMaven.java rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes => crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api}/DefinedMaven.java (65%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes => crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api}/MavenIndex.java (88%) create mode 100644 modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/ResultSearchArtifactTree.java rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes => crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api}/SettingsUrl.java (94%) create mode 100644 modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/internal/Activator.java delete mode 100644 modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java diff --git a/build/pom.xml b/build/pom.xml index b9e085e0..bcbf925f 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -27,7 +27,7 @@ 0.8.1-incubator 4.3.1 - 6.0.6 + 6.0.7 3.2.0 2.6.1 1.9.13 @@ -149,7 +149,8 @@ org.apache.maven.plugins maven-dependency-plugin - 2.9 + 3.0.2 + org.apache.cxf diff --git a/core/crce-metadata-api/.classpath b/core/crce-metadata-api/.classpath index 698778fe..d2ddf387 100644 --- a/core/crce-metadata-api/.classpath +++ b/core/crce-metadata-api/.classpath @@ -22,7 +22,7 @@
- + diff --git a/core/crce-metadata-api/.project b/core/crce-metadata-api/.project index 742c9778..b54c54b5 100644 --- a/core/crce-metadata-api/.project +++ b/core/crce-metadata-api/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/core/crce-metadata-dao-api/.classpath b/core/crce-metadata-dao-api/.classpath index faa90026..150739e5 100644 --- a/core/crce-metadata-dao-api/.classpath +++ b/core/crce-metadata-dao-api/.classpath @@ -12,7 +12,7 @@ - + diff --git a/core/crce-metadata-dao-api/.project b/core/crce-metadata-dao-api/.project index 684a2e2c..628a61d0 100644 --- a/core/crce-metadata-dao-api/.project +++ b/core/crce-metadata-dao-api/.project @@ -35,8 +35,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.pde.PluginNature diff --git a/core/crce-metadata-dao-impl/.classpath b/core/crce-metadata-dao-impl/.classpath index 303bafb0..92134a8e 100644 --- a/core/crce-metadata-dao-impl/.classpath +++ b/core/crce-metadata-dao-impl/.classpath @@ -17,7 +17,7 @@ - + diff --git a/core/crce-metadata-dao-impl/.project b/core/crce-metadata-dao-impl/.project index bc6afb37..115d9e0e 100644 --- a/core/crce-metadata-dao-impl/.project +++ b/core/crce-metadata-dao-impl/.project @@ -35,8 +35,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.pde.PluginNature diff --git a/core/crce-metadata-impl/.classpath b/core/crce-metadata-impl/.classpath index f619a536..0556be39 100644 --- a/core/crce-metadata-impl/.classpath +++ b/core/crce-metadata-impl/.classpath @@ -17,7 +17,7 @@ - + diff --git a/core/crce-metadata-impl/.project b/core/crce-metadata-impl/.project index a4af59d2..144732c1 100644 --- a/core/crce-metadata-impl/.project +++ b/core/crce-metadata-impl/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/core/crce-metadata-indexer-api/.classpath b/core/crce-metadata-indexer-api/.classpath index f619a536..0556be39 100644 --- a/core/crce-metadata-indexer-api/.classpath +++ b/core/crce-metadata-indexer-api/.classpath @@ -17,7 +17,7 @@ - + diff --git a/core/crce-metadata-indexer-api/.project b/core/crce-metadata-indexer-api/.project index 7ce7bc92..6e7b114d 100644 --- a/core/crce-metadata-indexer-api/.project +++ b/core/crce-metadata-indexer-api/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/core/crce-metadata-indexer-impl/.classpath b/core/crce-metadata-indexer-impl/.classpath index f619a536..0556be39 100644 --- a/core/crce-metadata-indexer-impl/.classpath +++ b/core/crce-metadata-indexer-impl/.classpath @@ -17,7 +17,7 @@ - + diff --git a/core/crce-metadata-indexer-impl/.project b/core/crce-metadata-indexer-impl/.project index 529a3266..f0972909 100644 --- a/core/crce-metadata-indexer-impl/.project +++ b/core/crce-metadata-indexer-impl/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/core/crce-metadata-json-api/.classpath b/core/crce-metadata-json-api/.classpath index f619a536..0556be39 100644 --- a/core/crce-metadata-json-api/.classpath +++ b/core/crce-metadata-json-api/.classpath @@ -17,7 +17,7 @@ - + diff --git a/core/crce-metadata-json-api/.project b/core/crce-metadata-json-api/.project index b6466006..4b94fad9 100644 --- a/core/crce-metadata-json-api/.project +++ b/core/crce-metadata-json-api/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/core/crce-metadata-json-impl/.classpath b/core/crce-metadata-json-impl/.classpath index f619a536..0556be39 100644 --- a/core/crce-metadata-json-impl/.classpath +++ b/core/crce-metadata-json-impl/.classpath @@ -17,7 +17,7 @@ - + diff --git a/core/crce-metadata-json-impl/.project b/core/crce-metadata-json-impl/.project index 17eaab60..f2d75234 100644 --- a/core/crce-metadata-json-impl/.project +++ b/core/crce-metadata-json-impl/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/core/crce-metadata-service-api/.classpath b/core/crce-metadata-service-api/.classpath index f619a536..0556be39 100644 --- a/core/crce-metadata-service-api/.classpath +++ b/core/crce-metadata-service-api/.classpath @@ -17,7 +17,7 @@ - + diff --git a/core/crce-metadata-service-api/.project b/core/crce-metadata-service-api/.project index c64b935f..275a659b 100644 --- a/core/crce-metadata-service-api/.project +++ b/core/crce-metadata-service-api/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/core/crce-metadata-service-impl/.classpath b/core/crce-metadata-service-impl/.classpath index f619a536..0556be39 100644 --- a/core/crce-metadata-service-impl/.classpath +++ b/core/crce-metadata-service-impl/.classpath @@ -17,7 +17,7 @@ - + diff --git a/core/crce-metadata-service-impl/.project b/core/crce-metadata-service-impl/.project index 8d5ac902..35fc914c 100644 --- a/core/crce-metadata-service-impl/.project +++ b/core/crce-metadata-service-impl/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/core/crce-plugin-api/.classpath b/core/crce-plugin-api/.classpath index f619a536..0556be39 100644 --- a/core/crce-plugin-api/.classpath +++ b/core/crce-plugin-api/.classpath @@ -17,7 +17,7 @@ - + diff --git a/core/crce-plugin-api/.project b/core/crce-plugin-api/.project index 8a6a039a..ed6a227d 100644 --- a/core/crce-plugin-api/.project +++ b/core/crce-plugin-api/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/core/crce-repository-api/.classpath b/core/crce-repository-api/.classpath index faa90026..150739e5 100644 --- a/core/crce-repository-api/.classpath +++ b/core/crce-repository-api/.classpath @@ -12,7 +12,7 @@ - + diff --git a/core/crce-repository-api/.project b/core/crce-repository-api/.project index 1ec320ad..09a2ad63 100644 --- a/core/crce-repository-api/.project +++ b/core/crce-repository-api/.project @@ -35,8 +35,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.pde.PluginNature diff --git a/core/crce-repository-impl/.classpath b/core/crce-repository-impl/.classpath index faa90026..150739e5 100644 --- a/core/crce-repository-impl/.classpath +++ b/core/crce-repository-impl/.classpath @@ -12,7 +12,7 @@ - + diff --git a/core/crce-repository-impl/.project b/core/crce-repository-impl/.project index c0c91906..8405ed2b 100644 --- a/core/crce-repository-impl/.project +++ b/core/crce-repository-impl/.project @@ -30,6 +30,11 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + org.eclipse.m2e.core.maven2Builder @@ -37,6 +42,7 @@ + org.fusesource.ide.project.RiderProjectNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.pde.PluginNature diff --git a/core/crce-resolver-api/.classpath b/core/crce-resolver-api/.classpath index faa90026..150739e5 100644 --- a/core/crce-resolver-api/.classpath +++ b/core/crce-resolver-api/.classpath @@ -12,7 +12,7 @@ - + diff --git a/core/crce-resolver-api/.project b/core/crce-resolver-api/.project index e96558e1..02b3081f 100644 --- a/core/crce-resolver-api/.project +++ b/core/crce-resolver-api/.project @@ -35,8 +35,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.pde.PluginNature diff --git a/core/crce-resolver-impl/.classpath b/core/crce-resolver-impl/.classpath index faa90026..150739e5 100644 --- a/core/crce-resolver-impl/.classpath +++ b/core/crce-resolver-impl/.classpath @@ -12,7 +12,7 @@ - + diff --git a/core/crce-resolver-impl/.project b/core/crce-resolver-impl/.project index ee6ae75e..35955ee7 100644 --- a/core/crce-resolver-impl/.project +++ b/core/crce-resolver-impl/.project @@ -35,8 +35,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.pde.PluginNature diff --git a/modules/crce-compatibility-api/.classpath b/modules/crce-compatibility-api/.classpath index da3f7efb..ff36ca09 100644 --- a/modules/crce-compatibility-api/.classpath +++ b/modules/crce-compatibility-api/.classpath @@ -22,7 +22,7 @@ - + diff --git a/modules/crce-compatibility-api/.project b/modules/crce-compatibility-api/.project index 92af28f5..dd3d0708 100644 --- a/modules/crce-compatibility-api/.project +++ b/modules/crce-compatibility-api/.project @@ -30,6 +30,11 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + org.eclipse.m2e.core.maven2Builder @@ -37,6 +42,7 @@ + org.fusesource.ide.project.RiderProjectNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.pde.PluginNature diff --git a/modules/crce-compatibility-dao-api/.classpath b/modules/crce-compatibility-dao-api/.classpath index f619a536..0556be39 100644 --- a/modules/crce-compatibility-dao-api/.classpath +++ b/modules/crce-compatibility-dao-api/.classpath @@ -17,7 +17,7 @@ - + diff --git a/modules/crce-compatibility-dao-api/.project b/modules/crce-compatibility-dao-api/.project index b7277b3f..a24a015e 100644 --- a/modules/crce-compatibility-dao-api/.project +++ b/modules/crce-compatibility-dao-api/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/modules/crce-compatibility-dao-mongodb/.classpath b/modules/crce-compatibility-dao-mongodb/.classpath index f619a536..0556be39 100644 --- a/modules/crce-compatibility-dao-mongodb/.classpath +++ b/modules/crce-compatibility-dao-mongodb/.classpath @@ -17,7 +17,7 @@ - + diff --git a/modules/crce-compatibility-dao-mongodb/.project b/modules/crce-compatibility-dao-mongodb/.project index c1baab22..5ca82f8e 100644 --- a/modules/crce-compatibility-dao-mongodb/.project +++ b/modules/crce-compatibility-dao-mongodb/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/modules/crce-concurrency/.classpath b/modules/crce-concurrency/.classpath index 698778fe..d2ddf387 100644 --- a/modules/crce-concurrency/.classpath +++ b/modules/crce-concurrency/.classpath @@ -22,7 +22,7 @@ - + diff --git a/modules/crce-concurrency/.project b/modules/crce-concurrency/.project index f5348e6d..7d99d9cb 100644 --- a/modules/crce-concurrency/.project +++ b/modules/crce-concurrency/.project @@ -15,8 +15,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/modules/crce-external-repository/.classpath b/modules/crce-external-repository/.classpath new file mode 100644 index 00000000..9fe6a19d --- /dev/null +++ b/modules/crce-external-repository/.classpath @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/crce-external-repository/.project b/modules/crce-external-repository/.project new file mode 100644 index 00000000..e51afa4f --- /dev/null +++ b/modules/crce-external-repository/.project @@ -0,0 +1,55 @@ + + + crce-external-repository + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.fusesource.ide.project.RiderProjectBuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.fusesource.ide.project.RiderProjectNature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature + org.eclipse.wst.common.project.facet.core.nature + + diff --git a/modules/crce-external-repository/META-INF/MANIFEST.MF b/modules/crce-external-repository/META-INF/MANIFEST.MF new file mode 100644 index 00000000..8e21e977 --- /dev/null +++ b/modules/crce-external-repository/META-INF/MANIFEST.MF @@ -0,0 +1,118 @@ +Manifest-Version: 1.0 +Bnd-LastModified: 1519907937443 +Build-Jdk: 1.8.0_162 +Built-By: rpesek +Bundle-Activator: cz.zcu.kiv.crce.crce_external_repository.internal.Acti + vator +Bundle-ClassPath: .,lib/aether-api-1.13.1.jar,lib/aether-util-1.13.1.jar + ,lib/aether-impl-1.1.0.jar,lib/aether-spi-1.1.0.jar,lib/aether-connecto + r-basic-1.1.0.jar,lib/aether-transport-file-1.1.0.jar,lib/aether-transp + ort-http-1.1.0.jar,lib/maven-aether-provider-3.3.9.jar,lib/maven-artifa + ct-3.3.9.jar,lib/maven-builder-support-3.3.9.jar,lib/slf4j-simple-1.7.2 + 2.jar,lib/jsoup-1.10.3.jar,lib/commons-codec-1.6.jar,lib/maven-model-3. + 3.9.jar,lib/maven-model-builder-3.3.9.jar,lib/flute-1.3.0.gg2.jar,lib/h + ttpcore-4.3.2.jar,lib/httpclient-4.3.5.jar,lib/guava-18.0.jar,lib/sac-1 + .3.jar,lib/maven-repository-metadata-3.3.9.jar,lib/plexus-component-ann + otations-1.6.jar,lib/plexus-interpolation-1.21.jar,lib/plexus-utils-3.0 + .22.jar,lib/org.eclipse.sisu.plexus-0.3.3.jar,lib/org.eclipse.sisu.inje + ct-0.3.3.jar,lib/indexer-core-5.1.2-4333789.jar,lib/wagon-http-lightwei + ght-2.3.jar,lib/wagon-provider-api-2.3.jar,lib/wagon-http-shared4-2.3.j + ar,lib/indexer-artifact-5.1.2-4333789.jar,lib/lucene-core-3.6.2.jar,lib + /lucene-queries-3.6.2.jar,lib/lucene-memory-3.6.2.jar,lib/lucene-highli + ghter-3.6.2.jar +Bundle-Description: Component Repository supporting Compatibility Evalua + tion +Bundle-DocURL: http://www.kiv.zcu.cz +Bundle-ManifestVersion: 2 +Bundle-Name: CRCE - External repository support +Bundle-SymbolicName: crce-external-repository +Bundle-Vendor: ZČU KIV +Bundle-Version: 1.0 +Created-By: Apache Maven Bundle Plugin +DynamicImport-Package: * +Embed-Dependency: !sisu-guice,*;scope=compile|runtime;inline=false +Embed-Directory: lib +Embed-StripGroup: true +Embedded-Artifacts: lib/aether-api-1.13.1.jar;g="org.sonatype.aether";a= + "aether-api";v="1.13.1",lib/aether-util-1.13.1.jar;g="org.sonatype.aeth + er";a="aether-util";v="1.13.1",lib/aether-impl-1.1.0.jar;g="org.eclipse + .aether";a="aether-impl";v="1.1.0",lib/aether-spi-1.1.0.jar;g="org.ecli + pse.aether";a="aether-spi";v="1.1.0",lib/aether-connector-basic-1.1.0.j + ar;g="org.eclipse.aether";a="aether-connector-basic";v="1.1.0",lib/aeth + er-transport-file-1.1.0.jar;g="org.eclipse.aether";a="aether-transport- + file";v="1.1.0",lib/aether-transport-http-1.1.0.jar;g="org.eclipse.aeth + er";a="aether-transport-http";v="1.1.0",lib/maven-aether-provider-3.3.9 + .jar;g="org.apache.maven";a="maven-aether-provider";v="3.3.9",lib/maven + -artifact-3.3.9.jar;g="org.apache.maven";a="maven-artifact";v="3.3.9",l + ib/maven-builder-support-3.3.9.jar;g="org.apache.maven";a="maven-builde + r-support";v="3.3.9",lib/slf4j-simple-1.7.22.jar;g="org.slf4j";a="slf4j + -simple";v="1.7.22",lib/jsoup-1.10.3.jar;g="org.jsoup";a="jsoup";v="1.1 + 0.3",lib/commons-codec-1.6.jar;g="commons-codec";a="commons-codec";v="1 + .6",lib/maven-model-3.3.9.jar;g="org.apache.maven";a="maven-model";v="3 + .3.9",lib/maven-model-builder-3.3.9.jar;g="org.apache.maven";a="maven-m + odel-builder";v="3.3.9",lib/flute-1.3.0.gg2.jar;g="com.vaadin.external. + flute";a="flute";v="1.3.0.gg2",lib/httpcore-4.3.2.jar;g="org.apache.htt + pcomponents";a="httpcore";v="4.3.2",lib/httpclient-4.3.5.jar;g="org.apa + che.httpcomponents";a="httpclient";v="4.3.5",lib/guava-18.0.jar;g="com. + google.guava";a="guava";v="18.0",lib/sac-1.3.jar;g="org.w3c.css";a="sac + ";v="1.3",lib/maven-repository-metadata-3.3.9.jar;g="org.apache.maven"; + a="maven-repository-metadata";v="3.3.9",lib/plexus-component-annotation + s-1.6.jar;g="org.codehaus.plexus";a="plexus-component-annotations";v="1 + .6",lib/plexus-interpolation-1.21.jar;g="org.codehaus.plexus";a="plexus + -interpolation";v="1.21",lib/plexus-utils-3.0.22.jar;g="org.codehaus.pl + exus";a="plexus-utils";v="3.0.22",lib/org.eclipse.sisu.plexus-0.3.3.jar + ;g="org.eclipse.sisu";a="org.eclipse.sisu.plexus";v="0.3.3",lib/org.ecl + ipse.sisu.inject-0.3.3.jar;g="org.eclipse.sisu";a="org.eclipse.sisu.inj + ect";v="0.3.3",lib/indexer-core-5.1.2-4333789.jar;g="org.apache.maven.i + ndexer";a="indexer-core";v="5.1.2-4333789",lib/wagon-http-lightweight-2 + .3.jar;g="org.apache.maven.wagon";a="wagon-http-lightweight";v="2.3",li + b/wagon-provider-api-2.3.jar;g="org.apache.maven.wagon";a="wagon-provid + er-api";v="2.3",lib/wagon-http-shared4-2.3.jar;g="org.apache.maven.wago + n";a="wagon-http-shared4";v="2.3",lib/indexer-artifact-5.1.2-4333789.ja + r;g="org.apache.maven.indexer";a="indexer-artifact";v="5.1.2-4333789",l + ib/lucene-core-3.6.2.jar;g="org.apache.lucene";a="lucene-core";v="3.6.2 + ",lib/lucene-queries-3.6.2.jar;g="org.apache.lucene";a="lucene-queries" + ;v="3.6.2",lib/lucene-memory-3.6.2.jar;g="org.apache.lucene";a="lucene- + memory";v="3.6.2",lib/lucene-highlighter-3.6.2.jar;g="org.apache.lucene + ";a="lucene-highlighter";v="3.6.2" +Export-Package: cz.zcu.kiv.crce.crce_external_repository.api;uses:="org. + apache.maven.index";version="1.0.0",org.apache.maven.index;uses:="org.a + pache.maven.index.artifact,org.apache.maven.index.context,org.apache.ma + ven.index.expr";version="1.0.0",org.apache.maven.index.archetype;uses:= + "org.apache.maven.index.context";version="1.0.0",org.apache.maven.index + .artifact;version="1.0.0",org.apache.maven.index.context;uses:="org.apa + che.maven.index,org.apache.maven.index.artifact";version="1.0.0",org.ap + ache.maven.index.creator;uses:="org.apache.maven.index,org.apache.maven + .index.context";version="1.0.0",org.apache.maven.index.expr;uses:="org. + apache.maven.index";version="1.0.0",org.apache.maven.index.fs;version=" + 1.0.0",org.apache.maven.index.incremental;uses:="org.apache.maven.index + .packer,org.apache.maven.index.updater";version="1.0.0",org.apache.mave + n.index.locator;uses:="org.apache.maven.index.artifact";version="1.0.0" + ,org.apache.maven.index.packer;uses:="org.apache.maven.index.context";v + ersion="1.0.0",org.apache.maven.index.search.grouping;uses:="org.apache + .maven.index";version="1.0.0",org.apache.maven.index.treeview;uses:="or + g.apache.maven.index,org.apache.maven.index.context";version="1.0.0",or + g.apache.maven.index.updater;uses:="org.apache.maven.index.context,org. + apache.maven.index.fs,org.apache.maven.index.incremental,org.apache.mav + en.wagon,org.apache.maven.wagon.authentication,org.apache.maven.wagon.e + vents,org.apache.maven.wagon.proxy";version="1.0.0",org.apache.maven.in + dex.util;uses:="org.apache.maven.index.context";version="1.0.0",org.apa + che.maven.index.util.zip;version="1.0.0",org.apache.maven.wagon;uses:=" + org.apache.maven.wagon.authentication,org.apache.maven.wagon.authorizat + ion,org.apache.maven.wagon.events,org.apache.maven.wagon.proxy,org.apac + he.maven.wagon.repository,org.apache.maven.wagon.resource";version="1.0 + .0",org.apache.maven.wagon.authentication;uses:="org.apache.maven.wagon + ";version="1.0.0",org.apache.maven.wagon.authorization;uses:="org.apach + e.maven.wagon";version="1.0.0",org.apache.maven.wagon.events;uses:="org + .apache.maven.wagon,org.apache.maven.wagon.resource";version="1.0.0",or + g.apache.maven.wagon.observers;uses:="org.apache.maven.wagon.events";ve + rsion="1.0.0",org.apache.maven.wagon.providers.http;uses:="org.apache.m + aven.wagon,org.apache.maven.wagon.authentication,org.apache.maven.wagon + .authorization,org.apache.maven.wagon.proxy,org.apache.maven.wagon.reso + urce";version="1.0.0",org.apache.maven.wagon.proxy;version="1.0.0",org. + apache.maven.wagon.repository;version="1.0.0",org.apache.maven.wagon.re + source;version="1.0.0",org.apache.maven.wagon.shared.http4;uses:="org.a + pache.maven.wagon,org.apache.maven.wagon.authorization,org.apache.maven + .wagon.repository,org.apache.maven.wagon.resource";version="1.0.0" +Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))" +Tool: Bnd-3.3.0.201609221906 diff --git a/modules/crce-external-repository/pom.xml b/modules/crce-external-repository/pom.xml new file mode 100644 index 00000000..92eb7d61 --- /dev/null +++ b/modules/crce-external-repository/pom.xml @@ -0,0 +1,397 @@ + + 4.0.0 + + ../pom + cz.zcu.kiv.crce + crce-modules-parent + 2.1.1-SNAPSHOT + + crce-external-repository + 1.0 + CRCE - External repository support + + bundle + + + CRCE - External repository + ${namespace}.crce_external_repository + UTF-8 + 1.8 + + + + + + + + + org.sonatype.aether + aether-api + 1.13.1 + + + org.sonatype.aether + aether-util + 1.13.1 + + + org.eclipse.aether + aether-impl + 1.1.0 + + + org.eclipse.aether + aether-spi + 1.1.0 + + + org.eclipse.aether + aether-connector-basic + 1.1.0 + + + org.eclipse.aether + aether-transport-file + 1.1.0 + + + org.eclipse.aether + aether-transport-http + 1.1.0 + + + org.apache.maven + maven-aether-provider + 3.3.9 + + + org.apache.maven + maven-artifact + 3.3.9 + + + org.slf4j + slf4j-simple + 1.7.22 + + + org.jsoup + jsoup + 1.10.3 + + + org.apache.httpcomponents + httpcore + 4.3.2 + + + org.apache.httpcomponents + httpclient + 4.3.5 + + + com.google.guava + guava + 18.0 + + + org.w3c.css + sac + 1.3 + + + org.apache.maven + maven-repository-metadata + 3.3.9 + + + org.codehaus.plexus + plexus-component-annotations + 1.6 + + + org.codehaus.plexus + plexus-interpolation + 1.21 + + + org.codehaus.plexus + plexus-utils + 3.0.22 + + + org.eclipse.sisu + org.eclipse.sisu.plexus + 0.3.3 + + + org.eclipse.sisu + org.eclipse.sisu.inject + 0.3.3 + + + commons-codec + commons-codec + 1.6 + + + org.apache.maven + maven-model + 3.3.9 + + + org.apache.maven + maven-model-builder + 3.3.9 + + + org.apache.maven + maven-builder-support + 3.3.9 + + + com.vaadin.external.flute + flute + 1.3.0.gg2 + + + org.apache.maven.indexer + indexer-core + 5.1.2-4333789 + + + org.apache.maven.wagon + wagon-http-lightweight + 2.3 + + + org.apache.maven.wagon + wagon-provider-api + 2.3 + + + org.apache.maven.wagon + wagon-http-shared4 + 2.3 + + + org.apache.maven.indexer + indexer-artifact + 5.1.2-4333789 + + + org.apache.lucene + lucene-core + 3.6.2 + + + org.apache.lucene + lucene-queries + 3.6.2 + + + org.apache.lucene + lucene-memory + 3.6.2 + + + org.apache.lucene + lucene-highlighter + 3.6.2 + + + org.sonatype.sisu + sisu-guice + 3.2.6 + + + + + + org.sonatype.aether + aether-api + + + org.sonatype.aether + aether-util + + + org.eclipse.aether + aether-impl + + + org.eclipse.aether + aether-spi + + + org.eclipse.aether + aether-connector-basic + + + org.eclipse.aether + aether-transport-file + + + org.eclipse.aether + aether-transport-http + + + org.apache.maven + maven-aether-provider + + + org.apache.maven + maven-artifact + + + org.apache.maven + maven-builder-support + + + org.slf4j + slf4j-simple + + + org.jsoup + jsoup + + + commons-codec + commons-codec + + + org.apache.maven + maven-model + + + org.apache.maven + maven-model-builder + + + com.vaadin.external.flute + flute + + + org.apache.httpcomponents + httpcore + + + org.apache.httpcomponents + httpclient + + + com.google.guava + guava + + + org.w3c.css + sac + + + org.apache.maven + maven-repository-metadata + + + org.codehaus.plexus + plexus-component-annotations + + + org.codehaus.plexus + plexus-interpolation + + + org.codehaus.plexus + plexus-utils + + + org.eclipse.sisu + org.eclipse.sisu.plexus + + + org.eclipse.sisu + org.eclipse.sisu.inject + + + org.apache.maven.indexer + indexer-core + + + org.apache.maven.wagon + wagon-http-lightweight + + + org.apache.maven.wagon + wagon-provider-api + + + org.apache.maven.wagon + wagon-http-shared4 + + + org.apache.maven.indexer + indexer-artifact + + + org.apache.lucene + lucene-core + + + org.apache.lucene + lucene-queries + + + org.apache.lucene + lucene-memory + + + org.apache.lucene + lucene-highlighter + + + org.sonatype.sisu + sisu-guice + + + + + + org.apache.felix + maven-bundle-plugin + true + + META-INF + + ${bundle.namespace}.internal.Activator + ${project.artifactId} + cz.zcu.kiv.crce.crce_external_repository.internal.* + + cz.zcu.kiv.crce.crce_external_repository.api, + org.apache.maven.index.*, + org.apache.maven.wagon.* + + * + + !${bundle.namespace}.internal.* + + !sisu-guice,*;scope=compile|runtime;inline=false + lib + true + + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + + + + + \ No newline at end of file diff --git a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/ArtifactTree.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/ArtifactTree.java new file mode 100644 index 00000000..4f631ec5 --- /dev/null +++ b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/ArtifactTree.java @@ -0,0 +1,45 @@ +package cz.zcu.kiv.crce.crce_external_repository.api; + +import java.util.List; + +public class ArtifactTree { + private String groupId; + private String artefactId; + private List versions; + private String packaging; + private String url; + + public ArtifactTree(String groupId, String artefactId, List versions, String packaging) { + super(); + this.groupId = groupId; + this.artefactId = artefactId; + this.versions = versions; + this.packaging = packaging; + } + public String getGroupId() { + return groupId; + } + public String getArtefactId() { + return artefactId; + } + public List getVersions() { + return versions; + } + public String getPackaging() { + return packaging; + } + public String getUrl() { + return url; + } + public void setUrl(String url) { + this.url = url; + } + public String getCaption(String version) { + for(String v : this.versions) { + if(v.equals(version)){ + return groupId + ":" + artefactId + ":" + version + ":" + packaging; + } + } + return null; + } +} diff --git a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/CentralMaven.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/CentralMaven.java new file mode 100644 index 00000000..cc7c19a8 --- /dev/null +++ b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/CentralMaven.java @@ -0,0 +1,148 @@ +package cz.zcu.kiv.crce.crce_external_repository.api; + +import java.io.IOException; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.index.ArtifactInfo; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; + +public class CentralMaven { + private String centralMavenUrl; + private boolean enableGroupSearch; + private List artifactTreeList = new ArrayList(); + private SettingsUrl settings; + + public CentralMaven(SettingsUrl settings) { + this.settings = settings; + } + + public ResultSearchArtifactTree getArtifactTree(String group, String artifact, String version, Object packaging, Object directIndex, + String range) { + if (settings == null) { + SettingsUrl settings = new SettingsUrl(); + centralMavenUrl = settings.getCentralMavenUrl(); + enableGroupSearch = settings.isEnableGroupSearch(); + } else { + centralMavenUrl = settings.getCentralMavenUrl(); + enableGroupSearch = settings.isEnableGroupSearch(); + } + // reset tree + artifactTreeList.clear(); + // direct search + if (directIndex.equals("Direct")) { + if (!artifact.isEmpty() || !version.isEmpty()) { + directSearch(group, artifact, version, packaging.toString()); + } else if (enableGroupSearch && !group.isEmpty()) { + onlyGroupSearch(group); + if(artifactTreeList.size() == 0) { + return new ResultSearchArtifactTree(null, "not found"); + } + else { + return new ResultSearchArtifactTree(artifactTreeList, "group"); + } + } + if (artifactTreeList.size() == 0) { + return new ResultSearchArtifactTree(null, "artifact not found"); + } else { + return new ResultSearchArtifactTree(artifactTreeList, "direct"); + } + } + // index search + else { + indexSearch(group, artifact, version, packaging.toString(), range); + if (artifactTreeList.size() == 0) { + return new ResultSearchArtifactTree(null, "notfound"); + } else { + return new ResultSearchArtifactTree(artifactTreeList, "found"); + } + } + } + + private void directSearch(String group, String artifact, String version, String packaging) { + URL website; + try { + website = new URL(centralMavenUrl + group.replace('.', '/') + "/" + artifact + "/" + version + "/" + + artifact + "-" + version + "." + packaging); + ReadableByteChannel rbc = Channels.newChannel(website.openStream()); + if (rbc.isOpen()) { + List versions = new ArrayList(); + versions.add(version); + ArtifactTree artifactTree = new ArtifactTree(group, artifact, versions, packaging); + artifactTree.setUrl(centralMavenUrl); + artifactTreeList.add(artifactTree); + rbc.close(); + } + } catch (IOException e) { + artifactTreeList.clear(); + } + } + + private void onlyGroupSearch(String group) { + try { + list(new URL(centralMavenUrl + group.replace('.', '/') + "/")); + } catch (IOException e) { + artifactTreeList.clear(); + } + } + + private void list(URL path) throws IOException { + Document doc = Jsoup.connect(path.toString()).get(); + for (Element file : doc.select("a").not("[href=../]")) { + if (file.text().endsWith("/")) { + list(new URL(path.toString() + file.text())); + } else { + ArtifactTree artifactTree = new ArtifactTree(path.getPath(), file.text(), null, file.text() + .substring(file.text().lastIndexOf('.') + 1)); + if(path.getPort() == -1) { + artifactTree.setUrl(path.getProtocol() + "://" + path.getHost() + path.getPath() + file.text()); + } + else { + artifactTree.setUrl(path.getProtocol() + "://" + path.getHost() + ":" + path.getPort() + path.getPath() + file.text()); + } + artifactTreeList.add(artifactTree); + } + } + } + + private void indexSearch(String group, String artifact, String version, String packaging, String range){ + MavenIndex mavenIndex = null; + try { + mavenIndex = new MavenIndex(); + List artifactInfoList = mavenIndex.searchArtefact(settings, group, artifact, version, + packaging, range); + for (ArtifactInfo ai : artifactInfoList) { + // list už obsahuje artefakt ? ano přidáme verzi + boolean find = false; + for(ArtifactTree artefactTree : artifactTreeList) { + if(artefactTree .getGroupId().equals(ai.groupId) && artefactTree.getArtefactId().equals(ai.artifactId) && + artefactTree.getPackaging().equals(ai.packaging)) { + find = true; + List versions = artefactTree .getVersions(); + versions.add(ai.version); + ArtifactTree newArtefactTree = new ArtifactTree(ai.groupId, ai.artifactId, versions, ai.packaging); + newArtefactTree.setUrl(artefactTree.getUrl()); + artifactTreeList.remove(artefactTree); + artifactTreeList.add(newArtefactTree); + break; + } + } + if(!find) { + List versions = new ArrayList(); + versions.add(ai.version); + ArtifactTree artifactTree = new ArtifactTree(ai.groupId, ai.artifactId, versions, ai.packaging); + artifactTree.setUrl(centralMavenUrl); + artifactTreeList.add(artifactTree); + } + } + } + catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/DefinedMaven.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/DefinedMaven.java similarity index 65% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/DefinedMaven.java rename to modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/DefinedMaven.java index 7d4db89d..a949afea 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/DefinedMaven.java +++ b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/DefinedMaven.java @@ -1,6 +1,9 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes; +package cz.zcu.kiv.crce.crce_external_repository.api; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; + import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; @@ -23,34 +26,36 @@ import org.eclipse.aether.transport.http.HttpTransporterFactory; import org.eclipse.aether.version.Version; -import com.vaadin.server.FontAwesome; -import com.vaadin.ui.Tree; - public class DefinedMaven { - private Tree definedMavenTree = new Tree("Result Search"); + private ArtifactTree definedArtefact; private String groupText; private String idText; private String versionText; private String packagingText; + private SettingsUrl settings; public DefinedMaven(SettingsUrl settings) { this.settings = settings; } - public Tree getTree(String group, String idText, String version, Object packaging) { + public ArtifactTree getArtifact(String group, String idText, String version, Object packaging) { // validator empty entries if (group.equals("") || idText.equals("")) { return null; } else { - // reset tree - definedMavenTree.removeAllItems(); this.groupText = group; this.idText = idText; this.versionText = version; this.packagingText = packaging.toString(); callAetherLib(); - return definedMavenTree; + /* + * System.out.println(new File(settings.getLocalAetherUrl()).mkdirs()); + * List pomoc = new ArrayList(); pomoc.add("0.0.0"); + * + * definedArtefact = new ArtifactTree("cz.pokus", "pokusId", pomoc, "jar"); + */ + return definedArtefact; } } @@ -59,8 +64,6 @@ private void callAetherLib() { .build(); RepositorySystem repoSystem = newRepositorySystem(); RepositorySystemSession session = newSession(repoSystem, settings.getLocalAetherUrl()); - - // Artifact artifact = new DefaultArtifact("groupId:artifactId:(0,]"); Artifact artifact; if (!versionText.equals("")) { artifact = new DefaultArtifact(groupText + ":" + idText + ":" + "[" + versionText + "]"); @@ -71,22 +74,18 @@ private void callAetherLib() { try { VersionRangeResult versionResult = repoSystem.resolveVersionRange(session, request); if (versionResult.getVersions().isEmpty()) { - definedMavenTree = null; + definedArtefact = null; } else { - String[] pom = artifact.getGroupId().split("\\."); - definedMavenTree.addItem(pom[0]); - for (int i = 1; i < pom.length; i++) { - definedMavenTree.addItem(pom[i]); - definedMavenTree.setParent(pom[i], pom[i - 1]); - } - + List versionTextList = new ArrayList(); if (versionResult.getVersions().size() > 1) { for (Version v : versionResult.getVersions()) { - addArtefactToTree(artifact, v, pom[pom.length - 1]); + versionTextList.add(v.toString()); } } else { - addArtefactToTree(artifact, versionResult.getHighestVersion(), pom[pom.length - 1]); + versionTextList.add(versionResult.getHighestVersion().toString()); } + definedArtefact = new ArtifactTree(artifact.getGroupId(), artifact.getArtifactId(), versionTextList, + packagingText); } } catch (VersionRangeResolutionException e) { @@ -94,41 +93,13 @@ private void callAetherLib() { } } - private void addArtefactToTree(Artifact artifact, Version version, String parent) { - definedMavenTree.addItem(artifact.getArtifactId()); - definedMavenTree.setParent(artifact.getArtifactId(), parent); - definedMavenTree.addItem(version.toString()); - definedMavenTree.setParent(version.toString(), artifact.getArtifactId()); - - // konečný artefact je komplet url link např. pro wget - UPRAVIT DLE - // POTŘEBY - /* - * String artifactText = settings.getExternalAetherUrl() + "/" + - * groupText + "/" + idText + "/" + version + "." + packagingText; - */ - String artifactText = groupText + ":" + idText + ":" + version + ":" + packagingText; - - definedMavenTree.addItem(artifactText); - definedMavenTree.setParent(artifactText, version.toString()); - definedMavenTree.setItemCaption(artifactText, - artifact.getArtifactId() + "-" + version.toString() + "." + packagingText); - definedMavenTree.setChildrenAllowed(artifactText, false); - if (packagingText.equals("jar") || packagingText.equals("war")) { - definedMavenTree.setItemIcon(artifactText, FontAwesome.GIFT); - } else if (packagingText.equals("xml") || packagingText.equals("pom")) { - definedMavenTree.setItemIcon(artifactText, FontAwesome.CODE); - } else { - definedMavenTree.setItemIcon(artifactText, FontAwesome.FILE); - } - } - - public static boolean resolveArtefact(String artifactText, SettingsUrl settings) { + public static boolean resolveArtifact(String artifactText, SettingsUrl settings) { RepositorySystem repoSystem = newRepositorySystem(); RepositorySystemSession session = newSession(repoSystem, settings.getLocalAetherUrl()); ArtifactRequest artifactRequest = new ArtifactRequest(); - Artifact artifact = new DefaultArtifact(artifactText.split(":")[0] + ":" + artifactText.split(":")[1] + ":" + - artifactText.split(":")[3] + ":" + artifactText.split(":")[2]); + Artifact artifact = new DefaultArtifact(artifactText.split(":")[0] + ":" + artifactText.split(":")[1] + ":" + + artifactText.split(":")[3] + ":" + artifactText.split(":")[2]); artifactRequest.setArtifact(artifact); @@ -148,6 +119,13 @@ private static RepositorySystem newRepositorySystem() { locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); locator.addService(TransporterFactory.class, FileTransporterFactory.class); locator.addService(TransporterFactory.class, HttpTransporterFactory.class); + locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler(){ + @Override + public void serviceCreationFailed( Class type, Class impl, Throwable exception ) + { + exception.printStackTrace(); + } + }); return locator.getService(RepositorySystem.class); } @@ -161,4 +139,4 @@ private static RepositorySystemSession newSession(RepositorySystem system, Strin public static RemoteRepository newCentralRepository(String centralAetherUrl) { return new RemoteRepository.Builder("central", "default", centralAetherUrl).build(); } -} +} \ No newline at end of file diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/MavenIndex.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/MavenIndex.java similarity index 88% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/MavenIndex.java rename to modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/MavenIndex.java index cffe16d9..77123da2 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/MavenIndex.java +++ b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/MavenIndex.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes; +package cz.zcu.kiv.crce.crce_external_repository.api; import java.io.File; import java.io.IOException; @@ -37,21 +37,19 @@ import org.eclipse.aether.util.version.GenericVersionScheme; import org.eclipse.aether.version.Version; -import com.vaadin.server.VaadinSession; - public class MavenIndex { private String centralCachePath = "repository-index/central-cache"; private String centralIndexPath = "repository-index/central-index"; - public String checkIndex(VaadinSession session) throws Exception { + public String checkIndex(SettingsUrl settings) throws Exception { final MavenIndex indexCentralRepository = new MavenIndex(); - return indexCentralRepository.perform(session); + return indexCentralRepository.perform(settings); } - public List searchArtefact(VaadinSession session, String group, String artifact, + public List searchArtefact(SettingsUrl settings, String group, String artifact, String version, String packaging, String range) throws Exception { final MavenIndex indexCentralRepository = new MavenIndex(); - return indexCentralRepository.getArtefact(session, group, artifact, version, packaging, range); + return indexCentralRepository.getArtefact(settings, group, artifact, version, packaging, range); } private final PlexusContainer plexusContainer; @@ -61,13 +59,16 @@ public List searchArtefact(VaadinSession session, String group, St private IndexingContext centralContext; public MavenIndex() throws PlexusContainerException, ComponentLookupException { + /*final DefaultContainerConfiguration config = new DefaultContainerConfiguration(); + config.setClassPathScanning(PlexusConstants.SCANNING_INDEX); + this.plexusContainer = new DefaultPlexusContainer(config);*/ this.plexusContainer = new DefaultPlexusContainer(); this.indexer = plexusContainer.lookup(Indexer.class); this.indexUpdater = plexusContainer.lookup(IndexUpdater.class); this.httpWagon = plexusContainer.lookup(Wagon.class, "http"); } - private String perform(VaadinSession session) + private String perform(SettingsUrl settings) throws IOException, ComponentLookupException, InvalidVersionSpecificationException { File centralLocalCache = new File(centralCachePath); File centralIndexDir = new File(centralIndexPath); @@ -80,13 +81,13 @@ private String perform(VaadinSession session) // Create context for central repository index - if (session.getAttribute("settingsUrl") == null) { + if (settings == null) { SettingsUrl settingsUrl = new SettingsUrl(); centralContext = indexer.createIndexingContext("central-context", "central", centralLocalCache, centralIndexDir, settingsUrl.getCentralMavenUrl(), null, true, true, indexers); } else { centralContext = indexer.createIndexingContext("central-context", "central", centralLocalCache, - centralIndexDir, ((SettingsUrl) session.getAttribute("settingsUrl")).getCentralMavenUrl(), null, + centralIndexDir, settings.getCentralMavenUrl(), null, true, true, indexers); } @@ -114,7 +115,6 @@ public void transferCompleted(TransferEvent transferEvent) { closeIndexer(); - session.setAttribute("mavenIndex", true); if (updateResult.isFullUpdate()) { return "Full update happened!"; } else if (updateResult.getTimestamp().equals(centralContextCurrentTimestamp)) { @@ -125,7 +125,7 @@ public void transferCompleted(TransferEvent transferEvent) { } } - private List getArtefact(VaadinSession session, String group, String artifact, String version, String packaging, String range) + private List getArtefact(SettingsUrl settings, String group, String artifact, String version, String packaging, String range) throws IOException, ComponentLookupException, InvalidVersionSpecificationException { File centralLocalCache = new File(centralCachePath); @@ -139,13 +139,13 @@ private List getArtefact(VaadinSession session, String group, Stri // Create context for central repository index - if (session.getAttribute("settingsUrl") == null) { + if (settings == null) { SettingsUrl settingsUrl = new SettingsUrl(); centralContext = indexer.createIndexingContext("central-context", "central", centralLocalCache, centralIndexDir, settingsUrl.getCentralMavenUrl(), null, true, true, indexers); } else { centralContext = indexer.createIndexingContext("central-context", "central", centralLocalCache, - centralIndexDir, ((SettingsUrl) session.getAttribute("settingsUrl")).getCentralMavenUrl(), null, + centralIndexDir, settings.getCentralMavenUrl(), null, true, true, indexers); } diff --git a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/ResultSearchArtifactTree.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/ResultSearchArtifactTree.java new file mode 100644 index 00000000..c46cd49b --- /dev/null +++ b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/ResultSearchArtifactTree.java @@ -0,0 +1,19 @@ +package cz.zcu.kiv.crce.crce_external_repository.api; + +import java.util.List; + +public class ResultSearchArtifactTree { + private String status; + private List artifactTreeList; + public ResultSearchArtifactTree(List artifactTreeList, String status) { + super(); + this.status = status; + this.artifactTreeList = artifactTreeList; + } + public String getStatus() { + return status; + } + public List getArtifactTreeList() { + return artifactTreeList; + } +} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/SettingsUrl.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/SettingsUrl.java similarity index 94% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/SettingsUrl.java rename to modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/SettingsUrl.java index 99ae929c..177aa6e9 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/SettingsUrl.java +++ b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/SettingsUrl.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes; +package cz.zcu.kiv.crce.crce_external_repository.api; public class SettingsUrl{ private String centralMavenUrl = "http://repo.maven.apache.org/maven2/"; @@ -38,3 +38,4 @@ public void setEnableGroupSearch(boolean enableGroupSearch) { this.enableGroupSearch = enableGroupSearch; } } + diff --git a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/internal/Activator.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/internal/Activator.java new file mode 100644 index 00000000..b0d6d90e --- /dev/null +++ b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/internal/Activator.java @@ -0,0 +1,35 @@ +package cz.zcu.kiv.crce.crce_external_repository.internal; + +import org.apache.felix.dm.DependencyActivatorBase; +import org.apache.felix.dm.DependencyManager; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Activator extends DependencyActivatorBase{ + + private static final Logger logger = LoggerFactory.getLogger(Activator.class); + + private static volatile Activator instance; + + public static Activator instance() { + if (instance == null) { + throw new IllegalStateException("Activator instance is null."); + } + return instance; + } + + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "Workaround for providing DM components.") + @Override + public void init(BundleContext context, DependencyManager manager) throws Exception { + instance = this; + + manager.add(createComponent().setImplementation(this)); + logger.debug("External repository activator initialized."); + } + + @Override + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + // nothing to do + } +} diff --git a/modules/crce-handler-metrics/.classpath b/modules/crce-handler-metrics/.classpath index f619a536..0556be39 100644 --- a/modules/crce-handler-metrics/.classpath +++ b/modules/crce-handler-metrics/.classpath @@ -17,7 +17,7 @@ - + diff --git a/modules/crce-handler-metrics/.project b/modules/crce-handler-metrics/.project index e42aad3c..79c89f14 100644 --- a/modules/crce-handler-metrics/.project +++ b/modules/crce-handler-metrics/.project @@ -10,6 +10,11 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + org.eclipse.m2e.core.maven2Builder @@ -17,6 +22,7 @@ + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/modules/crce-integration-tests/.project b/modules/crce-integration-tests/.project index 9a6c3a99..da2260e0 100644 --- a/modules/crce-integration-tests/.project +++ b/modules/crce-integration-tests/.project @@ -10,6 +10,11 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + org.eclipse.m2e.core.maven2Builder @@ -17,6 +22,7 @@ + org.fusesource.ide.project.RiderProjectNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/modules/crce-metadata-osgi-bundle/.classpath b/modules/crce-metadata-osgi-bundle/.classpath index a6731491..a086d4a1 100644 --- a/modules/crce-metadata-osgi-bundle/.classpath +++ b/modules/crce-metadata-osgi-bundle/.classpath @@ -17,7 +17,7 @@ - + diff --git a/modules/crce-metadata-osgi-bundle/.project b/modules/crce-metadata-osgi-bundle/.project index 63712ada..1ac6ed03 100644 --- a/modules/crce-metadata-osgi-bundle/.project +++ b/modules/crce-metadata-osgi-bundle/.project @@ -30,6 +30,11 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + org.eclipse.m2e.core.maven2Builder @@ -37,6 +42,7 @@ + org.fusesource.ide.project.RiderProjectNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.pde.PluginNature diff --git a/modules/crce-rest-v2/.classpath b/modules/crce-rest-v2/.classpath index 79855789..f4dcec35 100644 --- a/modules/crce-rest-v2/.classpath +++ b/modules/crce-rest-v2/.classpath @@ -12,7 +12,7 @@ - + diff --git a/modules/crce-rest-v2/.project b/modules/crce-rest-v2/.project index a8444c13..d3e6acfe 100644 --- a/modules/crce-rest-v2/.project +++ b/modules/crce-rest-v2/.project @@ -30,8 +30,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature diff --git a/modules/crce-vo/.classpath b/modules/crce-vo/.classpath index da3f7efb..ff36ca09 100644 --- a/modules/crce-vo/.classpath +++ b/modules/crce-vo/.classpath @@ -22,7 +22,7 @@ - + diff --git a/modules/crce-vo/.project b/modules/crce-vo/.project index d05aee05..ad056ea7 100644 --- a/modules/crce-vo/.project +++ b/modules/crce-vo/.project @@ -35,8 +35,14 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + + org.fusesource.ide.project.RiderProjectNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.pde.PluginNature diff --git a/modules/crce-webservices-indexer/.classpath b/modules/crce-webservices-indexer/.classpath index f619a536..0556be39 100644 --- a/modules/crce-webservices-indexer/.classpath +++ b/modules/crce-webservices-indexer/.classpath @@ -17,7 +17,7 @@ - + diff --git a/modules/crce-webservices-indexer/.project b/modules/crce-webservices-indexer/.project index ac410930..8f8edfa3 100644 --- a/modules/crce-webservices-indexer/.project +++ b/modules/crce-webservices-indexer/.project @@ -10,6 +10,11 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + org.eclipse.m2e.core.maven2Builder @@ -17,6 +22,7 @@ + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/modules/crce-webui-vaadin/.classpath b/modules/crce-webui-vaadin/.classpath index 6c0e1a79..54b64112 100644 --- a/modules/crce-webui-vaadin/.classpath +++ b/modules/crce-webui-vaadin/.classpath @@ -17,7 +17,7 @@ - + diff --git a/modules/crce-webui-vaadin/.project b/modules/crce-webui-vaadin/.project index 05d97306..f693cc9b 100644 --- a/modules/crce-webui-vaadin/.project +++ b/modules/crce-webui-vaadin/.project @@ -30,6 +30,11 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + org.eclipse.m2e.core.maven2Builder @@ -37,6 +42,7 @@ + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature diff --git a/modules/crce-webui-vaadin/pom.xml b/modules/crce-webui-vaadin/pom.xml index 0623a2cc..d16943a4 100644 --- a/modules/crce-webui-vaadin/pom.xml +++ b/modules/crce-webui-vaadin/pom.xml @@ -48,7 +48,7 @@ pom import - + @@ -138,7 +138,7 @@ com.vaadin vaadin-themes - + cz.zcu.kiv.crce crce-metadata-osgi-bundle @@ -202,6 +202,12 @@ 2.1.1-SNAPSHOT bundle + + cz.zcu.kiv.crce + crce-external-repository + 1.0 + bundle + @@ -279,11 +285,14 @@ * - !${bundle.namespace}.internal.* + + cz.zcu.kiv.crce.crce_external_repository.api, + !${bundle.namespace}.internal.* + ${bundle.namespace}.internal.Activator ${project.artifactId} - WEB-INF/classes, + WEB-INF/classes crce-vaadin crce-vaadin diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java index 13efabc4..609774f0 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java @@ -6,10 +6,8 @@ import java.net.URL; import java.util.EnumSet; -import com.vaadin.event.ShortcutListener; -import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.server.FontAwesome; import com.vaadin.server.Page; -import com.vaadin.server.VaadinSession; import com.vaadin.shared.Position; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.ui.Alignment; @@ -20,15 +18,18 @@ import com.vaadin.ui.NativeSelect; import com.vaadin.ui.Notification; import com.vaadin.ui.OptionGroup; +import com.vaadin.ui.Panel; import com.vaadin.ui.TextField; import com.vaadin.ui.Tree; import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; +import cz.zcu.kiv.crce.crce_external_repository.api.ArtifactTree; +import cz.zcu.kiv.crce.crce_external_repository.api.CentralMaven; +import cz.zcu.kiv.crce.crce_external_repository.api.ResultSearchArtifactTree; +import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; -import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.CentralMaven; import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; import cz.zcu.kiv.crce.repository.RefusedArtifactException; @@ -44,7 +45,9 @@ public class CentralMavenForm extends FormLayout { private Button searchButton = new Button("Search"); private Button clearButton = new Button("Clear"); private Label notFound = new Label("No artifact found"); - private Tree tree; + private Panel treePanel = new Panel("Result list"); + private Button uploadButton = new Button("Upload"); + private Tree tree = new Tree(); public CentralMavenForm() { HorizontalLayout content = new HorizontalLayout(); @@ -55,25 +58,26 @@ public CentralMavenForm(MyUI myUI) { VerticalLayout userForm = new VerticalLayout(); HorizontalLayout content = new HorizontalLayout(); HorizontalLayout versionLayout = new HorizontalLayout(); + VerticalLayout formPanelButtonLayout = new VerticalLayout(); packaging.addItems(EnumSet.allOf(TypePackaging.class)); packaging.select(TypePackaging.jar); packaging.setNullSelectionAllowed(false); - + caption.addStyleName(ValoTheme.LABEL_BOLD); - + group.setWidth("250px"); artifact.setWidth("250px"); - + directIndexOption.addItems("Direct", "Index"); directIndexOption.setValue("Direct"); - + rangeOption.addItem("<="); rangeOption.addItem("="); rangeOption.addItem(">="); rangeOption.select("="); rangeOption.setNullSelectionAllowed(false); rangeOption.setEnabled(false); - + versionLayout.addComponents(version, rangeOption); versionLayout.setSpacing(true); @@ -84,64 +88,195 @@ public CentralMavenForm(MyUI myUI) { userForm.addComponents(caption, group, artifact, versionLayout, packaging, directIndexOption, buttons); userForm.setSpacing(true); userForm.setMargin(new MarginInfo(false, true)); + + treePanel.setWidth("600px"); + treePanel.setHeight("380px"); + content.addComponent(userForm); // Add tree searchButton.addClickListener(e -> { + // clear tree + tree.removeAllItems(); // no function tree.clear(); // erasing any previous components shown - if (content.getComponentIndex(notFound) != -1) { - content.removeComponent(notFound); - } - if (content.getComponentIndex(tree) != -1) { - content.removeComponent(tree); + if (content.getComponentIndex(formPanelButtonLayout) != -1) { + content.removeComponent(formPanelButtonLayout); } // check exist component from central Maven repository - if(directIndexOption.getValue().equals("Direct")){ - tree = new CentralMaven(myUI.getSession()).getTree(group.getValue(), artifact.getValue(), version.getValue(), - packaging.getValue(), directIndexOption.getValue(), null); + if (directIndexOption.getValue().equals("Direct")) { + ResultSearchArtifactTree artifactList = new CentralMaven( + (SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).getArtifactTree(group.getValue(), + artifact.getValue(), version.getValue(), packaging.getValue(), + directIndexOption.getValue(), null); + if (artifactList.getArtifactTreeList() != null && artifactList.getStatus().equals("direct")) { + ArtifactTree artifactTree = artifactList.getArtifactTreeList().get(0); + String[] pom = artifactTree.getGroupId().split("\\."); + tree.addItem(pom[0]); + for (int i = 1; i < pom.length; i++) { + tree.addItem(pom[i]); + tree.setParent(pom[i], pom[i - 1]); + } + //addArtifactToTree(artifactTree, pom[pom.length - 1]); + addArtifactToTree(artifactTree.getUrl(), artifactTree.getGroupId(), artifactTree.getArtefactId(), + artifactTree.getVersions().get(0), artifactTree.getPackaging(), pom[pom.length - 1]); + + // for margin + HorizontalLayout treePanelLayout = new HorizontalLayout(); + treePanelLayout.addComponent(tree); + treePanelLayout.setMargin(true); + treePanel.setContent(treePanelLayout); + formPanelButtonLayout.addComponents(treePanel, uploadButton); + formPanelButtonLayout.setMargin(true); + formPanelButtonLayout.setSpacing(true); + formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); + uploadButton.setVisible(false); + } else if (artifactList.getArtifactTreeList() != null && artifactList.getStatus().equals("group")) { + for (ArtifactTree artifactTree : artifactList.getArtifactTreeList()) { + String[] pom = artifactTree.getGroupId().split("/"); + String uniqueItemChildren, uniqueItemParent = "/"; + + /*for central maven2 url - the correct is the listing over all items, + but in this case the first is empty and the second is maven2*/ + for(int i = 2; i < pom.length; i++) { + uniqueItemChildren = uniqueItemParent + pom[i] + "/"; + if(tree.getItem(uniqueItemChildren) == null) { + tree.addItem(uniqueItemChildren); + tree.setItemCaption(uniqueItemChildren, pom[i]); + tree.setParent(uniqueItemChildren, uniqueItemParent); + } + uniqueItemParent = uniqueItemChildren; + } + addArtefactToTreeGroup(artifactTree, uniqueItemParent); + /*for (int i = 1; i < pom.length; i++) { + uniqueItem = uniqueItem + pom[i]; + + if (tree.getItem(pom[i]) == null) { + tree.addItem(pom[i]); + tree.setParent(pom[i], pom[i - 1]); + } else { + tree.setParent(pom[i], pom[i - 1]); + } + } + addArtefactToTreeGroup(artifactTree, pom[pom.length - 1]);*/ + } + // for margin + HorizontalLayout treePanelLayout = new HorizontalLayout(); + treePanelLayout.addComponent(tree); + treePanelLayout.setMargin(true); + treePanel.setContent(treePanelLayout); + formPanelButtonLayout.addComponents(treePanel, uploadButton); + formPanelButtonLayout.setMargin(true); + formPanelButtonLayout.setSpacing(true); + formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); + uploadButton.setVisible(false); + } else { + // for margin + HorizontalLayout treePanelLayout = new HorizontalLayout(); + treePanelLayout.addComponent(notFound); + treePanelLayout.setMargin(true); + treePanel.setContent(treePanelLayout); + formPanelButtonLayout.addComponents(treePanel); + formPanelButtonLayout.setMargin(true); + } } - else{ - if(group.getValue().trim().isEmpty() || artifact.getValue().trim().isEmpty()){ - Notification notif = new Notification("Incomplete assignment!", - Notification.Type.WARNING_MESSAGE); + // index search + else { + if (group.getValue().trim().isEmpty() || artifact.getValue().trim().isEmpty()) { + Notification notif = new Notification("Incomplete assignment!", Notification.Type.WARNING_MESSAGE); notif.setDelayMsec(5000); notif.show(Page.getCurrent()); - } - else if(group.getValue().charAt(0) == '*' || group.getValue().charAt(0) == '?' || artifact.getValue().charAt(0) == '*' - || artifact.getValue().charAt(0) == '?'){ + } else if (group.getValue().charAt(0) == '*' || group.getValue().charAt(0) == '?' + || artifact.getValue().charAt(0) == '*' || artifact.getValue().charAt(0) == '?') { Notification notif = new Notification("Can not start a search term with '*' or '?'", Notification.Type.WARNING_MESSAGE); notif.setDelayMsec(5000); notif.show(Page.getCurrent()); - } - else{ - tree = new CentralMaven(myUI.getSession()).getTree(group.getValue(), artifact.getValue(), version.getValue(), - packaging.getValue(), directIndexOption.getValue(), rangeOption.getValue().toString()); + } else { + if(myUI.getSession().getAttribute("mavenIndex") == null) { + Notification notif = new Notification( + "The central maven repository index is not created. Check its creation in the settings menu", + Notification.Type.WARNING_MESSAGE); + notif.setDelayMsec(5000); + notif.show(Page.getCurrent()); + } + else { + ResultSearchArtifactTree artifactList = new CentralMaven( + (SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).getArtifactTree(group.getValue(), + artifact.getValue(), version.getValue(), packaging.getValue(), + directIndexOption.getValue(), rangeOption.getValue().toString()); + if(artifactList.getStatus().equals("found")) { + for (ArtifactTree artifactTree : artifactList.getArtifactTreeList()) { + String[] pom = artifactTree.getGroupId().split("\\."); + tree.addItem(pom[0]); + for (int i = 1; i < pom.length; i++) { + tree.addItem(pom[i]); + tree.setParent(pom[i], pom[i - 1]); + } + for (String s : artifactTree.getVersions()) { + addArtifactToTree(artifactTree.getUrl(), artifactTree.getGroupId(), artifactTree.getArtefactId(), s, + artifactTree.getPackaging(),pom[pom.length - 1]); + } + } + // for margin + HorizontalLayout treePanelLayout = new HorizontalLayout(); + treePanelLayout.addComponent(tree); + treePanelLayout.setMargin(true); + treePanel.setContent(treePanelLayout); + formPanelButtonLayout.addComponents(treePanel, uploadButton); + formPanelButtonLayout.setMargin(true); + formPanelButtonLayout.setSpacing(true); + formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); + uploadButton.setVisible(false); + } + else if(artifactList.getStatus().equals("notfound")){ + HorizontalLayout treePanelLayout = new HorizontalLayout(); + treePanelLayout.addComponent(notFound); + treePanelLayout.setMargin(true); + treePanel.setContent(treePanelLayout); + formPanelButtonLayout.addComponents(treePanel); + formPanelButtonLayout.setMargin(true); + } + } } } - if (tree == null) { - content.addComponent(notFound); + content.addComponent(formPanelButtonLayout); + }); + + tree.addCollapseListener(e -> { + uploadButton.setVisible(false); + }); + + tree.addExpandListener(e -> { + uploadButton.setVisible(true); + }); + + uploadButton.addClickListener(e -> { + if (tree.getValue() != null && !(tree.areChildrenAllowed((Object) tree.getValue()))) { + File file; + try { + URL url = new URL(tree.getValue().toString()); + file = new File(url.toString()); + InputStream input = url.openStream(); + Activator.instance().getBuffer(myUI.getSession().getSession()).put(file.getName(), input); + Notification notif = new Notification("Info", "Artefact from central maven upload sucess", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } catch (IOException | RefusedArtifactException ex) { + new Notification("Could not open or load file from url", ex.getMessage(), + Notification.Type.ERROR_MESSAGE).show(Page.getCurrent()); + } } else { - tree.addShortcutListener(new ShortcutListener("", KeyCode.ENTER, null) { - @Override - public void handleAction(Object sender, Object target) { - if (tree.getValue() != null && !(tree.areChildrenAllowed((Object) tree.getValue())) - && myUI.getWindows().isEmpty()) { - myUI.addWindow(new CheckUploadModal(tree.getValue().toString(), myUI.getSession())); - } - } - }); - content.addComponent(tree); + new Notification("No artefact selected", Notification.Type.WARNING_MESSAGE).show(Page.getCurrent()); } }); - - directIndexOption.addValueChangeListener(e ->{ - if(directIndexOption.getValue().equals("Direct")){ + + directIndexOption.addValueChangeListener(e -> { + if (directIndexOption.getValue().equals("Direct")) { rangeOption.setEnabled(false); group.setRequired(false); artifact.setRequired(false); - } - else{ + } else { rangeOption.setEnabled(true); group.setRequired(true); group.setRequiredError("The item can not be empty!"); @@ -152,11 +287,13 @@ public void handleAction(Object sender, Object target) { // Clear user form clearButton.addClickListener(e -> { + formPanelButtonLayout.removeAllComponents(); content.removeAllComponents(); group.clear(); artifact.clear(); version.clear(); packaging.select(TypePackaging.jar); + tree.removeAllItems(); content.addComponent(userForm); }); @@ -164,54 +301,50 @@ public void handleAction(Object sender, Object target) { addComponent(content); } - private static class CheckUploadModal extends Window { - public CheckUploadModal(String urlText, VaadinSession session) { - super("Upload " + urlText.substring(urlText.lastIndexOf('/') + 1) + " to buffer?"); - VerticalLayout content = new VerticalLayout(); - content.setWidth("500px"); - content.setHeight("100px"); - - HorizontalLayout buttonLayout = new HorizontalLayout(); - - Button uploadButton = new Button("Upload"); - uploadButton.setStyleName(ValoTheme.BUTTON_PRIMARY); - Button cancelButton = new Button("Cancel"); - - buttonLayout.addComponents(uploadButton, cancelButton); - - buttonLayout.setSpacing(true); - buttonLayout.setMargin(true); - - content.addComponent(buttonLayout); - content.setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER); - - center(); - setClosable(false); - setResizable(false); + private void addArtifactToTree(String url, String group, String artifact, String version, String packaging, String parent) { + String uniqueVersion = artifact + version; + + tree.addItem(artifact); + tree.setParent(artifact, parent); + tree.addItem(uniqueVersion); + tree.setItemCaption(uniqueVersion, version); + tree.setParent(uniqueVersion, artifact); - uploadButton.addClickListener(e -> { - File file; - try { - URL url = new URL(urlText); - file = new File(url.toString()); - InputStream input = url.openStream(); - Activator.instance().getBuffer(session.getSession()).put(file.getName(), input); - Notification notif = new Notification("Info", "Artefact from central maven upload sucess", - Notification.Type.ASSISTIVE_NOTIFICATION); - notif.setPosition(Position.TOP_RIGHT); - notif.show(Page.getCurrent()); - } catch (IOException | RefusedArtifactException ex) { - new Notification("Could not open or load file from url", ex.getMessage(), Notification.Type.ERROR_MESSAGE) - .show(Page.getCurrent()); - } - close(); - }); + // konečný artefact je komplet url link např. pro wget - UPRAVIT DLE + // POTŘEBY + String artifactText = url + group.replace('.', '/') + "/" + artifact + "/" + version + "/" + + artifact + "-" + version + "." + packaging; - cancelButton.addClickListener(e -> { - close(); - }); + tree.addItem(artifactText); + tree.setParent(artifactText, uniqueVersion); + tree.setItemCaption(artifactText, + artifact + "-" + version + "." + packaging); + tree.setChildrenAllowed(artifactText, false); + if (packaging.equals("jar") || packaging.equals("war")) { + tree.setItemIcon(artifactText, FontAwesome.GIFT); + } else if (packaging.equals("xml") || packaging.equals("pom")) { + tree.setItemIcon(artifactText, FontAwesome.CODE); + } else { + tree.setItemIcon(artifactText, FontAwesome.FILE); + } + } + + private void addArtefactToTreeGroup(ArtifactTree artifactTree, String parent) { + // konečný artefact je komplet url link např. pro wget - UPRAVIT DLE + // POTŘEBY + String artifactText = artifactTree.getArtefactId(); + String artifactUrl = artifactTree.getUrl(); - setContent(content); + tree.addItem(artifactUrl); + tree.setParent(artifactUrl, parent); + tree.setItemCaption(artifactUrl, artifactText); + tree.setChildrenAllowed(artifactUrl, false); + if (artifactTree.getPackaging().equals("jar") || artifactTree.getPackaging().equals("war")) { + tree.setItemIcon(artifactUrl, FontAwesome.GIFT); + } else if (artifactTree.getPackaging().equals("xml") || artifactTree.getPackaging().equals("pom")) { + tree.setItemIcon(artifactUrl, FontAwesome.CODE); + } else { + tree.setItemIcon(artifactUrl, FontAwesome.FILE); } } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CheckMavenIndexForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CheckMavenIndexForm.java index e6c30936..8f3fffbf 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CheckMavenIndexForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CheckMavenIndexForm.java @@ -7,7 +7,9 @@ import com.vaadin.ui.Label; import com.vaadin.ui.ProgressBar; import com.vaadin.ui.VerticalLayout; -import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.MavenIndex; + +import cz.zcu.kiv.crce.crce_external_repository.api.MavenIndex; +import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; @SuppressWarnings("serial") @@ -47,7 +49,7 @@ public HelperIndexingThread(VaadinSession session){ public void run() { try { MavenIndex check = new MavenIndex(); - result = check.checkIndex(session); + result = check.checkIndex((SettingsUrl)session.getAttribute("settingsUrl")); } catch (Exception e) { e.printStackTrace(); } finally { @@ -56,6 +58,7 @@ public void run() { myUI.access(() -> bar.setIndeterminate(false)); if (result != null) { myUI.access(() -> statusLabel.setValue(result)); + session.setAttribute("mavenIndex", true); } else{ myUI.access(() -> statusLabel.setValue("Error when creating index!")); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java index cf313771..c4494fd8 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java @@ -3,14 +3,12 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.Serializable; import java.nio.file.Files; import java.nio.file.StandardOpenOption; import java.util.EnumSet; -import com.vaadin.event.ShortcutListener; + +import com.vaadin.server.FontAwesome; import com.vaadin.server.Page; -import com.vaadin.server.VaadinSession; -import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.shared.Position; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.ui.Alignment; @@ -21,20 +19,21 @@ import com.vaadin.ui.Label; import com.vaadin.ui.NativeSelect; import com.vaadin.ui.Notification; +import com.vaadin.ui.Panel; import com.vaadin.ui.TextField; import com.vaadin.ui.Tree; import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; +import cz.zcu.kiv.crce.crce_external_repository.api.ArtifactTree; +import cz.zcu.kiv.crce.crce_external_repository.api.DefinedMaven; +import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; -import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.DefinedMaven; -import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.SettingsUrl; import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; import cz.zcu.kiv.crce.repository.RefusedArtifactException; -public class DefinedMavenForm extends FormLayout implements Serializable { +public class DefinedMavenForm extends FormLayout{ private static final long serialVersionUID = 4172878715304331198L; private transient DefinedMaven definedMaven; private TextField definedUrl = new TextField(); @@ -45,6 +44,9 @@ public class DefinedMavenForm extends FormLayout implements Serializable { private NativeSelect packaging = new NativeSelect("Packaging"); private Button searchButton = new Button("Search"); private Button clearButton = new Button("Clear"); + private Button uploadButton = new Button("Upload"); + private Button resolveButton = new Button("Resolve"); + private Panel treePanel = new Panel("Result list"); private Label notFound = new Label("No artifact found"); private Tree tree; @@ -53,9 +55,7 @@ public DefinedMavenForm() { addComponent(content); } - @SuppressWarnings("serial") public DefinedMavenForm(MyUI myUI) { - // settings url if (myUI.getSession().getAttribute("settingsUrl") == null) { SettingsUrl settings = new SettingsUrl(); definedUrl.setValue(settings.getExternalAetherUrl()); @@ -64,6 +64,9 @@ public DefinedMavenForm(MyUI myUI) { } VerticalLayout fieldLayout = new VerticalLayout(); + HorizontalLayout treePanelLayout = new HorizontalLayout(); + VerticalLayout treePanelButtonLayout = new VerticalLayout(); + HorizontalLayout buttonUploadResolveLayout = new HorizontalLayout(); HorizontalLayout treeLayout = new HorizontalLayout(); VerticalLayout formLayout = new VerticalLayout(); HorizontalLayout content = new HorizontalLayout(); @@ -78,22 +81,36 @@ public DefinedMavenForm(MyUI myUI) { searchButton.setStyleName(ValoTheme.BUTTON_PRIMARY); - HorizontalLayout buttons = new HorizontalLayout(searchButton, clearButton); - buttons.setSpacing(true); + HorizontalLayout buttonsSearchClearLayout = new HorizontalLayout(searchButton, clearButton); + buttonsSearchClearLayout.setSpacing(true); Button setUrl = new Button("Set"); CssLayout definedCss = new CssLayout(); definedCss.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); definedCss.addComponents(definedUrl, setUrl); - fieldLayout.addComponents(group, artifact, version, packaging, buttons); + fieldLayout.addComponents(group, artifact, version, packaging, buttonsSearchClearLayout); fieldLayout.setSpacing(true); fieldLayout.setMargin(new MarginInfo(false, true, false, false)); + + treeLayout.setMargin(true); + treePanel.setContent(treeLayout); + treePanel.setWidth("600px"); + treePanel.setHeight("283px"); + treePanel.setVisible(false); + buttonUploadResolveLayout.setVisible(false); + + buttonUploadResolveLayout.addComponents(resolveButton, uploadButton); + buttonUploadResolveLayout.setSpacing(true); + + treePanelButtonLayout.addComponents(treePanel, buttonUploadResolveLayout); + treePanelButtonLayout.setSpacing(true); + treePanelButtonLayout.setComponentAlignment(buttonUploadResolveLayout, Alignment.BOTTOM_CENTER); - treeLayout.addComponent(fieldLayout); - treeLayout.setSpacing(true); + treePanelLayout.addComponents(fieldLayout, treePanelButtonLayout); + treePanelLayout.setSpacing(true); - formLayout.addComponents(caption, definedCss, treeLayout); + formLayout.addComponents(caption, definedCss, treePanelLayout); formLayout.setSpacing(true); formLayout.setMargin(new MarginInfo(false, true)); @@ -126,10 +143,12 @@ public DefinedMavenForm(MyUI myUI) { if (treeLayout.getComponentIndex(tree) != -1) { treeLayout.removeComponent(tree); } + treePanel.setVisible(false); + buttonUploadResolveLayout.setVisible(false); }); // search artefact from defined repository - searchButton.addClickListener(e -> { + searchButton.addClickListener(e1 -> { SettingsUrl settings; if (myUI.getSession().getAttribute("settingsUrl") == null) { settings = new SettingsUrl(); @@ -144,75 +163,56 @@ public DefinedMavenForm(MyUI myUI) { treeLayout.removeComponent(tree); } - // předání hodnot - doplnit + // předání hodnot definedMaven = new DefinedMaven(settings); - tree = definedMaven.getTree(group.getValue(), artifact.getValue(), version.getValue(), + ArtifactTree definedArtefact = definedMaven.getArtifact(group.getValue(), artifact.getValue(), version.getValue(), packaging.getValue()); - if (tree == null) { + if(definedArtefact == null){ treeLayout.addComponent(notFound); - } else { - treeLayout.addComponent(tree); - tree.addShortcutListener(new ShortcutListener("", KeyCode.ENTER, null) { - @Override - public void handleAction(Object sender, Object target) { - if (tree.getValue() != null && !(tree.areChildrenAllowed((Object) tree.getValue())) - && myUI.getWindows().isEmpty()) { - myUI.addWindow( - new CheckUploadModal(tree.getValue().toString(), settings, myUI.getSession())); - } - } - }); } - }); - - content.setSpacing(true); - addComponent(content); - } - - @SuppressWarnings("serial") - private static class CheckUploadModal extends Window { - public CheckUploadModal(String artifactText, SettingsUrl settings, VaadinSession session) { - super("What to do next with " + artifactText.split(":")[1] + "-" + artifactText.split(":")[2] + "." - + artifactText.split(":")[3] + " ?"); - VerticalLayout content = new VerticalLayout(); - content.setWidth("500px"); - content.setHeight("100px"); - - HorizontalLayout buttonLayout = new HorizontalLayout(); - - Button uploadButton = new Button("Upload"); - uploadButton.setStyleName(ValoTheme.BUTTON_PRIMARY); - Button resolveButton = new Button("Resolve"); - Button cancelButton = new Button("Cancel"); - - buttonLayout.addComponents(uploadButton, resolveButton, cancelButton); - - buttonLayout.setSpacing(true); - buttonLayout.setMargin(true); - - content.addComponent(buttonLayout); - content.setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER); - - center(); - setClosable(false); - setResizable(false); + else { + tree = new Tree(); + String[] pom = definedArtefact.getGroupId().split("\\."); + tree.addItem(pom[0]); + for (int i = 1; i < pom.length; i++) { + tree.addItem(pom[i]); + tree.setParent(pom[i], pom[i - 1]); + } - resolveButton.addClickListener(e -> { - if (DefinedMaven.resolveArtefact(artifactText, settings)) { - Notification notif = new Notification("Info", "Artefact sucess resolved to Maven local repository.", - Notification.Type.ASSISTIVE_NOTIFICATION); - notif.setPosition(Position.TOP_RIGHT); - notif.show(Page.getCurrent()); + if (definedArtefact.getVersions().size() > 1) { + for (String s : definedArtefact.getVersions()) { + addArtefactToTree(definedArtefact.getGroupId(), definedArtefact.getArtefactId(), s, + definedArtefact.getPackaging(),pom[pom.length - 1]); + } } else { - new Notification("Problem with resolving artifact", Notification.Type.WARNING_MESSAGE) - .show(Page.getCurrent()); + addArtefactToTree(definedArtefact.getGroupId(), definedArtefact.getArtefactId(), definedArtefact.getVersions().get(0), + definedArtefact.getPackaging(),pom[pom.length - 1]); } - close(); - }); - - uploadButton.addClickListener(e -> { - // First check the artifact storage in the local repository - if (DefinedMaven.resolveArtefact(artifactText, settings)) { + + tree.addExpandListener(e2 ->{ + buttonUploadResolveLayout.setVisible(true); + }); + + tree.addCollapseListener(e3 -> { + buttonUploadResolveLayout.setVisible(false); + }); + + treeLayout.addComponent(tree); + } + treePanel.setVisible(true); + }); + + uploadButton.addClickListener(e -> { + SettingsUrl settings; + if (myUI.getSession().getAttribute("settingsUrl") == null) { + settings = new SettingsUrl(); + } else { + settings = (SettingsUrl) myUI.getSession().getAttribute("settingsUrl"); + } + // First check the artifact storage in the local repository + if(tree.getValue() != null && tree.getValue().toString().contains(":")) { + String artifactText = tree.getValue().toString(); + if (DefinedMaven.resolveArtifact(artifactText, settings)) { File file = new File(settings.getLocalAetherUrl() + "/" + artifactText.split(":")[0].replace('.', '/') + "/" + artifactText.split(":")[1] + "/" + artifactText.split(":")[2] + "/" + artifactText.split(":")[1] + "-" @@ -220,7 +220,7 @@ public CheckUploadModal(String artifactText, SettingsUrl settings, VaadinSession try { InputStream is = Files.newInputStream(file.toPath(), StandardOpenOption.READ); try { - Activator.instance().getBuffer(session.getSession()).put(file.getName(), is); + Activator.instance().getBuffer(myUI.getSession().getSession()).put(file.getName(), is); Notification notif = new Notification("Info", "Artifact to buffer upload sucess", Notification.Type.ASSISTIVE_NOTIFICATION); notif.setPosition(Position.TOP_RIGHT); @@ -236,14 +236,67 @@ public CheckUploadModal(String artifactText, SettingsUrl settings, VaadinSession new Notification("Problem with resolving artifact", Notification.Type.WARNING_MESSAGE) .show(Page.getCurrent()); } - close(); - }); + } + else { + new Notification("No artefact selected", Notification.Type.WARNING_MESSAGE) + .show(Page.getCurrent()); + } + }); + + resolveButton.addClickListener(e ->{ + SettingsUrl settings; + if (myUI.getSession().getAttribute("settingsUrl") == null) { + settings = new SettingsUrl(); + } else { + settings = (SettingsUrl) myUI.getSession().getAttribute("settingsUrl"); + } + // First check the artifact storage in the local repository + if(tree.getValue() != null && tree.getValue().toString().contains(":")) { + String artifactText = tree.getValue().toString(); + if (DefinedMaven.resolveArtifact(artifactText, settings)) { + Notification notif = new Notification("Info", "Artefact sucess resolved to Maven local repository.", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } else { + new Notification("Problem with resolving artifact", Notification.Type.WARNING_MESSAGE) + .show(Page.getCurrent()); + } + } + else { + new Notification("No artefact selected", Notification.Type.WARNING_MESSAGE) + .show(Page.getCurrent()); + } + }); + + content.setSpacing(true); + addComponent(content); + } + + private void addArtefactToTree(String group, String artifact, String version, String packaging, String parent) { + tree.addItem(artifact); + tree.setParent(artifact, parent); + tree.addItem(version); + tree.setParent(version, artifact); - cancelButton.addClickListener(e -> { - close(); - }); + // konečný artefact je komplet url link např. pro wget - UPRAVIT DLE + // POTŘEBY + /*String artifactText = settings.getExternalAetherUrl() + "/" + + groupText + "/" + idText + "/" + version + "." + packagingText;*/ + + String artifactText = group + ":" + artifact + ":" + version + ":" + packaging; - setContent(content); + tree.addItem(artifactText); + tree.setParent(artifactText, version.toString()); + tree.setItemCaption(artifactText, + artifact + "-" + version + "." + packaging); + tree.setChildrenAllowed(artifactText, false); + if (packaging.equals("jar") || packaging.equals("war")) { + tree.setItemIcon(artifactText, FontAwesome.GIFT); + } else if (packaging.equals("xml") || packaging.equals("pom")) { + tree.setItemIcon(artifactText, FontAwesome.CODE); + } else { + tree.setItemIcon(artifactText, FontAwesome.FILE); } } } \ No newline at end of file diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java index 5d3a0f79..baa26d59 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java @@ -10,10 +10,7 @@ import java.nio.file.StandardOpenOption; import java.nio.file.attribute.BasicFileAttributes; -import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.server.Page; -import com.vaadin.server.VaadinSession; -import com.vaadin.event.ShortcutListener; import com.vaadin.shared.Position; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.ui.Alignment; @@ -21,11 +18,11 @@ import com.vaadin.ui.FormLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; +import com.vaadin.ui.Panel; import com.vaadin.ui.Notification; import com.vaadin.ui.Tree; import com.vaadin.ui.themes.ValoTheme; import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.LocalMaven; @@ -36,7 +33,10 @@ public class LocalMavenForm extends FormLayout { private LocalMaven localMaven = new LocalMaven(); private Label caption = new Label("Local Maven repository"); - + private Panel formPanel = new Panel("Content"); + private Button uploadButton = new Button("Upload"); + private Button removeButton = new Button("Remove"); + public LocalMavenForm() { HorizontalLayout content = new HorizontalLayout(); addComponent(content); @@ -46,139 +46,90 @@ public LocalMavenForm(MyUI myUI) { VerticalLayout content = new VerticalLayout(); caption.addStyleName(ValoTheme.LABEL_BOLD); + VerticalLayout formLayout = new VerticalLayout(); + HorizontalLayout buttons = new HorizontalLayout(); + + removeButton.setStyleName(ValoTheme.BUTTON_DANGER); + + buttons.addComponents(uploadButton, removeButton); + buttons.setSpacing(true); + buttons.setVisible(false); + // Tree of Maven local repository Tree localMavenTree = localMaven.getTree(myUI.getSession()); content.setMargin(new MarginInfo(false, true)); if (localMavenTree == null) { content.addComponent(new Label("Local Maven repository not found")); } else { - content.addComponents(caption, localMavenTree); + HorizontalLayout treeLayout = new HorizontalLayout(); + treeLayout.addComponent(localMavenTree); + treeLayout.setMargin(true); + formPanel.setContent(treeLayout); + formPanel.setHeight("500px"); + formLayout.addComponents(caption, formPanel, buttons); + formLayout.setSpacing(true); + formLayout.setComponentAlignment(buttons, Alignment.BOTTOM_CENTER); + content.addComponents(formLayout); content.setSpacing(true); - - localMavenTree.addShortcutListener(new ShortcutListener("", KeyCode.ENTER, null) { - @Override - public void handleAction(Object sender, Object target) { - if (localMavenTree.getValue() != null && myUI.getWindows().isEmpty()) { - if (localMavenTree.areChildrenAllowed((Object) localMavenTree.getValue())) { - myUI.addWindow(new RemovePathModal(new File(localMavenTree.getValue().toString()), myUI)); - } else { - myUI.addWindow(new CheckUploadModal(new File(localMavenTree.getValue().toString()), - myUI.getSession())); - } - } - } + + localMavenTree.addItemClickListener(e -> { + buttons.setVisible(true); }); - } - addComponent(content); - } - - private static class CheckUploadModal extends Window { - public CheckUploadModal(File file, VaadinSession session) { - super("Upload " + file.getName() + " to buffer?"); - VerticalLayout content = new VerticalLayout(); - content.setWidth("400px"); - content.setHeight("100px"); - - HorizontalLayout buttonLayout = new HorizontalLayout(); - - Button acceptButton = new Button("OK"); - acceptButton.setStyleName(ValoTheme.BUTTON_PRIMARY); - Button cancelButton = new Button("Cancel"); - - buttonLayout.addComponents(acceptButton, cancelButton); - - buttonLayout.setSpacing(true); - buttonLayout.setMargin(true); - - content.addComponent(buttonLayout); - content.setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER); - - center(); - setClosable(false); - setResizable(false); - - acceptButton.addClickListener(e -> { - try { - InputStream is = Files.newInputStream(file.toPath(), StandardOpenOption.READ); + + removeButton.addClickListener(e -> { + if (localMavenTree.getValue() != null) { + File file = new File(localMavenTree.getValue().toString()); + Path directory = file.toPath(); try { - Activator.instance().getBuffer(session.getSession()).put(file.getName(), is); - Notification notif = new Notification("Info", "Artifact to buffer upload sucess", - Notification.Type.ASSISTIVE_NOTIFICATION); - notif.setPosition(Position.TOP_RIGHT); - notif.show(Page.getCurrent()); + Files.walkFileTree(directory, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException ex) { + new Notification("Could not remove path!", ex.getMessage(), Notification.Type.ERROR_MESSAGE) + .show(Page.getCurrent()); } finally { - is.close(); - close(); + myUI.setContentBodyLocalMaven(); } - } catch (IOException | RefusedArtifactException ex) { - new Notification("Could not open file", ex.getMessage(), Notification.Type.ERROR_MESSAGE) - .show(Page.getCurrent()); } }); - - cancelButton.addClickListener(e -> { - close(); - }); - - setContent(content); - } - } - - private static class RemovePathModal extends Window { - public RemovePathModal(File file, MyUI myUI) { - super("Remove path " + file.getName() + "?"); - VerticalLayout content = new VerticalLayout(); - content.setWidth("400px"); - content.setHeight("100px"); - - HorizontalLayout buttonLayout = new HorizontalLayout(); - - Button removeButton = new Button("Remove"); - removeButton.setStyleName(ValoTheme.BUTTON_DANGER); - Button cancelButton = new Button("Cancel"); - - buttonLayout.addComponents(removeButton, cancelButton); - - buttonLayout.setSpacing(true); - buttonLayout.setMargin(true); - - content.addComponent(buttonLayout); - content.setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER); - - center(); - setClosable(false); - setResizable(false); - - removeButton.addClickListener(e -> { - Path directory = file.toPath(); - try { - Files.walkFileTree(directory, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - Files.delete(dir); - return FileVisitResult.CONTINUE; + + uploadButton.addClickListener(e -> { + if (localMavenTree.getValue() != null) { + if (!localMavenTree.areChildrenAllowed((Object) localMavenTree.getValue())) { + try { + File file = new File(localMavenTree.getValue().toString()); + InputStream is = Files.newInputStream(file.toPath(), StandardOpenOption.READ); + try { + Activator.instance().getBuffer(myUI.getSession().getSession()).put(file.getName(), is); + Notification notif = new Notification("Info", "Artifact to buffer upload sucess", + Notification.Type.ASSISTIVE_NOTIFICATION); + notif.setPosition(Position.TOP_RIGHT); + notif.show(Page.getCurrent()); + } finally { + is.close(); + } + } catch (IOException | RefusedArtifactException ex) { + new Notification("Could not open file", ex.getMessage(), Notification.Type.ERROR_MESSAGE) + .show(Page.getCurrent()); } - }); - } catch (IOException ex) { - new Notification("Could not remove path!", ex.getMessage(), Notification.Type.ERROR_MESSAGE) - .show(Page.getCurrent()); - } finally { - close(); - myUI.setContentBodyLocalMaven(); + + } else { + new Notification("No artifact is selected for upload!", Notification.Type.WARNING_MESSAGE) + .show(Page.getCurrent()); + } } }); - - cancelButton.addClickListener(e -> { - close(); - }); - - setContent(content); } + addComponent(content); } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java deleted file mode 100644 index 997ca7ec..00000000 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/CentralMaven.java +++ /dev/null @@ -1,201 +0,0 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes; - -import java.io.IOException; -import java.net.URL; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; -import java.util.List; - -import org.apache.maven.index.ArtifactInfo; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import com.vaadin.server.FontAwesome; -import com.vaadin.server.Page; -import com.vaadin.server.VaadinSession; -import com.vaadin.ui.Notification; -import com.vaadin.ui.Tree; - -public class CentralMaven { - private String centralMavenUrl; - private boolean enableGroupSearch; - private Tree resultSearchTree = new Tree("Result Search"); - private VaadinSession session; - - public CentralMaven(VaadinSession session) { - this.session = session; - } - - public Tree getTree(String group, String artifact, String version, Object packaging, Object directIndex, - String range) { - if (session.getAttribute("settingsUrl") == null) { - SettingsUrl settings = new SettingsUrl(); - centralMavenUrl = settings.getCentralMavenUrl(); - enableGroupSearch = settings.isEnableGroupSearch(); - } else { - centralMavenUrl = ((SettingsUrl) session.getAttribute("settingsUrl")).getCentralMavenUrl(); - enableGroupSearch = ((SettingsUrl) session.getAttribute("settingsUrl")).isEnableGroupSearch(); - } - // reset tree - resultSearchTree.removeAllItems(); - // direct search - if (directIndex.equals("Direct")) { - if (!artifact.isEmpty() || !version.isEmpty()) { - directSearch(group, artifact, version, packaging.toString()); - } else if (enableGroupSearch && !group.isEmpty()) { - onlyGroupSearch(group); - } - if (resultSearchTree.size() == 0) { - return null; - } else { - return resultSearchTree; - } - } - // index search - else { - if (session.getAttribute("mavenIndex") != null) { - indexSearch(group, artifact, version, packaging.toString(), range); - if (resultSearchTree.size() == 0) { - return null; - } else { - return resultSearchTree; - } - } else { - Notification notif = new Notification( - "The central maven repository index is not created. Check its creation in the settings menu", - Notification.Type.WARNING_MESSAGE); - notif.setDelayMsec(5000); - notif.show(Page.getCurrent()); - return null; - } - } - } - - private void directSearch(String group, String artifact, String version, String packaging) { - URL website; - try { - website = new URL(centralMavenUrl + group.replace('.', '/') + "/" + artifact + "/" + version + "/" - + artifact + "-" + version + "." + packaging); - ReadableByteChannel rbc = Channels.newChannel(website.openStream()); - if (rbc.isOpen()) { - String[] pom = group.split("\\."); - // adding group - resultSearchTree.addItem(pom[0]); - for (int i = 1; i < pom.length; i++) { - resultSearchTree.addItem(pom[i]); - resultSearchTree.setParent(pom[i], pom[i - 1]); - } - resultSearchTree.addItem(artifact); - resultSearchTree.setParent(artifact, pom[pom.length - 1]); - resultSearchTree.addItem(version); - resultSearchTree.setParent(version, artifact); - // end artifact - resultSearchTree.addItem(website.toString()); - resultSearchTree.setParent(website.toString(), version); - resultSearchTree.setItemCaption(website.toString(), artifact + "-" + version + "." + packaging); - resultSearchTree.setChildrenAllowed(website.toString(), false); - if (packaging.equals("jar") || packaging.equals("war")) { - resultSearchTree.setItemIcon(website.toString(), FontAwesome.GIFT); - } else if (packaging.equals("xml") || packaging.equals("pom")) { - resultSearchTree.setItemIcon(website.toString(), FontAwesome.CODE); - } else { - resultSearchTree.setItemIcon(website.toString(), FontAwesome.FILE); - } - rbc.close(); - } - } catch (IOException e) { - resultSearchTree.clear(); - } - } - - private void onlyGroupSearch(String group) { - try { - list(new URL(centralMavenUrl + group.replace('.', '/') + "/")); - } catch (IOException e) { - // resultSearchTree.addItem(centralMavenUrl + group.replace('.', - // '/')); - resultSearchTree.clear(); - } - } - - private void list(URL path) throws IOException { - Document doc = Jsoup.connect(path.toString()).get(); - for (Element file : doc.select("a").not("[href=../]")) { - if (file.text().endsWith("/")) { - resultSearchTree.addItem(path.toString() + file.text()); - resultSearchTree.setItemCaption(path.toString() + file.text(), - file.text().substring(0, (file.text().length() - 1))); - resultSearchTree.setParent(path.toString() + file.text(), path.toString()); - list(new URL(path.toString() + file.text())); - } else { - resultSearchTree.addItem(path.toString() + file.text()); - resultSearchTree.setItemCaption(path.toString() + file.text(), file.text()); - resultSearchTree.setParent(path.toString() + file.text(), path.toString()); - resultSearchTree.setChildrenAllowed(path.toString() + file.text(), false); - if (file.text().endsWith(".jar") || file.text().endsWith(".war")) { - resultSearchTree.setItemIcon(path.toString() + file.text(), FontAwesome.GIFT); - } else if (file.text().endsWith(".xml") || file.text().endsWith(".pom")) { - resultSearchTree.setItemIcon(path.toString() + file.text(), FontAwesome.CODE); - } else { - resultSearchTree.setItemIcon(path.toString() + file.text(), FontAwesome.FILE); - } - } - } - } - - private void indexSearch(String group, String artifact, String version, String packaging, String range){ - MavenIndex mavenIndex = null; - try { - mavenIndex = new MavenIndex(); - List artifactInfoList = mavenIndex.searchArtefact(session, group, artifact, version, - packaging, range); - for (ArtifactInfo ai : artifactInfoList) { - URL website; - try { - website = new URL(centralMavenUrl + ai.groupId.replace('.', '/') + "/" + ai.artifactId + "/" + ai.version + "/" - + ai.artifactId + "-" + ai.version + "." + ai.packaging); - ReadableByteChannel rbc = Channels.newChannel(website.openStream()); - if (rbc.isOpen()) { - String[] pom = ai.groupId.split("\\."); - if(resultSearchTree.getItem(pom[0]) == null){ - resultSearchTree.addItem(pom[0]); - } - // adding group - for (int i = 1; i < pom.length; i++) { - if(resultSearchTree.getItem(pom[i]) == null){ - resultSearchTree.addItem(pom[i]); - resultSearchTree.setParent(pom[i], pom[i - 1]); - } - } - // adding artefact and version - resultSearchTree.addItem(ai.artifactId); - resultSearchTree.setParent(ai.artifactId, pom[pom.length - 1]); - resultSearchTree.addItem(ai.version + "-" + ai.artifactId); - resultSearchTree.setItemCaption(ai.version + "-" + ai.artifactId, ai.version); - resultSearchTree.setParent(ai.version + "-" + ai.artifactId , ai.artifactId); - resultSearchTree.addItem(website.toString()); - resultSearchTree.setParent(website.toString(), ai.version + "-" + ai.artifactId); - resultSearchTree.setItemCaption(website.toString(), ai.artifactId + "-" + ai.version + "." + ai.packaging); - resultSearchTree.setChildrenAllowed(website.toString(), false); - if (packaging.equals("jar") || packaging.equals("war")) { - resultSearchTree.setItemIcon(website.toString(), FontAwesome.GIFT); - } else if (packaging.equals("xml") || packaging.equals("pom")) { - resultSearchTree.setItemIcon(website.toString(), FontAwesome.CODE); - } else { - resultSearchTree.setItemIcon(website.toString(), FontAwesome.FILE); - } - rbc.close(); - } - } catch (IOException e) { - resultSearchTree.clear(); - } - } - } - catch (Exception e) { - e.printStackTrace(); - Notification notif = new Notification("Error retrieving artifact from maven index context!", - Notification.Type.ERROR_MESSAGE); - notif.show(Page.getCurrent()); - } - } -} diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/LocalMaven.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/LocalMaven.java index 629d323d..90ab17e5 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/LocalMaven.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/LocalMaven.java @@ -7,6 +7,8 @@ import com.vaadin.server.VaadinSession; import com.vaadin.ui.Tree; +import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; + @SuppressWarnings("serial") public class LocalMaven implements Serializable{ private Tree localMavenTree = new Tree(); diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java index 861ffc26..549426ef 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java @@ -75,6 +75,8 @@ public List getAllResourceBeanFromBuffer(WrappedSession session){ return resources; } + // Dořešit!!! V modulu crce-repository-impl ve třídě BufferImpl v metodě isInBuffer (na konci třídy) je kontrola na začátek řetězce + // .getPath().startsWith(baseDir.getAbsolutePath())- proč? Pokud se toto zaremuje, resource LZE z Bufferu odebrat public boolean removeResourceFromBuffer(WrappedSession wSession, Resource resource){ boolean result; try { diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LoginForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LoginForm.java index 175750cd..a1ca1586 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LoginForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LoginForm.java @@ -2,6 +2,7 @@ import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.FormLayout; @@ -19,6 +20,7 @@ public class LoginForm extends FormLayout{ private TextField login = new TextField("Name"); private PasswordField password = new PasswordField("Password"); private Button loginButton = new Button("Log in"); + private Button guestButton = new Button("Guest"); private Label error = new Label(); private HorizontalLayout loginFormLayout = new HorizontalLayout(); private HorizontalLayout submitErrorLayout = new HorizontalLayout(); @@ -36,7 +38,7 @@ public LoginForm(MyUI myUI) { loginFormLayout.addComponents(login, password); loginFormLayout.setSpacing(true); - submitErrorLayout.addComponents(loginButton, error); + submitErrorLayout.addComponents(loginButton, guestButton, error); submitErrorLayout.setSpacing(true); panelLayout.addComponents(loginFormLayout, submitErrorLayout); @@ -53,15 +55,21 @@ public LoginForm(MyUI myUI) { // kontrola vstupu např. volání služby apod. // v případě neúspěchu doplnění error hlášky např: - /*submitErrorLayout.removeComponent(error); + submitErrorLayout.removeComponent(error); error = new Label("

Incorrect login

", ContentMode.HTML); - submitErrorLayout.addComponent(error);*/ + submitErrorLayout.addComponent(error); // v případě úspěchu: - myUI.getSession().setAttribute("singed", login.getValue()); + /*myUI.getSession().setAttribute("singed", login.getValue()); + myUI.loginExistSession();*/ + }); + + guestButton.addClickListener(e -> { + myUI.getSession().setAttribute("singed", "guest"); myUI.loginExistSession(); }); + addComponent(content); } } diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java index ad4d161a..e43384dd 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java @@ -24,6 +24,7 @@ import cz.zcu.kiv.crce.crce_webui_vaadin.repository.StoreForm; import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; + /** * This UI is the application entry point. A UI may either represent a browser window * (or tab) or some part of a html page where a Vaadin application is embedded. diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java index 12ce9e1d..1764bb61 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java +++ b/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java @@ -14,7 +14,9 @@ import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; -import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.SettingsUrl; +import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; + +//import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.SettingsUrl; @SuppressWarnings("serial") public class SettingsForm extends FormLayout { diff --git a/modules/crce-webui/.classpath b/modules/crce-webui/.classpath index 23e05000..f3932ed9 100644 --- a/modules/crce-webui/.classpath +++ b/modules/crce-webui/.classpath @@ -17,7 +17,7 @@
- + diff --git a/modules/crce-webui/.project b/modules/crce-webui/.project index fbed2b06..42c6bade 100644 --- a/modules/crce-webui/.project +++ b/modules/crce-webui/.project @@ -25,6 +25,11 @@ + + org.fusesource.ide.project.RiderProjectBuilder + + + org.eclipse.m2e.core.maven2Builder @@ -32,6 +37,7 @@ + org.fusesource.ide.project.RiderProjectNature org.eclipse.pde.PluginNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature diff --git a/modules/pom.xml b/modules/pom.xml index 5918364e..2a4caec0 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -58,7 +58,6 @@ pom - crce-metadata-osgi-bundle @@ -86,6 +85,7 @@ crce-webui-vaadin provision + crce-external-repository From 5377917352d662f7d6c5189915c5bf910a79c886 Mon Sep 17 00:00:00 2001 From: rpesek Date: Mon, 25 Jun 2018 12:33:24 +0200 Subject: [PATCH 12/85] CRCE from branch dev preparation for implementation in JACC --- README.md | 58 + build/compiled/pom.xml | 2 - build/pom.xml | 1314 +-- core/crce-core/pom.xml | 15 +- core/crce-metadata-api/.classpath | 1 + core/crce-metadata-api/.project | 27 +- core/crce-metadata-api/pom.xml | 1 - .../kiv/crce/metadata/MetadataFactory.java | 3 + .../metadata/namespace/NsCrceIdentity.java | 1 + .../crce/metadata/namespace/NsCrceView.java | 26 + core/crce-metadata-dao-api/.classpath | 6 +- core/crce-metadata-dao-api/.project | 12 +- core/crce-metadata-dao-api/pom.xml | 2 +- .../{ResourceDAO.java => MetadataDao.java} | 41 +- .../kiv/crce/metadata/dao/RepositoryDAO.java | 43 - .../metadata/dao/filter/CapabilityFilter.java | 20 +- .../crce/metadata/dao/filter/Operator.java | 2 + ...urceDAOFilter.java => ResourceFilter.java} | 7 +- ...ourceDAOImpl.java => MetadataDaoImpl.java} | 157 +- .../dao/internal/RepositoryDAOImpl.java | 153 - .../dao/internal/mapper/ResolvingMapper.java | 4 +- .../internal/mapper/SqlFilterProvider.java | 4 +- .../dao/internal/mapper/ResourceMapper.xml | 12 + .../mapper/SqlFilterProviderTest.java | 6 +- .../crce-metadata-dao-mongodb}/.classpath | 2 +- .../.project | 14 +- core/crce-metadata-dao-mongodb/osgi.bnd | 6 + core/crce-metadata-dao-mongodb/pom.xml | 139 + .../metadata/dao/mongodb/BaseMongoDao.java | 100 + .../crce/metadata/dao/mongodb}/DbContext.java | 2 +- .../dao/mongodb/internal/Activator.java | 39 + .../mongodb/internal/MetaDataDaoMongo.java | 208 + .../dao/mongodb/internal/db/DbAttribute.java | 45 + .../dao/mongodb/internal/db/DbCapability.java | 123 + .../dao/mongodb/internal/db/DbDirective.java | 32 + .../dao/mongodb/internal/db/DbProperty.java | 79 + .../dao/mongodb/internal/db/DbRepository.java | 55 + .../mongodb/internal/db/DbRequirement.java | 99 + .../dao/mongodb/internal/db/DbResource.java | 99 + .../mongodb/internal/mapper/QueryBuilder.java | 190 + .../mapper/ResourceMetadataMapper.java | 334 + core/crce-metadata-impl/.classpath | 1 + core/crce-metadata-impl/.project | 27 +- core/crce-metadata-impl/pom.xml | 2 +- .../internal/MetadataFactoryImpl.java | 79 +- core/crce-metadata-indexer-api/.project | 2 +- core/crce-metadata-indexer-impl/.project | 2 +- core/crce-metadata-json-api/.project | 2 +- core/crce-metadata-json-api/pom.xml | 2 +- core/crce-metadata-json-impl/.project | 2 +- core/crce-metadata-service-api/.classpath | 1 + core/crce-metadata-service-api/.project | 27 +- .../metadata/service/MetadataService.java | 14 + core/crce-metadata-service-impl/.classpath | 1 + core/crce-metadata-service-impl/.project | 27 +- core/crce-metadata-service-impl/pom.xml | 2 +- .../service/internal/MetadataServiceImpl.java | 9 +- core/crce-plugin-api/.classpath | 1 + core/crce-plugin-api/.project | 27 +- core/crce-plugin-api/pom.xml | 2 +- ...bstractOsgiFunctionProviderRepository.java | 75 + .../zcu/kiv/crce/plugin/FunctionProvider.java | 37 + .../plugin/FunctionProviderRepository.java | 32 + core/crce-repository-api/.classpath | 6 +- core/crce-repository-api/.project | 12 +- .../cz/zcu/kiv/crce/repository/Store.java | 26 +- core/crce-repository-impl/.classpath | 6 +- core/crce-repository-impl/.project | 12 +- .../filebased/internal/Activator.java | 6 +- .../filebased/internal/BufferImpl.java | 44 +- .../internal/FilebasedStoreImpl.java | 59 +- .../internal/SessionRegisterImpl.java | 6 +- core/crce-resolver-api/.classpath | 6 +- core/crce-resolver-api/.project | 12 +- core/crce-resolver-api/pom.xml | 6 + .../cz/zcu/kiv/crce/resolver/Operator.java | 11 + .../zcu/kiv/crce/resolver/ResourceLoader.java | 22 +- .../crce/resolver/optimizer/CostFunction.java | 32 + .../optimizer/CostFunctionFactory.java | 65 + .../optimizer/CostFunctionRepository.java | 13 + .../resolver/optimizer/NsResultOptimizer.java | 23 + .../resolver/optimizer/OptimizationMode.java | 23 + .../resolver/optimizer/ResultOptimizer.java | 36 + .../optimizer/ResultOptimizerRepository.java | 15 + core/crce-resolver-impl/.classpath | 6 +- core/crce-resolver-impl/.project | 12 +- core/crce-resolver-impl/pom.xml | 14 +- .../resolver/internal/ResourceLoaderImpl.java | 199 +- .../optimizer/OsgiCostFunctionRepository.java | 27 + .../OsgiResultOptimizerRepository.java | 27 + core/pom.xml | 2 +- modules/crce-compatibility-api/.project | 10 +- modules/crce-compatibility-dao-api/.project | 2 +- .../crce-compatibility-dao-mongodb/.project | 6 +- .../compatibility/dao/internal/Activator.java | 18 +- .../CompatibilityDaoMongoFactory.java | 1 + .../internal/CompatibilityDaoMongoImpl.java | 73 +- modules/crce-concurrency/.project | 2 +- modules/crce-concurrency/pom.xml | 1 + .../crce/concurrency/model/ChainableTask.java | 32 + .../META-INF/MANIFEST.MF | 89 +- modules/crce-external-repository/pom.xml | 12 +- modules/crce-handler-metrics/.project | 2 +- modules/crce-handler-metrics/pom.xml | 3 +- .../handler/metrics/internal/Activator.java | 18 +- .../internal/MetricsIndexerActionHandler.java | 24 +- .../metrics/internal/MetricsIndexerTask.java | 46 +- modules/crce-integration-tests/.project | 4 +- modules/crce-integration-tests/pom.xml | 2 +- modules/crce-metadata-osgi-bundle/.project | 10 +- .../crce-optimizer-functions}/.classpath | 10 +- .../.project | 24 +- modules/crce-optimizer-functions/osgi.bnd | 12 + modules/crce-optimizer-functions/pom.xml | 76 + .../internal/cost/EqualCostFunction.java | 61 + .../internal/cost/FileSizeCostFunction.java | 72 + .../internal/result/IlpLPSolveOptimizer.java | 262 + .../result/IlpLPSolveTransitiveOptimizer.java | 161 + .../repository/maven/internal/Activator.java | 6 +- .../maven/internal/MavenStoreImpl.java | 47 +- modules/crce-rest-v2/.classpath | 6 +- modules/crce-rest-v2/.project | 6 +- .../kiv/crce/rest/v2/internal/Activator.java | 14 + .../kiv/crce/rest/v2/internal/CORSFilter.java | 39 + .../kiv/crce/rest/v2/internal/Headers.java | 17 + .../rest/v2/internal/ws/CostFunctionRes.java | 18 + .../crce/rest/v2/internal/ws/MetadataRes.java | 10 + .../rest/v2/internal/ws/OptimizerRes.java | 18 + .../ws/jersey/CostFunctionResJersey.java | 50 + .../internal/ws/jersey/MetadataResJersey.java | 51 +- .../ws/jersey/OptimizerResJersey.java | 50 + .../internal/ws/jersey/ResourceResJersey.java | 14 +- .../src/main/webapp/WEB-INF/web.xml | 10 +- .../rest/internal/xml/MetadataResource.java | 2 +- modules/crce-target/pom.xml | 13 + modules/crce-vo/.project | 12 +- modules/crce-vo/pom.xml | 11 +- .../zcu/kiv/crce/vo/internal/Activator.java | 15 +- .../dozer/convertor/RequirementConvertor.java | 99 + .../internal/service/MappingServiceDozer.java | 74 + .../crce/vo/model/metadata/DirectiveVO.java | 51 + .../model/metadata/GenericRequirementVO.java | 26 + .../vo/model/metadata/RequirementListVO.java | 49 + .../optimizer/CostFunctionDescriptorVO.java | 53 + .../vo/model/optimizer/ResultOptimizerVO.java | 53 + .../kiv/crce/vo/service/MappingService.java | 28 + .../crce-vo/src/main/resources/mappings.xml | 15 + .../DetailedResourceConverterTest.java | 5 +- .../convertor/RequirementConvertorTest.java | 251 + modules/crce-webservices-indexer/.project | 2 +- modules/crce-webui-vaadin/pom.xml | 2 +- .../crce_webui_vaadin/internal/Activator.java | 12 +- modules/crce-webui/osgi.bnd | 40 - modules/crce-webui/pom.xml | 182 - .../kiv/crce/webui/internal/Activator.java | 177 - .../kiv/crce/webui/internal/CheckServlet.java | 80 - .../crce/webui/internal/DownloadServlet.java | 132 - .../kiv/crce/webui/internal/EditServlet.java | 1023 -- .../zcu/kiv/crce/webui/internal/Helper.java | 26 - .../crce/webui/internal/ResourceServlet.java | 389 - .../crce/webui/internal/RuntimeServlet.java | 111 - .../crce/webui/internal/SessionListener.java | 25 - .../crce/webui/internal/UploadServlet.java | 213 - .../kiv/crce/webui/internal/VersionInfo.java | 67 - .../crce/webui/internal/bean/Category.java | 65 - .../crce/webui/internal/custom/Plugin.java | 47 - .../internal/custom/RequirementAdapter.java | 85 - .../webui/internal/custom/RequirementExt.java | 21 - .../internal/custom/RequirementsWrap.java | 42 - .../internal/custom/ResourceAdapter.java | 341 - .../webui/internal/custom/ResourceExt.java | 45 - .../webui/internal/custom/ResourceWrap.java | 482 - .../CompatibilityAvailabilityFilter.java | 39 - .../webui/internal/legacy/Capability.java | 13 - .../webui/internal/legacy/NewProperty.java | 13 - .../crce/webui/internal/legacy/Property.java | 36 - .../internal/legacy/PropertyProvider.java | 41 - .../webui/internal/legacy/Requirement.java | 36 - .../crce/webui/internal/legacy/Resource.java | 122 - .../kiv/crce/webui/internal/legacy/Type.java | 79 - .../src/main/webapp/META-INF/MANIFEST.MF | 3 - .../src/main/webapp/WEB-INF/web.xml | 89 - modules/crce-webui/src/main/webapp/crce.png | Bin 1334 -> 0 bytes .../crce-webui/src/main/webapp/css/styl.css | 612 -- .../src/main/webapp/graphic/add.png | Bin 733 -> 0 bytes .../src/main/webapp/graphic/check.png | Bin 1388 -> 0 bytes .../src/main/webapp/graphic/commit.png | Bin 891 -> 0 bytes .../src/main/webapp/graphic/crce.png | Bin 1334 -> 0 bytes .../src/main/webapp/graphic/del.png | Bin 715 -> 0 bytes .../src/main/webapp/graphic/edit.png | Bin 450 -> 0 bytes .../src/main/webapp/graphic/heading-bg.png | Bin 191 -> 0 bytes .../src/main/webapp/graphic/hlavicka_bg.png | Bin 10258 -> 0 bytes .../src/main/webapp/graphic/hlavicka_loga.png | Bin 22199 -> 0 bytes .../src/main/webapp/graphic/logo.png | Bin 18213 -> 0 bytes .../src/main/webapp/graphic/menu_bg.png | Bin 215 -> 0 bytes .../src/main/webapp/graphic/save.png | Bin 870 -> 0 bytes .../src/main/webapp/graphic/zoom.png | Bin 692 -> 0 bytes modules/crce-webui/src/main/webapp/index.jsp | 145 - .../src/main/webapp/js/jquery-1.5.1.js | 8316 ----------------- .../src/main/webapp/js/plus_minus_form.js | 49 - .../crce-webui/src/main/webapp/js/slide.js | 19 - .../crce-webui/src/main/webapp/jsp/buffer.jsp | 168 - .../src/main/webapp/jsp/compatibility.jsp | 69 - .../webapp/jsp/forms/capabilitiesForm.jsp | 47 - .../main/webapp/jsp/forms/capabilityForm.jsp | 31 - .../main/webapp/jsp/forms/categoriesForm.jsp | 25 - .../main/webapp/jsp/forms/categoryForm.jsp | 31 - .../src/main/webapp/jsp/forms/pluginForm.jsp | 35 - .../main/webapp/jsp/forms/propertiesForm.jsp | 58 - .../main/webapp/jsp/forms/propertyForm.jsp | 49 - .../main/webapp/jsp/forms/requirementForm.jsp | 56 - .../webapp/jsp/forms/requirementsForm.jsp | 40 - .../src/main/webapp/jsp/forms/testForm.jsp | 66 - .../src/main/webapp/jsp/include/footer.jsp | 11 - .../src/main/webapp/jsp/include/header.jsp | 98 - .../src/main/webapp/jsp/plugins.jsp | 49 - .../crce-webui/src/main/webapp/jsp/store.jsp | 178 - .../crce-webui/src/main/webapp/jsp/tags.jsp | 146 - modules/crce-webui/src/main/webapp/test.jsp | 142 - .../webui/internal/ResourceServletTest.java | 40 - modules/pom.xml | 14 +- modules/pom/pom.xml | 2 +- modules/provision/pom.xml | 299 +- pom.xml | 2 +- pom/pom.xml | 4 +- third-party/httpclient/pom.xml | 2 +- third-party/httpcore/pom.xml | 2 +- third-party/jna-platform/osgi.bnd | 9 + third-party/jna-platform/pom.xml | 37 + third-party/lpsolve/osgi.bnd | 21 + third-party/lpsolve/pom.xml | 45 + .../src/main/java/lpsolve/AbortListener.java | 44 + .../src/main/java/lpsolve/BbListener.java | 46 + .../src/main/java/lpsolve/LogListener.java | 44 + .../src/main/java/lpsolve/LpSolve.java | 1706 ++++ .../main/java/lpsolve/LpSolveException.java | 44 + .../src/main/java/lpsolve/MsgListener.java | 46 + .../src/main/java/lpsolve/VersionInfo.java | 73 + .../resources/libs/linux/x64/liblpsolve55j.so | Bin 0 -> 127393 bytes .../resources/libs/win/x64/lpsolve55j.dll | Bin 0 -> 130048 bytes .../resources/libs/win/x86/lpsolve55j.dll | Bin 0 -> 102400 bytes .../plexus-component-annotations/pom.xml | 2 +- third-party/plexus-interpolation/pom.xml | 2 +- third-party/plexus-utils/pom.xml | 2 +- 244 files changed, 7709 insertions(+), 16028 deletions(-) create mode 100644 core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/namespace/NsCrceView.java rename core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/{ResourceDAO.java => MetadataDao.java} (54%) delete mode 100644 core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/RepositoryDAO.java rename core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/{ResourceDAOFilter.java => ResourceFilter.java} (88%) rename core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/{ResourceDAOImpl.java => MetadataDaoImpl.java} (81%) delete mode 100644 core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/RepositoryDAOImpl.java rename {modules/crce-webui => core/crce-metadata-dao-mongodb}/.classpath (92%) rename core/{crce-metadata-dao-impl => crce-metadata-dao-mongodb}/.project (97%) create mode 100644 core/crce-metadata-dao-mongodb/osgi.bnd create mode 100644 core/crce-metadata-dao-mongodb/pom.xml create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/BaseMongoDao.java rename {modules/crce-compatibility-dao-mongodb/src/main/java/cz/zcu/kiv/crce/compatibility/dao/internal => core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb}/DbContext.java (95%) create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/internal/Activator.java create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/internal/MetaDataDaoMongo.java create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/internal/db/DbAttribute.java create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/internal/db/DbCapability.java create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/internal/db/DbDirective.java create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/internal/db/DbProperty.java create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/internal/db/DbRepository.java create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/internal/db/DbRequirement.java create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/internal/db/DbResource.java create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/internal/mapper/QueryBuilder.java create mode 100644 core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/internal/mapper/ResourceMetadataMapper.java create mode 100644 core/crce-plugin-api/src/main/java/cz/zcu/kiv/crce/plugin/AbstractOsgiFunctionProviderRepository.java create mode 100644 core/crce-plugin-api/src/main/java/cz/zcu/kiv/crce/plugin/FunctionProvider.java create mode 100644 core/crce-plugin-api/src/main/java/cz/zcu/kiv/crce/plugin/FunctionProviderRepository.java create mode 100644 core/crce-resolver-api/src/main/java/cz/zcu/kiv/crce/resolver/Operator.java create mode 100644 core/crce-resolver-api/src/main/java/cz/zcu/kiv/crce/resolver/optimizer/CostFunction.java create mode 100644 core/crce-resolver-api/src/main/java/cz/zcu/kiv/crce/resolver/optimizer/CostFunctionFactory.java create mode 100644 core/crce-resolver-api/src/main/java/cz/zcu/kiv/crce/resolver/optimizer/CostFunctionRepository.java create mode 100644 core/crce-resolver-api/src/main/java/cz/zcu/kiv/crce/resolver/optimizer/NsResultOptimizer.java create mode 100644 core/crce-resolver-api/src/main/java/cz/zcu/kiv/crce/resolver/optimizer/OptimizationMode.java create mode 100644 core/crce-resolver-api/src/main/java/cz/zcu/kiv/crce/resolver/optimizer/ResultOptimizer.java create mode 100644 core/crce-resolver-api/src/main/java/cz/zcu/kiv/crce/resolver/optimizer/ResultOptimizerRepository.java create mode 100644 core/crce-resolver-impl/src/main/java/cz/zcu/kiv/crce/resolver/internal/optimizer/OsgiCostFunctionRepository.java create mode 100644 core/crce-resolver-impl/src/main/java/cz/zcu/kiv/crce/resolver/internal/optimizer/OsgiResultOptimizerRepository.java create mode 100644 modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/ChainableTask.java rename {core/crce-metadata-dao-impl => modules/crce-optimizer-functions}/.classpath (79%) rename modules/{crce-webui => crce-optimizer-functions}/.project (51%) create mode 100644 modules/crce-optimizer-functions/osgi.bnd create mode 100644 modules/crce-optimizer-functions/pom.xml create mode 100644 modules/crce-optimizer-functions/src/main/java/cz/zcu/kiv/crce/optimizer/internal/cost/EqualCostFunction.java create mode 100644 modules/crce-optimizer-functions/src/main/java/cz/zcu/kiv/crce/optimizer/internal/cost/FileSizeCostFunction.java create mode 100644 modules/crce-optimizer-functions/src/main/java/cz/zcu/kiv/crce/optimizer/internal/result/IlpLPSolveOptimizer.java create mode 100644 modules/crce-optimizer-functions/src/main/java/cz/zcu/kiv/crce/optimizer/internal/result/IlpLPSolveTransitiveOptimizer.java create mode 100644 modules/crce-rest-v2/src/main/java/cz/zcu/kiv/crce/rest/v2/internal/CORSFilter.java create mode 100644 modules/crce-rest-v2/src/main/java/cz/zcu/kiv/crce/rest/v2/internal/Headers.java create mode 100644 modules/crce-rest-v2/src/main/java/cz/zcu/kiv/crce/rest/v2/internal/ws/CostFunctionRes.java create mode 100644 modules/crce-rest-v2/src/main/java/cz/zcu/kiv/crce/rest/v2/internal/ws/OptimizerRes.java create mode 100644 modules/crce-rest-v2/src/main/java/cz/zcu/kiv/crce/rest/v2/internal/ws/jersey/CostFunctionResJersey.java create mode 100644 modules/crce-rest-v2/src/main/java/cz/zcu/kiv/crce/rest/v2/internal/ws/jersey/OptimizerResJersey.java create mode 100644 modules/crce-vo/src/main/java/cz/zcu/kiv/crce/vo/internal/dozer/convertor/RequirementConvertor.java create mode 100644 modules/crce-vo/src/main/java/cz/zcu/kiv/crce/vo/model/metadata/DirectiveVO.java create mode 100644 modules/crce-vo/src/main/java/cz/zcu/kiv/crce/vo/model/metadata/RequirementListVO.java create mode 100644 modules/crce-vo/src/main/java/cz/zcu/kiv/crce/vo/model/optimizer/CostFunctionDescriptorVO.java create mode 100644 modules/crce-vo/src/main/java/cz/zcu/kiv/crce/vo/model/optimizer/ResultOptimizerVO.java create mode 100644 modules/crce-vo/src/test/java/cz/zcu/kiv/crce/vo/internal/dozer/convertor/RequirementConvertorTest.java delete mode 100644 modules/crce-webui/osgi.bnd delete mode 100644 modules/crce-webui/pom.xml delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Activator.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Helper.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/SessionListener.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/UploadServlet.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/VersionInfo.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/bean/Category.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/Plugin.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/filter/CompatibilityAvailabilityFilter.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Capability.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Property.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/PropertyProvider.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Requirement.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Resource.java delete mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Type.java delete mode 100644 modules/crce-webui/src/main/webapp/META-INF/MANIFEST.MF delete mode 100644 modules/crce-webui/src/main/webapp/WEB-INF/web.xml delete mode 100644 modules/crce-webui/src/main/webapp/crce.png delete mode 100644 modules/crce-webui/src/main/webapp/css/styl.css delete mode 100644 modules/crce-webui/src/main/webapp/graphic/add.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/check.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/commit.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/crce.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/del.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/edit.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/heading-bg.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/hlavicka_bg.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/hlavicka_loga.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/logo.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/menu_bg.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/save.png delete mode 100644 modules/crce-webui/src/main/webapp/graphic/zoom.png delete mode 100644 modules/crce-webui/src/main/webapp/index.jsp delete mode 100644 modules/crce-webui/src/main/webapp/js/jquery-1.5.1.js delete mode 100644 modules/crce-webui/src/main/webapp/js/plus_minus_form.js delete mode 100644 modules/crce-webui/src/main/webapp/js/slide.js delete mode 100644 modules/crce-webui/src/main/webapp/jsp/buffer.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/compatibility.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/capabilitiesForm.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/capabilityForm.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/categoriesForm.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/categoryForm.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/pluginForm.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/propertiesForm.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/propertyForm.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/requirementForm.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/requirementsForm.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/testForm.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/include/footer.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/include/header.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/plugins.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/store.jsp delete mode 100644 modules/crce-webui/src/main/webapp/jsp/tags.jsp delete mode 100644 modules/crce-webui/src/main/webapp/test.jsp delete mode 100644 modules/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java create mode 100644 third-party/jna-platform/osgi.bnd create mode 100644 third-party/jna-platform/pom.xml create mode 100644 third-party/lpsolve/osgi.bnd create mode 100644 third-party/lpsolve/pom.xml create mode 100644 third-party/lpsolve/src/main/java/lpsolve/AbortListener.java create mode 100644 third-party/lpsolve/src/main/java/lpsolve/BbListener.java create mode 100644 third-party/lpsolve/src/main/java/lpsolve/LogListener.java create mode 100644 third-party/lpsolve/src/main/java/lpsolve/LpSolve.java create mode 100644 third-party/lpsolve/src/main/java/lpsolve/LpSolveException.java create mode 100644 third-party/lpsolve/src/main/java/lpsolve/MsgListener.java create mode 100644 third-party/lpsolve/src/main/java/lpsolve/VersionInfo.java create mode 100644 third-party/lpsolve/src/main/resources/libs/linux/x64/liblpsolve55j.so create mode 100644 third-party/lpsolve/src/main/resources/libs/win/x64/lpsolve55j.dll create mode 100644 third-party/lpsolve/src/main/resources/libs/win/x86/lpsolve55j.dll diff --git a/README.md b/README.md index a5eb2ecf..2f2719d8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,61 @@ # CRCE - Component Repository supporting Compatibility Evaluation CRCE is an experimental repository, designed to support research into component-based and modular systems undertaken by ReliSA research group at the Faculty of Applied Sciences, University of West Bohemia (http://relisa.kiv.zcu.cz). The project website is over at Assembla: https://www.assembla.com/spaces/crce/wiki . + +## Prerequisities + +- **JDK 7** set in `JAVA_HOME` environment variable before starting CRCE (there is a problem with running web UI on JDK 8, need to update dependencies), tested on 1.7.0_80 +- **MongoDB**, tested on v2.6.10, v3.4.10 +- **Maven 3**, tested on 3.5.2 + +On linux, switching to JDK 7 for development/build can be done via `sudo update-alternatives --config java`. + +## Build + +1. `crce-parent` in `/pom` directory +2. `shared-build-settings` in `/build` +3. everything in `/third-party` +4. `crce-core-reactor` in `/core` +5. `crce-modules-reactor` in `/modules` + +## Start up + +Run CRCE using Maven plugin for pax in `crce-modules-reactor` module (`/modules` directory); note the JDK 7 requirement above: + +`mvn pax:provision` + +The output log should write up some info about dependencies terminated by lines similar to the following: + +``` +Listening for transport dt_socket at address: 65505 +____________________________ +Welcome to Apache Felix Gogo + +g! X 10, 2017 10:38:47 DOP. org.glassfish.jersey.server.ApplicationHandler initialize +INFO: Initiating Jersey application, version Jersey: 2.9.1 2014-06-01 23:30:50... +``` + +At the moment, a bunch of errors will probably come up: + +``` +[Fatal Error] :1:1: Content is not allowed in prolog. +``` + +The cause of the latter is a badly loaded binary of mathematical solver which does not affect common application run. Any other error/exception (typically OSGi complaining about a thing) is a problem that needs to be examined as such. However, it should not happen with this version. + +Started up, the application is accessible at: + +- web UI: http://localhost:8080/crce +- REST web services: http://localhost:8080/rest/v2/ + +Updated (more or less) REST WS documentation is available at [Apiary](https://crceapi.docs.apiary.io/). + +### lpsolve installation + +To solve the issue with mathematical solver, you need to install [lpsolve library](https://sourceforge.net/projects/lpsolve/) to your computer. To do that, follow [their guide](http://lpsolve.sourceforge.net/5.5/Java/README.html#install) step by step. + +> Note that on Windows, you do not have to place the libs to `\WINDOWS` or `\WINDOWS\SYSTEM32` as the guide states. Put it wherever you wish and add the directory to your `Path`. + +## Code updates + +After modifying a part of code, only the parental module needs to be rebuilt (no need to rebuild all). After that, the pax process must be restarted. diff --git a/build/compiled/pom.xml b/build/compiled/pom.xml index 0557ad67..c0ceda26 100644 --- a/build/compiled/pom.xml +++ b/build/compiled/pom.xml @@ -127,6 +127,4 @@ - 2.1.1 - cz.zcu.kiv.crce diff --git a/build/pom.xml b/build/pom.xml index bcbf925f..c0f11ba2 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -1,208 +1,218 @@ - - - 4.0.0 - - - cz.zcu.kiv.crce - crce-parent - - 2.1.1-SNAPSHOT - - - - shared-build-settings - 2.1.2-SNAPSHOT - - CRCE - Build - Shared build configuration - - pom - - - cz.zcu.kiv.crce - 1.7 - 3.0.4 - 2.11.3 - 0.8.1-incubator - 4.3.1 - - 6.0.7 - 3.2.0 - 2.6.1 - 1.9.13 - 1.7.7 - - - - - - wrappers - compiled - - - - - - - org.ops4j - maven-pax-plugin - 1.5 - - - - org.ops4j.pax.exam - exam-maven-plugin - 4.3.0 - - - org.apache.maven.plugins - maven-surefire-plugin - 2.18 - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.18 - - - org.apache.servicemix.tooling - depends-maven-plugin - 1.2 - - - org.apache.felix - maven-bundle-plugin - 3.3.0 - true - - - org.apache.maven.plugins - maven-compiler-plugin - 3.2 - - ${version.jdk} - ${version.jdk} - ${project.build.sourceEncoding} - - - - org.apache.maven.plugins - maven-enforcer-plugin - 1.3.1 - - - enforce-versions - - enforce - - - - - ${version.jdk} - - - ${version.maven} - - - - - - - - maven-war-plugin - 2.6 - - - org.apache.maven.plugins - maven-pmd-plugin - 3.8 - - - - org.codehaus.mojo - findbugs-maven-plugin - 3.0.0 - - - org.apache.felix - org.apache.felix.dependencymanager.annotation - ${version.org.apache.felix.dependencymanager} - - - - scan - - - info - - - - - - org.apache.maven.plugins - maven-dependency-plugin - 3.0.2 - - - - org.apache.cxf - cxf-xjc-plugin - 3.0.2 - - - - - - - - - - - - - org.ops4j.pax.runner - pax-runner - 1.8.6 - provided - - - - - - org.osgi - org.osgi.core - ${version.org.osgi} - provided - true - - - - org.osgi - org.osgi.compendium - ${version.org.osgi} - provided - true - - - - - + + + 4.0.0 + + + cz.zcu.kiv.crce + crce-parent + + 2.1.1-SNAPSHOT + + + + shared-build-settings + 2.1.2-SNAPSHOT + + CRCE - Build - Shared build configuration + + pom + + + cz.zcu.kiv.crce + 1.7 + 3.0.4 + 2.13.3 + 0.8.1-incubator + 4.3.1 + + 6.0.7 + 1.0.0.Final + 3.2.0 + 2.6.1 + 1.9.13 + 1.7.7 + + + + https://github.com/ReliSA/crce/tree/master/build + https://github.com/ReliSA/crce.git + scm:git:git@github.com:ReliSA/crce.git + HEAD + + + + wrappers + compiled + + + + + + + org.ops4j + maven-pax-plugin + 1.5 + + + + org.ops4j.pax.exam + exam-maven-plugin + 4.3.0 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.18 + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.18 + + + org.apache.servicemix.tooling + depends-maven-plugin + 1.2 + + + org.apache.felix + maven-bundle-plugin + + 3.3.0 + true + + + org.apache.maven.plugins + maven-compiler-plugin + 3.2 + + ${version.jdk} + ${version.jdk} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-enforcer-plugin + 1.3.1 + + + enforce-versions + + enforce + + + + + ${version.jdk} + + + ${version.maven} + + + + + + + + maven-war-plugin + 2.6 + + + org.apache.maven.plugins + maven-pmd-plugin + 3.8 + + + + org.codehaus.mojo + findbugs-maven-plugin + 3.0.0 + + + org.apache.felix + org.apache.felix.dependencymanager.annotation + ${version.org.apache.felix.dependencymanager} + + + + scan + + + info + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + 3.0.2 + + + org.apache.cxf + cxf-xjc-plugin + 3.0.2 + + + + + + + + + + + + + org.ops4j.pax.runner + pax-runner + 1.8.6 + provided + + + + + + org.osgi + org.osgi.core + ${version.org.osgi} + provided + true + + + + org.osgi + org.osgi.compendium + ${version.org.osgi} + provided + true + + + + + org.ops4j.pax.web pax-web-jetty-bundle @@ -233,453 +243,461 @@ ${version.org.ops4j.pax.web} provided - - - - - - org.slf4j - slf4j-api - ${version.org.slf4j} - provided - - - - - org.slf4j - osgi-over-slf4j - ${version.org.slf4j} - provided - - - org.slf4j - log4j-over-slf4j - ${version.org.slf4j} - provided - - - org.slf4j - jcl-over-slf4j - ${version.org.slf4j} - provided - - - org.slf4j - jul-to-slf4j - ${version.org.slf4j} - provided - - - - - ch.qos.logback - logback-core - 1.1.2 - provided - - - ch.qos.logback - logback-classic - 1.1.2 - provided - - - - - - org.apache.felix - org.apache.felix.framework - 4.0.3 - - - org.apache.felix - org.apache.felix.eventadmin - 1.4.2 - provided - - - org.apache.felix - org.apache.felix.dependencymanager - ${version.org.apache.felix.dependencymanager} - provided - - - org.apache.felix - org.apache.felix.dependencymanager.shell - ${version.org.apache.felix.dependencymanager} - - provided - - - org.apache.felix - org.apache.felix.dependencymanager.annotation - ${version.org.apache.felix.dependencymanager} - compile - - - biz.aQute - bndlib - - - - - org.apache.felix - org.apache.felix.dependencymanager.runtime - ${version.org.apache.felix.dependencymanager} - provided - - - org.apache.felix - org.apache.felix.configadmin - 1.8.0 - provided - - - org.apache.felix - org.apache.felix.bundlerepository - 2.0.2 - provided - - - org.apache.felix - org.osgi.service.obr - 1.0.2 - provided - - - org.apache.felix - org.apache.felix.scr - 1.8.2 - provided - - - org.apache.felix - org.apache.felix.webconsole - 4.2.2 - provided - - - org.apache.felix - org.apache.felix.shell - 1.4.3 - provided - - - org.apache.felix - org.apache.felix.fileinstall - 3.4.2 - provided - - - - - - - log4j - log4j - 1.2.17 - true - - - org.slf4j - slf4j-log4j12 - 1.7.7 - true - - - - - - javax.servlet - servlet-api - 2.5 - provided - - - javax.servlet - jsp-api - 2.0 - provided - + + + + org.hibernate.javax.persistence + hibernate-jpa-2.1-api + ${version.jpa} + + + + + + + org.slf4j + slf4j-api + ${version.org.slf4j} + provided + + + + + org.slf4j + osgi-over-slf4j + ${version.org.slf4j} + provided + + + org.slf4j + log4j-over-slf4j + ${version.org.slf4j} + provided + + + org.slf4j + jcl-over-slf4j + ${version.org.slf4j} + provided + + + org.slf4j + jul-to-slf4j + ${version.org.slf4j} + provided + + + + + ch.qos.logback + logback-core + 1.1.2 + provided + + + ch.qos.logback + logback-classic + 1.1.2 + provided + + + + + + org.apache.felix + org.apache.felix.framework + 4.0.3 + + + org.apache.felix + org.apache.felix.eventadmin + 1.4.2 + provided + + + org.apache.felix + org.apache.felix.dependencymanager + ${version.org.apache.felix.dependencymanager} + provided + + + org.apache.felix + org.apache.felix.dependencymanager.shell + ${version.org.apache.felix.dependencymanager} + + provided + + + org.apache.felix + org.apache.felix.dependencymanager.annotation + ${version.org.apache.felix.dependencymanager} + compile + + + biz.aQute + bndlib + + + + + org.apache.felix + org.apache.felix.dependencymanager.runtime + ${version.org.apache.felix.dependencymanager} + provided + + + org.apache.felix + org.apache.felix.configadmin + 1.8.0 + provided + + + org.apache.felix + org.apache.felix.bundlerepository + 2.0.2 + provided + + + org.apache.felix + org.osgi.service.obr + 1.0.2 + provided + + + org.apache.felix + org.apache.felix.scr + 1.8.2 + provided + + + org.apache.felix + org.apache.felix.webconsole + 4.2.2 + provided + + + org.apache.felix + org.apache.felix.shell + 1.4.3 + provided + + + org.apache.felix + org.apache.felix.fileinstall + 3.4.2 + provided + + + + + + + log4j + log4j + 1.2.17 + true + + + org.slf4j + slf4j-log4j12 + 1.7.7 + true + + + + + + javax.servlet + servlet-api + 2.5 + provided + + + + + + org.apache.ace + org.apache.ace.httplistener + ${version.org.apache.ace} + provided + + + org.apache.ace + org.apache.ace.obr.metadata + ${version.org.apache.ace} + provided + + + org.apache.ace + org.apache.ace.obr.storage + ${version.org.apache.ace} + provided + + + org.apache.ace + org.apache.ace.obr.servlet + ${version.org.apache.ace} + provided + + + + + + org.mybatis + mybatis + 3.2.2 + provided + + + com.h2database + h2 + 1.3.176 + provided + + + com.googlecode.flyway + flyway-core + 2.3.1 + compile + + + + org.mongodb + mongo-java-driver + ${version.mongodb} + provided + + + + + + org.codehaus.plexus + plexus-utils + 3.0.15 + provided + + + org.apache.commons + commons-io + 1.3.2 + jar + provided + + + + commons-beanutils + commons-beanutils + 1.9.1 + provided + + + org.apache.commons + commons-lang3 + 3.3.2 + provided + + + + org.apache.felix + org.apache.felix.utils + 1.6.0 + jar + compile + + + + org.ow2.asm + asm-all + 5.2 + + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.commons-vfs + 1.0_6 + provided + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.bcel + 5.2_4 + provided + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.jaxp-ri + 1.4.5_1 + provided + + + com.google.code.gson + gson + 2.2.4 + provided + + + org.codehaus.groovy + groovy-all + 2.2.1 + provided + + + commons-fileupload + commons-fileupload + 1.3.1 + provided + + + commons-io + commons-io + 2.4 + provided + + + commons-net + commons-net + 3.3 + provided + + + de.twentyeleven.skysail + org.json-osgi + 20080701 + provided + + + org.apache.xbean + xbean-finder + + 4.5 + + provided + + + org.apache.xbean + xbean-bundleutils + + 4.5 + provided + + + + com.google.code.findbugs + jsr305 + 3.0.0 + true + + + com.google.code.findbugs + annotations + 3.0.0 + true + + + com.fasterxml.jackson.core + jackson-core + ${version.com.fasterxml.jackson} + compile + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base + ${version.com.fasterxml.jackson} + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-xml-provider + ${version.com.fasterxml.jackson} + + + com.fasterxml.jackson.core + jackson-databind + ${version.com.fasterxml.jackson} + compile + + + com.fasterxml.jackson.core + jackson-annotations + ${version.com.fasterxml.jackson} + compile + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + ${version.com.fasterxml.jackson} + compile + + + org.codehaus.jackson + jackson-core-asl + ${version.org.codehaus.jackson} + + + org.codehaus.jackson + jackson-jaxrs + ${version.org.codehaus.jackson} + + + org.codehaus.jackson + jackson-mapper-asl + ${version.org.codehaus.jackson} + + + org.codehaus.jackson + jackson-xc + ${version.org.codehaus.jackson} + + + org.codehaus.jettison + jettison + 1.3.6 + + + + + + junit + junit + 4.11 + test + + + org.skyscreamer + jsonassert + 1.2.3 + test + + + org.mockito + mockito-core + 1.9.5 + test + + + + + + + + + relisa-global + ReliSA Global Proxy repository + http://relisa-dev.kiv.zcu.cz:8081/nexus/content/groups/public + + + maven.kalwi.eu.releases + kalwi.eu releases repository + http://maven.kalwi.eu/repo/releases + + + tmatesoft + https://maven.tmatesoft.com/content/repositories/releases/ + + - - - org.apache.ace - org.apache.ace.httplistener - ${version.org.apache.ace} - provided - - - org.apache.ace - org.apache.ace.obr.metadata - ${version.org.apache.ace} - provided - - - org.apache.ace - org.apache.ace.obr.storage - ${version.org.apache.ace} - provided - - - org.apache.ace - org.apache.ace.obr.servlet - ${version.org.apache.ace} - provided - - - - - - org.mybatis - mybatis - 3.2.2 - provided - - - com.h2database - h2 - 1.3.176 - provided - - - com.googlecode.flyway - flyway-core - 2.3.1 - compile - - - - org.mongodb - mongo-java-driver - ${version.mongodb} - provided - - - - - - org.codehaus.plexus - plexus-utils - 3.0.15 - provided - - - org.apache.commons - commons-io - 1.3.2 - jar - provided - - - commons-beanutils - commons-beanutils - 1.9.1 - provided - - - org.apache.commons - commons-lang3 - 3.3.2 - provided - - - org.apache.felix - org.apache.felix.utils - 1.6.0 - jar - compile - - - - asm - asm-all - 3.3.1 - provided - - - org.ow2.asm - asm-all - 4.1 - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.commons-vfs - 1.0_6 - provided - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.bcel - 5.2_4 - provided - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.jaxp-ri - 1.4.5_1 - provided - - - com.google.code.gson - gson - 2.2.4 - provided - - - org.codehaus.groovy - groovy-all - 2.2.1 - provided - - - commons-fileupload - commons-fileupload - 1.3.1 - provided - - - commons-io - commons-io - 2.4 - provided - - - commons-net - commons-net - 3.3 - provided - - - de.twentyeleven.skysail - org.json-osgi - 20080701 - provided - - - org.apache.xbean - xbean-finder - 4.5 - - - provided - - - org.apache.xbean - xbean-bundleutils - 4.5 - - provided - - - - com.google.code.findbugs - jsr305 - 3.0.0 - true - - - com.google.code.findbugs - annotations - 3.0.0 - true - - - com.fasterxml.jackson.core - jackson-core - ${version.com.fasterxml.jackson} - compile - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-base - ${version.com.fasterxml.jackson} - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-xml-provider - ${version.com.fasterxml.jackson} - - - com.fasterxml.jackson.core - jackson-databind - ${version.com.fasterxml.jackson} - compile - - - com.fasterxml.jackson.core - jackson-annotations - ${version.com.fasterxml.jackson} - compile - - - com.fasterxml.jackson.module - jackson-module-jaxb-annotations - ${version.com.fasterxml.jackson} - compile - - - org.codehaus.jackson - jackson-core-asl - ${version.org.codehaus.jackson} - - - org.codehaus.jackson - jackson-jaxrs - ${version.org.codehaus.jackson} - - - org.codehaus.jackson - jackson-mapper-asl - ${version.org.codehaus.jackson} - - - org.codehaus.jackson - jackson-xc - ${version.org.codehaus.jackson} - - - org.codehaus.jettison - jettison - 1.3.6 - - - - - - junit - junit - 4.11 - test - - - org.skyscreamer - jsonassert - 1.2.3 - test - - - org.mockito - mockito-core - 1.9.5 - test - - - - - - - - relisa-global - ReliSA Global Proxy repository - http://relisa-dev.kiv.zcu.cz:8081/nexus/content/groups/public - - - maven.kalwi.eu.releases - kalwi.eu releases repository - http://maven.kalwi.eu/repo/releases - - - cz.zcu.kiv.crce diff --git a/core/crce-core/pom.xml b/core/crce-core/pom.xml index 697729ed..1811c2a2 100644 --- a/core/crce-core/pom.xml +++ b/core/crce-core/pom.xml @@ -10,7 +10,6 @@ - cz.zcu.kiv.crce crce-core 3.0.0-SNAPSHOT pom @@ -28,7 +27,7 @@ ${project.groupId} crce-metadata-api - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} @@ -37,13 +36,13 @@ ${project.groupId} - crce-metadata-dao-impl - 3.1.0-SNAPSHOT + crce-metadata-dao-mongodb + 3.0.0-SNAPSHOT ${project.groupId} crce-metadata-impl - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} @@ -68,17 +67,17 @@ ${project.groupId} crce-metadata-service-api - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} crce-metadata-service-impl - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} crce-plugin-api - 2.1.0 + 2.1.1-SNAPSHOT ${project.groupId} diff --git a/core/crce-metadata-api/.classpath b/core/crce-metadata-api/.classpath index d2ddf387..ff36ca09 100644 --- a/core/crce-metadata-api/.classpath +++ b/core/crce-metadata-api/.classpath @@ -25,6 +25,7 @@ + diff --git a/core/crce-metadata-api/.project b/core/crce-metadata-api/.project index b54c54b5..dcddf63f 100644 --- a/core/crce-metadata-api/.project +++ b/core/crce-metadata-api/.project @@ -5,6 +5,11 @@ + + org.eclipse.wst.common.project.facet.core.builder + + + org.eclipse.jdt.core.javabuilder @@ -20,11 +25,31 @@ + + org.jboss.tools.jst.web.kb.kbbuilder + + + + + org.jboss.tools.cdi.core.cdibuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + - org.fusesource.ide.project.RiderProjectNature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.pde.PluginNature + org.fusesource.ide.project.RiderProjectNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.jboss.tools.jst.web.kb.kbnature + org.jboss.tools.cdi.core.cdinature diff --git a/core/crce-metadata-api/pom.xml b/core/crce-metadata-api/pom.xml index c383f269..303c5ec3 100644 --- a/core/crce-metadata-api/pom.xml +++ b/core/crce-metadata-api/pom.xml @@ -64,5 +64,4 @@ - cz.zcu.kiv.crce diff --git a/core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/MetadataFactory.java b/core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/MetadataFactory.java index 13f3be89..659218c7 100644 --- a/core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/MetadataFactory.java +++ b/core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/MetadataFactory.java @@ -29,6 +29,9 @@ public interface MetadataFactory { @Nonnull Resource createResource(String id); + //TODO move this to (Store?) + Resource createResourceView(Resource... resources); + /** * Creates an empty requirement with given name. * @param namespace Name of created requirement. diff --git a/core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/namespace/NsCrceIdentity.java b/core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/namespace/NsCrceIdentity.java index fdef00a2..a7b1cc5c 100644 --- a/core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/namespace/NsCrceIdentity.java +++ b/core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/namespace/NsCrceIdentity.java @@ -23,6 +23,7 @@ public final class NsCrceIdentity { public static final AttributeType ATTRIBUTE__EXTERNAL_ID = new SimpleAttributeType<>("external-id", String.class); public static final AttributeType ATTRIBUTE__NAME = new SimpleAttributeType<>("name", String.class); + public static final AttributeType ATTRIBUTE__REPOSITORY_ID = new SimpleAttributeType<>("repository-id", String.class); public static final AttributeType ATTRIBUTE__URI = new SimpleAttributeType<>("uri", URI.class); public static final AttributeType ATTRIBUTE__FILE_NAME = new SimpleAttributeType<>("file-name", String.class); public static final AttributeType ATTRIBUTE__SIZE = new SimpleAttributeType<>("size", Long.class); diff --git a/core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/namespace/NsCrceView.java b/core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/namespace/NsCrceView.java new file mode 100644 index 00000000..2ad17bd4 --- /dev/null +++ b/core/crce-metadata-api/src/main/java/cz/zcu/kiv/crce/metadata/namespace/NsCrceView.java @@ -0,0 +1,26 @@ +package cz.zcu.kiv.crce.metadata.namespace; + +import java.util.List; + +import cz.zcu.kiv.crce.metadata.AttributeType; +import cz.zcu.kiv.crce.metadata.impl.ListAttributeType; + +/** + * TODO drop this and move to identity capability + * + * Date: 23.7.17 + * + * @author Jakub Danek + */ +public class NsCrceView { + + public static final String NAMESPACE__CRCE_VIEW_IDENTITY = "crce.view.identity"; + + public static final AttributeType ATTRIBUTE__SIZE = NsCrceIdentity.ATTRIBUTE__SIZE; + + public static final AttributeType> ATTRIBUTE__RESOURCE_IDS = new ListAttributeType("resources"); + public static final AttributeType> ATTRIBUTE__RESOURCE_NAMES = new ListAttributeType("resource-names"); + + public static final AttributeType> ATTRIBUTE__CATEGORIES = NsCrceIdentity.ATTRIBUTE__CATEGORIES; + +} diff --git a/core/crce-metadata-dao-api/.classpath b/core/crce-metadata-dao-api/.classpath index 150739e5..a086d4a1 100644 --- a/core/crce-metadata-dao-api/.classpath +++ b/core/crce-metadata-dao-api/.classpath @@ -12,15 +12,15 @@ - + - - + + diff --git a/core/crce-metadata-dao-api/.project b/core/crce-metadata-dao-api/.project index 628a61d0..0d413bc0 100644 --- a/core/crce-metadata-dao-api/.project +++ b/core/crce-metadata-dao-api/.project @@ -16,36 +16,36 @@ - org.jboss.tools.jst.web.kb.kbbuilder + org.eclipse.m2e.core.maven2Builder - org.jboss.tools.cdi.core.cdibuilder + org.fusesource.ide.project.RiderProjectBuilder - org.eclipse.wst.validation.validationbuilder + org.jboss.tools.jst.web.kb.kbbuilder - org.eclipse.m2e.core.maven2Builder + org.jboss.tools.cdi.core.cdibuilder - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.wst.validation.validationbuilder - org.fusesource.ide.project.RiderProjectNature org.eclipse.jem.workbench.JavaEMFNature org.eclipse.wst.common.modulecore.ModuleCoreNature org.eclipse.pde.PluginNature + org.fusesource.ide.project.RiderProjectNature org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature org.eclipse.wst.common.project.facet.core.nature diff --git a/core/crce-metadata-dao-api/pom.xml b/core/crce-metadata-dao-api/pom.xml index d1f8e2eb..483bcd54 100644 --- a/core/crce-metadata-dao-api/pom.xml +++ b/core/crce-metadata-dao-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.1-SNAPSHOT diff --git a/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/ResourceDAO.java b/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/MetadataDao.java similarity index 54% rename from core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/ResourceDAO.java rename to core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/MetadataDao.java index 795afea7..6c7efb25 100644 --- a/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/ResourceDAO.java +++ b/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/MetadataDao.java @@ -10,20 +10,21 @@ import cz.zcu.kiv.crce.metadata.Repository; import cz.zcu.kiv.crce.metadata.Resource; -import cz.zcu.kiv.crce.metadata.dao.filter.ResourceDAOFilter; +import cz.zcu.kiv.crce.metadata.dao.filter.ResourceFilter; /** * Plugin implementing this class manages retrieving and storing metadata of an * artifact. * - *

Typical usage of ResourceDAO plugin is in repository core to + *

Typical usage of MetadataDao plugin is in repository core to * manipulate and manage metadata resource while uploading artifacts, retrieving * them, copying etc. * * @author Jiri Kucera (jiri.kucera@kalwi.eu) + * @version 3.0.0 */ @ParametersAreNonnullByDefault -public interface ResourceDAO { +public interface MetadataDao { /** * Returns Resource object for the given resource. Returns @@ -36,8 +37,14 @@ public interface ResourceDAO { @CheckForNull Resource loadResource(URI uri) throws IOException; + @CheckForNull + Resource loadResource(String uid, boolean withDetails) throws IOException; + @Nonnull - List loadResources(Repository repository) throws IOException; + List loadResourcesWithoutCategory(String category, boolean withDetails) throws IOException; + + @Nonnull + List loadResources(Repository repository, boolean withDetails) throws IOException; /** * Loads all resources in the given repository and whose capabilities match the given filter (at least one capability must match). @@ -47,7 +54,7 @@ public interface ResourceDAO { * @throws IOException */ @Nonnull - List loadResources(Repository repository, ResourceDAOFilter filter) throws IOException; + List loadResources(Repository repository, boolean withDetails, ResourceFilter filter) throws IOException; /** * Saves metadata of Resource. @@ -67,4 +74,28 @@ public interface ResourceDAO { boolean existsResource(URI uri) throws IOException; boolean existsResource(URI uri, Repository repository) throws IOException; + + /** + * Reads metadata of resources stored in repository on the given URI. + * @param uri Path to repository or a repository identificator. + * @return Loaded repository or null if such repository doesn't exist. + * @throws IOException + */ + @CheckForNull + Repository loadRepository(URI uri) throws IOException; + + /** + * Deletes existing repository (if it exists) including all contained resources. + * @param repository + * @throws IOException + */ + void deleteRepository(Repository repository) throws IOException; + + /** + * Stores metadata of resources stored in the given repository. Typical + * target is a repository.xml in the root folder of the repository. + * @param repository + * @throws IOException + */ + void saveRepository(Repository repository) throws IOException; } diff --git a/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/RepositoryDAO.java b/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/RepositoryDAO.java deleted file mode 100644 index 58c6aa01..00000000 --- a/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/RepositoryDAO.java +++ /dev/null @@ -1,43 +0,0 @@ -package cz.zcu.kiv.crce.metadata.dao; - -import java.io.IOException; -import java.net.URI; - -import javax.annotation.CheckForNull; -import javax.annotation.ParametersAreNonnullByDefault; - -import cz.zcu.kiv.crce.metadata.Repository; - -/** - * This type of plugin defines DAO class for reading and storing the metadata of - * a repository. - * - * @author Jiri Kucera (jiri.kucera@kalwi.eu) - */ -@ParametersAreNonnullByDefault -public interface RepositoryDAO { - - /** - * Reads metadata of resources stored in repository on the given URI. - * @param uri Path to repository or a repository identificator. - * @return Loaded repository or null if such repository doesn't exist. - * @throws IOException - */ - @CheckForNull - Repository loadRepository(URI uri) throws IOException; - - /** - * Deletes existing repository (if it exists) including all contained resources. - * @param repository - * @throws IOException - */ - void deleteRepository(Repository repository) throws IOException; - - /** - * Stores metadata of resources stored in the given repository. Typical - * target is a repository.xml in the root folder of the repository. - * @param repository - * @throws IOException - */ - void saveRepository(Repository repository) throws IOException; -} diff --git a/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/CapabilityFilter.java b/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/CapabilityFilter.java index ad85fe5b..0de480e0 100644 --- a/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/CapabilityFilter.java +++ b/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/CapabilityFilter.java @@ -10,6 +10,8 @@ * Date: 10.3.16 * * @author Jakub Danek + * @since 3.0.0 + * @version 3.0.0 */ public class CapabilityFilter { @@ -51,7 +53,7 @@ public void addSubFilter(CapabilityFilter subFilter) { this.subFilters.add(subFilter); } - public void addSubFilters(List subFilters) { + public void addSubFilters(Collection subFilters) { this.subFilters.addAll(subFilters); } @@ -73,13 +75,21 @@ public void setOperator(Operator operator) { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof CapabilityFilter)) return false; + if (this == o) { + return true; + } + if (!(o instanceof CapabilityFilter)) { + return false; + } CapabilityFilter that = (CapabilityFilter) o; - if (namespace != null ? !namespace.equals(that.namespace) : that.namespace != null) return false; - if (!attributes.equals(that.attributes)) return false; + if (namespace != null ? !namespace.equals(that.namespace) : that.namespace != null) { + return false; + } + if (!attributes.equals(that.attributes)) { + return false; + } return subFilters.equals(that.subFilters); } diff --git a/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/Operator.java b/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/Operator.java index fd91b626..7374ff56 100644 --- a/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/Operator.java +++ b/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/Operator.java @@ -4,6 +4,8 @@ * Date: 10.3.16 * * @author Jakub Danek + * @since 3.0.0 + * @version 3.0.0 */ public enum Operator { AND("AND"), diff --git a/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/ResourceDAOFilter.java b/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/ResourceFilter.java similarity index 88% rename from core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/ResourceDAOFilter.java rename to core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/ResourceFilter.java index a89300dc..9af71dad 100644 --- a/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/ResourceDAOFilter.java +++ b/core/crce-metadata-dao-api/src/main/java/cz/zcu/kiv/crce/metadata/dao/filter/ResourceFilter.java @@ -7,8 +7,10 @@ * Date: 10.3.16 * * @author Jakub Danek + * @since 3.0.0 + * @version 3.0.0 */ -public class ResourceDAOFilter { +public class ResourceFilter { /** * Operator to be used to joing the filters @@ -16,7 +18,8 @@ public class ResourceDAOFilter { private Operator operator; private final List capabilityFilters; - public ResourceDAOFilter() { + public ResourceFilter() { + this.operator = Operator.AND; this.capabilityFilters = new ArrayList<>(); } diff --git a/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/ResourceDAOImpl.java b/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/MetadataDaoImpl.java similarity index 81% rename from core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/ResourceDAOImpl.java rename to core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/MetadataDaoImpl.java index 42a395bb..7ab7b5ac 100644 --- a/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/ResourceDAOImpl.java +++ b/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/MetadataDaoImpl.java @@ -11,6 +11,7 @@ import java.util.Map; import java.util.Map.Entry; +import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import org.apache.felix.dm.annotation.api.Component; @@ -28,12 +29,13 @@ import cz.zcu.kiv.crce.metadata.Repository; import cz.zcu.kiv.crce.metadata.Requirement; import cz.zcu.kiv.crce.metadata.Resource; -import cz.zcu.kiv.crce.metadata.dao.ResourceDAO; -import cz.zcu.kiv.crce.metadata.dao.filter.ResourceDAOFilter; +import cz.zcu.kiv.crce.metadata.dao.MetadataDao; +import cz.zcu.kiv.crce.metadata.dao.filter.ResourceFilter; import cz.zcu.kiv.crce.metadata.dao.internal.db.DbAttribute; import cz.zcu.kiv.crce.metadata.dao.internal.db.DbCapability; import cz.zcu.kiv.crce.metadata.dao.internal.db.DbDirective; import cz.zcu.kiv.crce.metadata.dao.internal.db.DbProperty; +import cz.zcu.kiv.crce.metadata.dao.internal.db.DbRepository; import cz.zcu.kiv.crce.metadata.dao.internal.db.DbRequirement; import cz.zcu.kiv.crce.metadata.dao.internal.db.DbResource; import cz.zcu.kiv.crce.metadata.dao.internal.mapper.ResolvingMapper; @@ -47,17 +49,18 @@ * @author Jan Dyrczyk (dyrczyk@students.zcu.cz) * @author Pavel Cihlář */ -@Component(provides={ResourceDAO.class}) -public class ResourceDAOImpl implements ResourceDAO { +@Component(provides={MetadataDao.class}) +public class MetadataDaoImpl implements MetadataDao { - private static final Logger logger = LoggerFactory.getLogger(ResourceDAOImpl.class); + private static final Logger logger = LoggerFactory.getLogger(MetadataDaoImpl.class); private static final String RESOURCE_MAPPER = "cz.zcu.kiv.crce.metadata.dao.internal.mapper.ResourceMapper."; + private static final String REPOSITORY_MAPPER = "cz.zcu.kiv.crce.metadata.dao.internal.mapper.RepositoryMapper."; + @ServiceDependency private volatile MetadataFactory metadataFactory; @ServiceDependency private volatile MetadataService metadataService; @ServiceDependency private volatile SessionManager sessionManager; - @ServiceDependency private volatile RepositoryDAOImpl repositoryDAOImpl; @Start void start() { @@ -69,6 +72,11 @@ synchronized void stop() { logger.info("CRCE Metadata DAO ResourceDAO finished."); } + @Override + public Resource loadResource(String uid, boolean withDetails) throws IOException { + throw new UnsupportedOperationException("Too lazy to implement this."); + } + @Override public synchronized Resource loadResource(URI uri) throws IOException { // TODO, only an URI as an argument is not nice logger.debug("loadResource(uri={})", uri); @@ -89,6 +97,29 @@ public synchronized Resource loadResource(URI uri) throws IOException { // TODO, return result; } + @Override + public List loadResourcesWithoutCategory(String category, boolean withDetails) throws IOException { + logger.debug("loadResourcesWithoutCateogry(category={})", category); + + List result = new ArrayList<>(); + + try (SqlSession session = sessionManager.getSession()) { + List dbResources = session.selectList(RESOURCE_MAPPER + "selectResourceByMissingCategory", category); + + if (dbResources != null) { + for (DbResource dbResource : dbResources) { + result.add(loadResource(dbResource, session)); + } + + } + } catch (PersistenceException e) { + throw new IOException("Could not load resource.", e); + } + + logger.debug("loadResource(uri) returns {}", result); + return result; + } + private Resource loadResource(@Nonnull DbResource dbResource, @Nonnull SqlSession session) { Resource resource = metadataFactory.createResource(dbResource.getId()); // loaded from DB as part of capabilities: @@ -279,12 +310,12 @@ void loadCapabilityPropertyAttributes(Property property, long propertyId, SqlSes } @Override - public synchronized List loadResources(Repository repository) throws IOException { + public synchronized List loadResources(Repository repository, boolean withDetails) throws IOException { logger.debug("loadResources(repository={})", repository); List result = Collections.emptyList(); try (SqlSession session = sessionManager.getSession()) { - Long repositoryId = repositoryDAOImpl.getRepositoryId(repository.getId(), session); + Long repositoryId = getRepositoryId(repository.getId(), session); if (repositoryId != null) { List dbResources = session.selectList(RESOURCE_MAPPER + "selectResourcesByRepositoryId", repositoryId); @@ -312,13 +343,13 @@ public synchronized List loadResources(Repository repository) throws I } @Override - public List loadResources(@Nonnull Repository repository, @Nonnull ResourceDAOFilter filter) throws IOException { + public List loadResources(@Nonnull Repository repository, boolean withDetails, @Nonnull ResourceFilter filter) throws IOException { logger.debug("loadResources(repository={}, filter={})", repository, logger.isTraceEnabled() ? filter.toString() : "(" + filter.getCapabilityFilters().size() + ")"); List result = Collections.emptyList(); try (SqlSession session = sessionManager.getSession()) { - Long repositoryId = repositoryDAOImpl.getRepositoryId(repository.getId(), session); + Long repositoryId = getRepositoryId(repository.getId(), session); if (repositoryId != null) { List dbResources = session.getMapper(ResolvingMapper.class).getResources(repositoryId, filter); @@ -378,7 +409,7 @@ public synchronized void saveResource(Resource resource) throws IOException { throw new IllegalArgumentException("Repository is not set on resource: " + resource.getId()); } - Long repositoryId = repositoryDAOImpl.getRepositoryId(repositoryUuid, session); + Long repositoryId = getRepositoryId(repositoryUuid, session); if (repositoryId == null) { throw new IllegalArgumentException("Repository doesn't exist: " + repositoryUuid); } @@ -542,7 +573,7 @@ public boolean existsResource(URI uri, Repository repository) throws IOException boolean result = false; try (SqlSession session = sessionManager.getSession()) { - Long repositoryId = repositoryDAOImpl.getRepositoryId(repository.getId(), session); + Long repositoryId = getRepositoryId(repository.getId(), session); DbResource dbResource = session.selectOne(RESOURCE_MAPPER + "selectResourceByUri", uri.toString()); if (dbResource != null && dbResource.getRepositoryId() == repositoryId) { @@ -570,4 +601,106 @@ private boolean existsResource(@Nonnull String id) throws IOException { return result; } + + + @Override + public Repository loadRepository(URI uri) throws IOException { + logger.debug("loadRepository(uri={})", uri); + + Repository repository; + try (SqlSession session = sessionManager.getSession()) { + repository = loadRepository(uri, session); + } catch (PersistenceException e) { + throw new IOException(e); + } + + logger.debug("loadRepository(uri={}) returns {}", uri, repository); + + return repository; + } + + @CheckForNull + private Repository loadRepository(@Nonnull URI uri, @Nonnull SqlSession session) { + Repository repository = null; + DbRepository dbRepository = session.selectOne(REPOSITORY_MAPPER + "selectRepositoryByUri", uri.toString()); + if (dbRepository != null) { + try { + repository = metadataFactory.createRepository(new URI(dbRepository.getUri()), dbRepository.getId()); + } catch (URISyntaxException ex) { + throw new IllegalArgumentException("Invalid URI: " + dbRepository.getUri(), ex); + } + } + return repository; + } + + @Override + public void deleteRepository(Repository repository) throws IOException { + logger.debug("deleteRepository(repository={})", repository); + + try (SqlSession session = sessionManager.getSession()) { + session.delete(REPOSITORY_MAPPER + "deleteRepository", repository.getUri().toString()); + } + + logger.debug("deleteRepository(repository={}) returns", repository); + } + + @Override + public void saveRepository(Repository repository) throws IOException { + logger.debug("saveRepository(repository={})", repository); + + try (SqlSession session = sessionManager.getSession()) { + if (loadRepository(repository.getUri()) == null) { + SequenceMapper seqMapper = session.getMapper(SequenceMapper.class); + + DbRepository dbRepository = new DbRepository(); + + long repositoryId = seqMapper.nextVal("resource_seq"); + + dbRepository.setRepositoryId(repositoryId); + dbRepository.setUri(repository.getUri().toString()); + dbRepository.setId(repository.getId()); + + session.insert(REPOSITORY_MAPPER + "insertRepository", dbRepository); + + session.commit(); + } else { + logger.info("Saved repository already exists, saving skipped (update not implemented)."); + } + } + + logger.debug("saveRepository(repository={}) returns", repository); + } + + /* Internal public methods */ + + @CheckForNull + public Long getRepositoryId(@Nonnull String uuid, @Nonnull SqlSession session) { + logger.debug("getRepositoryId(uuid={})", uuid); + + Long repositoryId = session.selectOne(REPOSITORY_MAPPER + "selectRepositoryId", uuid); + + logger.debug("getRepositoryId(uuid={}) returns {}", uuid, repositoryId); + + return repositoryId; + } + + @CheckForNull + public Repository loadRepository(long repositoryId, @Nonnull SqlSession session) throws IOException { + logger.debug("getRepository(repositoryId={})", repositoryId); + + Repository repository = null; + + DbRepository dbRepository = session.selectOne(REPOSITORY_MAPPER + "selectRepositoryByRepositoryId", repositoryId); + if (dbRepository != null) { + try { + repository = metadataFactory.createRepository(new URI(dbRepository.getUri()), dbRepository.getId()); + } catch (URISyntaxException e) { + throw new IOException("Invalid URI syntax of repository with ID: " + repositoryId + ", URI: " + dbRepository.getUri(), e); + } + } + + logger.debug("getRepository(repositoryId={}) returns {}", repositoryId, repository); + + return repository; + } } diff --git a/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/RepositoryDAOImpl.java b/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/RepositoryDAOImpl.java deleted file mode 100644 index d6a147d4..00000000 --- a/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/RepositoryDAOImpl.java +++ /dev/null @@ -1,153 +0,0 @@ -package cz.zcu.kiv.crce.metadata.dao.internal; - -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; - -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; - -import org.apache.felix.dm.annotation.api.Component; -import org.apache.felix.dm.annotation.api.ServiceDependency; -import org.apache.felix.dm.annotation.api.Start; -import org.apache.felix.dm.annotation.api.Stop; -import org.apache.ibatis.exceptions.PersistenceException; -import org.apache.ibatis.session.SqlSession; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import cz.zcu.kiv.crce.metadata.Repository; -import cz.zcu.kiv.crce.metadata.MetadataFactory; -import cz.zcu.kiv.crce.metadata.dao.RepositoryDAO; -import cz.zcu.kiv.crce.metadata.dao.internal.db.DbRepository; -import cz.zcu.kiv.crce.metadata.dao.internal.mapper.SequenceMapper; -import cz.zcu.kiv.crce.metadata.service.MetadataService; - -/** - * - * @author Jiri Kucera (jiri.kucera@kalwi.eu) - */ -@Component(provides={RepositoryDAO.class, RepositoryDAOImpl.class}) -public class RepositoryDAOImpl implements RepositoryDAO { - - private static final Logger logger = LoggerFactory.getLogger(RepositoryDAOImpl.class); - - private static final String REPOSITORY_MAPPER = "cz.zcu.kiv.crce.metadata.dao.internal.mapper.RepositoryMapper."; - - @ServiceDependency private volatile MetadataFactory metadataFactory; - @ServiceDependency private volatile MetadataService metadataService; // NOPMD - @ServiceDependency private volatile SessionManager sessionManager; - - @Start - void start() { - logger.info("CRCE Metadata DAO RepositoryDAO started."); - } - - @Stop - synchronized void stop() { - logger.info("CRCE Metadata DAO RepositoryDAO finished."); - } - - @Override - public Repository loadRepository(URI uri) throws IOException { - logger.debug("loadRepository(uri={})", uri); - - Repository repository; - try (SqlSession session = sessionManager.getSession()) { - repository = loadRepository(uri, session); - } catch (PersistenceException e) { - throw new IOException(e); - } - - logger.debug("loadRepository(uri={}) returns {}", uri, repository); - - return repository; - } - - @CheckForNull - private Repository loadRepository(@Nonnull URI uri, @Nonnull SqlSession session) { - Repository repository = null; - DbRepository dbRepository = session.selectOne(REPOSITORY_MAPPER + "selectRepositoryByUri", uri.toString()); - if (dbRepository != null) { - try { - repository = metadataFactory.createRepository(new URI(dbRepository.getUri()), dbRepository.getId()); - } catch (URISyntaxException ex) { - throw new IllegalArgumentException("Invalid URI: " + dbRepository.getUri(), ex); - } - } - return repository; - } - - @Override - public void deleteRepository(Repository repository) throws IOException { - logger.debug("deleteRepository(repository={})", repository); - - try (SqlSession session = sessionManager.getSession()) { - session.delete(REPOSITORY_MAPPER + "deleteRepository", repository.getUri().toString()); - } - - logger.debug("deleteRepository(repository={}) returns", repository); - } - - @Override - public void saveRepository(Repository repository) throws IOException { - logger.debug("saveRepository(repository={})", repository); - - try (SqlSession session = sessionManager.getSession()) { - if (loadRepository(repository.getUri()) == null) { - SequenceMapper seqMapper = session.getMapper(SequenceMapper.class); - - DbRepository dbRepository = new DbRepository(); - - long repositoryId = seqMapper.nextVal("resource_seq"); - - dbRepository.setRepositoryId(repositoryId); - dbRepository.setUri(repository.getUri().toString()); - dbRepository.setId(repository.getId()); - - session.insert(REPOSITORY_MAPPER + "insertRepository", dbRepository); - - session.commit(); - } else { - logger.info("Saved repository already exists, saving skipped (update not implemented)."); - } - } - - logger.debug("saveRepository(repository={}) returns", repository); - } - - /* Internal public methods */ - - @CheckForNull - public Long getRepositoryId(@Nonnull String uuid, @Nonnull SqlSession session) { - logger.debug("getRepositoryId(uuid={})", uuid); - - Long repositoryId = session.selectOne(REPOSITORY_MAPPER + "selectRepositoryId", uuid); - - logger.debug("getRepositoryId(uuid={}) returns {}", uuid, repositoryId); - - return repositoryId; - } - - @CheckForNull - public Repository loadRepository(long repositoryId, @Nonnull SqlSession session) throws IOException { - logger.debug("getRepository(repositoryId={})", repositoryId); - - Repository repository = null; - - DbRepository dbRepository = session.selectOne(REPOSITORY_MAPPER + "selectRepositoryByRepositoryId", repositoryId); - if (dbRepository != null) { - try { - repository = metadataFactory.createRepository(new URI(dbRepository.getUri()), dbRepository.getId()); - } catch (URISyntaxException e) { - throw new IOException("Invalid URI syntax of repository with ID: " + repositoryId + ", URI: " + dbRepository.getUri(), e); - } - } - - logger.debug("getRepository(repositoryId={}) returns {}", repositoryId, repository); - - return repository; - } - -} diff --git a/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/mapper/ResolvingMapper.java b/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/mapper/ResolvingMapper.java index 05aa7b6d..78631db9 100644 --- a/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/mapper/ResolvingMapper.java +++ b/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/mapper/ResolvingMapper.java @@ -5,7 +5,7 @@ import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.SelectProvider; -import cz.zcu.kiv.crce.metadata.dao.filter.ResourceDAOFilter; +import cz.zcu.kiv.crce.metadata.dao.filter.ResourceFilter; import cz.zcu.kiv.crce.metadata.dao.internal.db.DbResource; /** @@ -15,5 +15,5 @@ public interface ResolvingMapper { @SelectProvider(type = SqlFilterProvider.class, method = "generateSQL") - List getResources(@Param(SqlFilterProvider.PARAM_REPOSITORY_ID) long repositoryId, @Param(SqlFilterProvider.PARAM_FILTER) ResourceDAOFilter filter); + List getResources(@Param(SqlFilterProvider.PARAM_REPOSITORY_ID) long repositoryId, @Param(SqlFilterProvider.PARAM_FILTER) ResourceFilter filter); } diff --git a/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/mapper/SqlFilterProvider.java b/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/mapper/SqlFilterProvider.java index 706c2a6d..ef9fea0e 100644 --- a/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/mapper/SqlFilterProvider.java +++ b/core/crce-metadata-dao-impl/src/main/java/cz/zcu/kiv/crce/metadata/dao/internal/mapper/SqlFilterProvider.java @@ -11,7 +11,7 @@ import cz.zcu.kiv.crce.metadata.Attribute; import cz.zcu.kiv.crce.metadata.dao.filter.CapabilityFilter; -import cz.zcu.kiv.crce.metadata.dao.filter.ResourceDAOFilter; +import cz.zcu.kiv.crce.metadata.dao.filter.ResourceFilter; import cz.zcu.kiv.crce.metadata.dao.internal.helper.SimpleStringBuilder; import cz.zcu.kiv.crce.metadata.dao.internal.type.DbAttributeType; @@ -76,7 +76,7 @@ public String generateSQL(Map params) { logger.debug("generateSQL({})", params); @SuppressWarnings("unchecked") - ResourceDAOFilter filter = (ResourceDAOFilter) params.get(PARAM_FILTER); + ResourceFilter filter = (ResourceFilter) params.get(PARAM_FILTER); switch (filter.getOperator()) { case OR: diff --git a/core/crce-metadata-dao-impl/src/main/resources/cz/zcu/kiv/crce/metadata/dao/internal/mapper/ResourceMapper.xml b/core/crce-metadata-dao-impl/src/main/resources/cz/zcu/kiv/crce/metadata/dao/internal/mapper/ResourceMapper.xml index 2a3b1b1a..a2a73245 100644 --- a/core/crce-metadata-dao-impl/src/main/resources/cz/zcu/kiv/crce/metadata/dao/internal/mapper/ResourceMapper.xml +++ b/core/crce-metadata-dao-impl/src/main/resources/cz/zcu/kiv/crce/metadata/dao/internal/mapper/ResourceMapper.xml @@ -23,6 +23,18 @@ WHERE id = #{id} + +
- - - <% - String success = request.getParameter("success"); - if ("true".equals(success)) { - out.println("

Upload successful

"); - } - if ("false".equals(success)) { - out.println("

Upload failed

"); - } - %> - -

Plugins in plugin manager:

- <% - List plugins = Activator.instance().getPluginManager().getPlugins(); - out.println(""); - out.println(""); - for (Plugin plugin : plugins) { - out.println(""); - out.println(""); - out.println(""); - } - out.println("
IDprioritydescription
" + plugin.getPluginId() + "" + plugin.getPluginPriority() + "" + plugin.getPluginDescription() + "
"); - %> - -

Resources in buffer

- - <% - - - Buffer buffer = Activator.instance().getBuffer(request); - for (Resource res : buffer.getResources()) { - out.println("

" + res.getId() + "

"); - - out.println(""); - out.println(""); - out.println(""); - out.println(""); - out.print(""); - out.println("
Presentation name:" + Activator.instance().getMetadataService().getPresentationName(res) + "
Size:" + Activator.instance().getMetadataService().getSize(res) + "
URI:" + Activator.instance().getMetadataService().getUri(res).normalize() + "
Categories:"); - boolean first = true; - for (String category : Activator.instance().getMetadataService().getCategories(res)) { - if (first) { - first = false; - } else { - out.print(", "); - } - out.print(category); - } - out.println("
"); - - /* - out.println("

Properties

"); - out.println("
"); - out.println(""); - out.println(""); - for (Property prop : res.getProperties()) { - out.println(""); - } - out.println("
typenamevalue
" + prop.getType() + "" + prop.getName() + "" + prop.getValue() + "
"); - out.println("
"); - */ - - out.println("

Capabilities

"); - - out.println(""); - - out.println(""); - - for (Capability cap : res.getCapabilities()) { - out.println(""); - out.println(""); - - out.println(""); - out.println(""); - } - - out.println("
NameProperties
" + cap.getNamespace()+ ""); - out.println(""); - out.println(""); - for (Attribute attr : cap.getAttributes()) { - out.println(""); - } - out.println("
typenamevalue
" + attr.getAttributeType().getType() - + "" + attr.getAttributeType().getName() + "" + attr.getValue() + "
"); - out.println("
"); - - - out.println("

Requirements

"); - out.println(""); - out.println(""); - for (Requirement req : res.getRequirements()) { - out.println("" - + "" - + "" - + "" - + ""); - } - out.println("
NameFilterOptionalMultipleExtended
" + req.getNamespace()+ "" + req.getDirective("filter") + "" + (Boolean.getBoolean(req.getDirective("optional")) ? "Y" : "N") + "" + (Boolean.getBoolean(req.getDirective("multiple")) ? "Y" : "N") + "" + (Boolean.getBoolean(req.getDirective("extend")) ? "Y" : "N") + "
"); - - out.println("
"); - } - - - %> - - - - diff --git a/modules/crce-webui/src/main/webapp/js/jquery-1.5.1.js b/modules/crce-webui/src/main/webapp/js/jquery-1.5.1.js deleted file mode 100644 index 78fcfa46..00000000 --- a/modules/crce-webui/src/main/webapp/js/jquery-1.5.1.js +++ /dev/null @@ -1,8316 +0,0 @@ -/*! - * jQuery JavaScript Library v1.5.1 - * http://jquery.com/ - * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Wed Feb 23 13:55:29 2011 -0500 - */ -(function( window, undefined ) { - -// Use the correct document accordingly with window argument (sandbox) -var document = window.document; -var jQuery = (function() { - -// Define a local copy of jQuery -var jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context, rootjQuery ); - }, - - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - - // Map over the $ in case of overwrite - _$ = window.$, - - // A central reference to the root jQuery(document) - rootjQuery, - - // A simple way to check for HTML strings or ID strings - // (both of which we optimize for) - quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/, - - // Check if a string has a non-whitespace character in it - rnotwhite = /\S/, - - // Used for trimming whitespace - trimLeft = /^\s+/, - trimRight = /\s+$/, - - // Check for digits - rdigit = /\d/, - - // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, - - // JSON RegExp - rvalidchars = /^[\],:{}\s]*$/, - rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, - rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, - rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - - // Useragent RegExp - rwebkit = /(webkit)[ \/]([\w.]+)/, - ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, - rmsie = /(msie) ([\w.]+)/, - rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, - - // Keep a UserAgent string for use with jQuery.browser - userAgent = navigator.userAgent, - - // For matching the engine and version of the browser - browserMatch, - - // Has the ready events already been bound? - readyBound = false, - - // The deferred used on DOM ready - readyList, - - // Promise methods - promiseMethods = "then done fail isResolved isRejected promise".split( " " ), - - // The ready event handler - DOMContentLoaded, - - // Save a reference to some core methods - toString = Object.prototype.toString, - hasOwn = Object.prototype.hasOwnProperty, - push = Array.prototype.push, - slice = Array.prototype.slice, - trim = String.prototype.trim, - indexOf = Array.prototype.indexOf, - - // [[Class]] -> type pairs - class2type = {}; - -jQuery.fn = jQuery.prototype = { - constructor: jQuery, - init: function( selector, context, rootjQuery ) { - var match, elem, ret, doc; - - // Handle $(""), $(null), or $(undefined) - if ( !selector ) { - return this; - } - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - } - - // The body element only exists once, optimize finding it - if ( selector === "body" && !context && document.body ) { - this.context = document; - this[0] = document.body; - this.selector = "body"; - this.length = 1; - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? - match = quickExpr.exec( selector ); - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - doc = (context ? context.ownerDocument || context : document); - - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - ret = rsingleTag.exec( selector ); - - if ( ret ) { - if ( jQuery.isPlainObject( context ) ) { - selector = [ document.createElement( ret[1] ) ]; - jQuery.fn.attr.call( selector, context, true ); - - } else { - selector = [ doc.createElement( ret[1] ) ]; - } - - } else { - ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); - selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; - } - - return jQuery.merge( this, selector ); - - // HANDLE: $("#id") - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return (context || rootjQuery).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return rootjQuery.ready( selector ); - } - - if (selector.selector !== undefined) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }, - - // Start with an empty selector - selector: "", - - // The current version of jQuery being used - jquery: "1.5.1", - - // The default length of a jQuery object is 0 - length: 0, - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - toArray: function() { - return slice.call( this, 0 ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num == null ? - - // Return a 'clean' array - this.toArray() : - - // Return just the object - ( num < 0 ? this[ this.length + num ] : this[ num ] ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems, name, selector ) { - // Build a new jQuery matched element set - var ret = this.constructor(); - - if ( jQuery.isArray( elems ) ) { - push.apply( ret, elems ); - - } else { - jQuery.merge( ret, elems ); - } - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - ret.context = this.context; - - if ( name === "find" ) { - ret.selector = this.selector + (this.selector ? " " : "") + selector; - } else if ( name ) { - ret.selector = this.selector + "." + name + "(" + selector + ")"; - } - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - ready: function( fn ) { - // Attach the listeners - jQuery.bindReady(); - - // Add the callback - readyList.done( fn ); - - return this; - }, - - eq: function( i ) { - return i === -1 ? - this.slice( i ) : - this.slice( i, +i + 1 ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ), - "slice", slice.call(arguments).join(",") ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - end: function() { - return this.prevObject || this.constructor(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: [].sort, - splice: [].splice -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( length === i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - noConflict: function( deep ) { - window.$ = _$; - - if ( deep ) { - window.jQuery = _jQuery; - } - - return jQuery; - }, - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Handle when the DOM is ready - ready: function( wait ) { - // A third-party is pushing the ready event forwards - if ( wait === true ) { - jQuery.readyWait--; - } - - // Make sure that the DOM is not already loaded - if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready, 1 ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.trigger ) { - jQuery( document ).trigger( "ready" ).unbind( "ready" ); - } - } - }, - - bindReady: function() { - if ( readyBound ) { - return; - } - - readyBound = true; - - // Catch cases where $(document).ready() is called after the - // browser event has already occurred. - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - return setTimeout( jQuery.ready, 1 ); - } - - // Mozilla, Opera and webkit nightlies currently support this event - if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", jQuery.ready, false ); - - // If IE event model is used - } else if ( document.attachEvent ) { - // ensure firing before onload, - // maybe late but safe also for iframes - document.attachEvent("onreadystatechange", DOMContentLoaded); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", jQuery.ready ); - - // If IE and not a frame - // continually check to see if the document is ready - var toplevel = false; - - try { - toplevel = window.frameElement == null; - } catch(e) {} - - if ( document.documentElement.doScroll && toplevel ) { - doScrollCheck(); - } - } - }, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray || function( obj ) { - return jQuery.type(obj) === "array"; - }, - - // A crude way of determining if an object is a window - isWindow: function( obj ) { - return obj && typeof obj === "object" && "setInterval" in obj; - }, - - isNaN: function( obj ) { - return obj == null || !rdigit.test( obj ) || isNaN( obj ); - }, - - type: function( obj ) { - return obj == null ? - String( obj ) : - class2type[ toString.call(obj) ] || "object"; - }, - - isPlainObject: function( obj ) { - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - - var key; - for ( key in obj ) {} - - return key === undefined || hasOwn.call( obj, key ); - }, - - isEmptyObject: function( obj ) { - for ( var name in obj ) { - return false; - } - return true; - }, - - error: function( msg ) { - throw msg; - }, - - parseJSON: function( data ) { - if ( typeof data !== "string" || !data ) { - return null; - } - - // Make sure leading/trailing whitespace is removed (IE can't handle it) - data = jQuery.trim( data ); - - // Make sure the incoming data is actual JSON - // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test(data.replace(rvalidescape, "@") - .replace(rvalidtokens, "]") - .replace(rvalidbraces, "")) ) { - - // Try to use the native JSON parser first - return window.JSON && window.JSON.parse ? - window.JSON.parse( data ) : - (new Function("return " + data))(); - - } else { - jQuery.error( "Invalid JSON: " + data ); - } - }, - - // Cross-browser xml parsing - // (xml & tmp used internally) - parseXML: function( data , xml , tmp ) { - - if ( window.DOMParser ) { // Standard - tmp = new DOMParser(); - xml = tmp.parseFromString( data , "text/xml" ); - } else { // IE - xml = new ActiveXObject( "Microsoft.XMLDOM" ); - xml.async = "false"; - xml.loadXML( data ); - } - - tmp = xml.documentElement; - - if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) { - jQuery.error( "Invalid XML: " + data ); - } - - return xml; - }, - - noop: function() {}, - - // Evalulates a script in a global context - globalEval: function( data ) { - if ( data && rnotwhite.test(data) ) { - // Inspired by code by Andrea Giammarchi - // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement, - script = document.createElement( "script" ); - - if ( jQuery.support.scriptEval() ) { - script.appendChild( document.createTextNode( data ) ); - } else { - script.text = data; - } - - // Use insertBefore instead of appendChild to circumvent an IE6 bug. - // This arises when a base node is used (#2709). - head.insertBefore( script, head.firstChild ); - head.removeChild( script ); - } - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, - length = object.length, - isObj = length === undefined || jQuery.isFunction(object); - - if ( args ) { - if ( isObj ) { - for ( name in object ) { - if ( callback.apply( object[ name ], args ) === false ) { - break; - } - } - } else { - for ( ; i < length; ) { - if ( callback.apply( object[ i++ ], args ) === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isObj ) { - for ( name in object ) { - if ( callback.call( object[ name ], name, object[ name ] ) === false ) { - break; - } - } - } else { - for ( var value = object[0]; - i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} - } - } - - return object; - }, - - // Use native String.trim function wherever possible - trim: trim ? - function( text ) { - return text == null ? - "" : - trim.call( text ); - } : - - // Otherwise use our own trimming functionality - function( text ) { - return text == null ? - "" : - text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); - }, - - // results is for internal usage only - makeArray: function( array, results ) { - var ret = results || []; - - if ( array != null ) { - // The window, strings (and functions) also have 'length' - // The extra typeof function check is to prevent crashes - // in Safari 2 (See: #3039) - // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 - var type = jQuery.type(array); - - if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { - push.call( ret, array ); - } else { - jQuery.merge( ret, array ); - } - } - - return ret; - }, - - inArray: function( elem, array ) { - if ( array.indexOf ) { - return array.indexOf( elem ); - } - - for ( var i = 0, length = array.length; i < length; i++ ) { - if ( array[ i ] === elem ) { - return i; - } - } - - return -1; - }, - - merge: function( first, second ) { - var i = first.length, - j = 0; - - if ( typeof second.length === "number" ) { - for ( var l = second.length; j < l; j++ ) { - first[ i++ ] = second[ j ]; - } - - } else { - while ( second[j] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, inv ) { - var ret = [], retVal; - inv = !!inv; - - // Go through the array, only saving the items - // that pass the validator function - for ( var i = 0, length = elems.length; i < length; i++ ) { - retVal = !!callback( elems[ i ], i ); - if ( inv !== retVal ) { - ret.push( elems[ i ] ); - } - } - - return ret; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var ret = [], value; - - // Go through the array, translating each of the items to their - // new value (or values). - for ( var i = 0, length = elems.length; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - - // Flatten any nested arrays - return ret.concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - proxy: function( fn, proxy, thisObject ) { - if ( arguments.length === 2 ) { - if ( typeof proxy === "string" ) { - thisObject = fn; - fn = thisObject[ proxy ]; - proxy = undefined; - - } else if ( proxy && !jQuery.isFunction( proxy ) ) { - thisObject = proxy; - proxy = undefined; - } - } - - if ( !proxy && fn ) { - proxy = function() { - return fn.apply( thisObject || this, arguments ); - }; - } - - // Set the guid of unique handler to the same of original handler, so it can be removed - if ( fn ) { - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - } - - // So proxy can be declared as an argument - return proxy; - }, - - // Mutifunctional method to get and set values to a collection - // The value/s can be optionally by executed if its a function - access: function( elems, key, value, exec, fn, pass ) { - var length = elems.length; - - // Setting many attributes - if ( typeof key === "object" ) { - for ( var k in key ) { - jQuery.access( elems, k, key[k], exec, fn, value ); - } - return elems; - } - - // Setting one attribute - if ( value !== undefined ) { - // Optionally, function values get executed if exec is true - exec = !pass && exec && jQuery.isFunction(value); - - for ( var i = 0; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); - } - - return elems; - } - - // Getting an attribute - return length ? fn( elems[0], key ) : undefined; - }, - - now: function() { - return (new Date()).getTime(); - }, - - // Create a simple deferred (one callbacks list) - _Deferred: function() { - var // callbacks list - callbacks = [], - // stored [ context , args ] - fired, - // to avoid firing when already doing so - firing, - // flag to know if the deferred has been cancelled - cancelled, - // the deferred itself - deferred = { - - // done( f1, f2, ...) - done: function() { - if ( !cancelled ) { - var args = arguments, - i, - length, - elem, - type, - _fired; - if ( fired ) { - _fired = fired; - fired = 0; - } - for ( i = 0, length = args.length; i < length; i++ ) { - elem = args[ i ]; - type = jQuery.type( elem ); - if ( type === "array" ) { - deferred.done.apply( deferred, elem ); - } else if ( type === "function" ) { - callbacks.push( elem ); - } - } - if ( _fired ) { - deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); - } - } - return this; - }, - - // resolve with given context and args - resolveWith: function( context, args ) { - if ( !cancelled && !fired && !firing ) { - firing = 1; - try { - while( callbacks[ 0 ] ) { - callbacks.shift().apply( context, args ); - } - } - // We have to add a catch block for - // IE prior to 8 or else the finally - // block will never get executed - catch (e) { - throw e; - } - finally { - fired = [ context, args ]; - firing = 0; - } - } - return this; - }, - - // resolve with this as context and given arguments - resolve: function() { - deferred.resolveWith( jQuery.isFunction( this.promise ) ? this.promise() : this, arguments ); - return this; - }, - - // Has this deferred been resolved? - isResolved: function() { - return !!( firing || fired ); - }, - - // Cancel - cancel: function() { - cancelled = 1; - callbacks = []; - return this; - } - }; - - return deferred; - }, - - // Full fledged deferred (two callbacks list) - Deferred: function( func ) { - var deferred = jQuery._Deferred(), - failDeferred = jQuery._Deferred(), - promise; - // Add errorDeferred methods, then and promise - jQuery.extend( deferred, { - then: function( doneCallbacks, failCallbacks ) { - deferred.done( doneCallbacks ).fail( failCallbacks ); - return this; - }, - fail: failDeferred.done, - rejectWith: failDeferred.resolveWith, - reject: failDeferred.resolve, - isRejected: failDeferred.isResolved, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - if ( obj == null ) { - if ( promise ) { - return promise; - } - promise = obj = {}; - } - var i = promiseMethods.length; - while( i-- ) { - obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; - } - return obj; - } - } ); - // Make sure only one callback list will be used - deferred.done( failDeferred.cancel ).fail( deferred.cancel ); - // Unexpose cancel - delete deferred.cancel; - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - return deferred; - }, - - // Deferred helper - when: function( object ) { - var lastIndex = arguments.length, - deferred = lastIndex <= 1 && object && jQuery.isFunction( object.promise ) ? - object : - jQuery.Deferred(), - promise = deferred.promise(); - - if ( lastIndex > 1 ) { - var array = slice.call( arguments, 0 ), - count = lastIndex, - iCallback = function( index ) { - return function( value ) { - array[ index ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; - if ( !( --count ) ) { - deferred.resolveWith( promise, array ); - } - }; - }; - while( ( lastIndex-- ) ) { - object = array[ lastIndex ]; - if ( object && jQuery.isFunction( object.promise ) ) { - object.promise().then( iCallback(lastIndex), deferred.reject ); - } else { - --count; - } - } - if ( !count ) { - deferred.resolveWith( promise, array ); - } - } else if ( deferred !== object ) { - deferred.resolve( object ); - } - return promise; - }, - - // Use of jQuery.browser is frowned upon. - // More details: http://docs.jquery.com/Utilities/jQuery.browser - uaMatch: function( ua ) { - ua = ua.toLowerCase(); - - var match = rwebkit.exec( ua ) || - ropera.exec( ua ) || - rmsie.exec( ua ) || - ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || - []; - - return { browser: match[1] || "", version: match[2] || "0" }; - }, - - sub: function() { - function jQuerySubclass( selector, context ) { - return new jQuerySubclass.fn.init( selector, context ); - } - jQuery.extend( true, jQuerySubclass, this ); - jQuerySubclass.superclass = this; - jQuerySubclass.fn = jQuerySubclass.prototype = this(); - jQuerySubclass.fn.constructor = jQuerySubclass; - jQuerySubclass.subclass = this.subclass; - jQuerySubclass.fn.init = function init( selector, context ) { - if ( context && context instanceof jQuery && !(context instanceof jQuerySubclass) ) { - context = jQuerySubclass(context); - } - - return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass ); - }; - jQuerySubclass.fn.init.prototype = jQuerySubclass.fn; - var rootjQuerySubclass = jQuerySubclass(document); - return jQuerySubclass; - }, - - browser: {} -}); - -// Create readyList deferred -readyList = jQuery._Deferred(); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -browserMatch = jQuery.uaMatch( userAgent ); -if ( browserMatch.browser ) { - jQuery.browser[ browserMatch.browser ] = true; - jQuery.browser.version = browserMatch.version; -} - -// Deprecated, use jQuery.browser.webkit instead -if ( jQuery.browser.webkit ) { - jQuery.browser.safari = true; -} - -if ( indexOf ) { - jQuery.inArray = function( elem, array ) { - return indexOf.call( array, elem ); - }; -} - -// IE doesn't match non-breaking spaces with \s -if ( rnotwhite.test( "\xA0" ) ) { - trimLeft = /^[\s\xA0]+/; - trimRight = /[\s\xA0]+$/; -} - -// All jQuery objects should point back to these -rootjQuery = jQuery(document); - -// Cleanup functions for the document ready method -if ( document.addEventListener ) { - DOMContentLoaded = function() { - document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - jQuery.ready(); - }; - -} else if ( document.attachEvent ) { - DOMContentLoaded = function() { - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( document.readyState === "complete" ) { - document.detachEvent( "onreadystatechange", DOMContentLoaded ); - jQuery.ready(); - } - }; -} - -// The DOM ready check for Internet Explorer -function doScrollCheck() { - if ( jQuery.isReady ) { - return; - } - - try { - // If IE is used, use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - document.documentElement.doScroll("left"); - } catch(e) { - setTimeout( doScrollCheck, 1 ); - return; - } - - // and execute any waiting functions - jQuery.ready(); -} - -// Expose jQuery to the global object -return jQuery; - -})(); - - -(function() { - - jQuery.support = {}; - - var div = document.createElement("div"); - - div.style.display = "none"; - div.innerHTML = "
a"; - - var all = div.getElementsByTagName("*"), - a = div.getElementsByTagName("a")[0], - select = document.createElement("select"), - opt = select.appendChild( document.createElement("option") ), - input = div.getElementsByTagName("input")[0]; - - // Can't get basic test support - if ( !all || !all.length || !a ) { - return; - } - - jQuery.support = { - // IE strips leading whitespace when .innerHTML is used - leadingWhitespace: div.firstChild.nodeType === 3, - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - tbody: !div.getElementsByTagName("tbody").length, - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - htmlSerialize: !!div.getElementsByTagName("link").length, - - // Get the style information from getAttribute - // (IE uses .cssText insted) - style: /red/.test( a.getAttribute("style") ), - - // Make sure that URLs aren't manipulated - // (IE normalizes it by default) - hrefNormalized: a.getAttribute("href") === "/a", - - // Make sure that element opacity exists - // (IE uses filter instead) - // Use a regex to work around a WebKit issue. See #5145 - opacity: /^0.55$/.test( a.style.opacity ), - - // Verify style float existence - // (IE uses styleFloat instead of cssFloat) - cssFloat: !!a.style.cssFloat, - - // Make sure that if no value is specified for a checkbox - // that it defaults to "on". - // (WebKit defaults to "" instead) - checkOn: input.value === "on", - - // Make sure that a selected-by-default option has a working selected property. - // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) - optSelected: opt.selected, - - // Will be defined later - deleteExpando: true, - optDisabled: false, - checkClone: false, - noCloneEvent: true, - noCloneChecked: true, - boxModel: null, - inlineBlockNeedsLayout: false, - shrinkWrapBlocks: false, - reliableHiddenOffsets: true - }; - - input.checked = true; - jQuery.support.noCloneChecked = input.cloneNode( true ).checked; - - // Make sure that the options inside disabled selects aren't marked as disabled - // (WebKit marks them as diabled) - select.disabled = true; - jQuery.support.optDisabled = !opt.disabled; - - var _scriptEval = null; - jQuery.support.scriptEval = function() { - if ( _scriptEval === null ) { - var root = document.documentElement, - script = document.createElement("script"), - id = "script" + jQuery.now(); - - try { - script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); - } catch(e) {} - - root.insertBefore( script, root.firstChild ); - - // Make sure that the execution of code works by injecting a script - // tag with appendChild/createTextNode - // (IE doesn't support this, fails, and uses .text instead) - if ( window[ id ] ) { - _scriptEval = true; - delete window[ id ]; - } else { - _scriptEval = false; - } - - root.removeChild( script ); - // release memory in IE - root = script = id = null; - } - - return _scriptEval; - }; - - // Test to see if it's possible to delete an expando from an element - // Fails in Internet Explorer - try { - delete div.test; - - } catch(e) { - jQuery.support.deleteExpando = false; - } - - if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { - div.attachEvent("onclick", function click() { - // Cloning a node shouldn't copy over any - // bound event handlers (IE does this) - jQuery.support.noCloneEvent = false; - div.detachEvent("onclick", click); - }); - div.cloneNode(true).fireEvent("onclick"); - } - - div = document.createElement("div"); - div.innerHTML = ""; - - var fragment = document.createDocumentFragment(); - fragment.appendChild( div.firstChild ); - - // WebKit doesn't clone checked state correctly in fragments - jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; - - // Figure out if the W3C box model works as expected - // document.body must exist before we can do this - jQuery(function() { - var div = document.createElement("div"), - body = document.getElementsByTagName("body")[0]; - - // Frameset documents with no body should not run this code - if ( !body ) { - return; - } - - div.style.width = div.style.paddingLeft = "1px"; - body.appendChild( div ); - jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; - - if ( "zoom" in div.style ) { - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - // (IE < 8 does this) - div.style.display = "inline"; - div.style.zoom = 1; - jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2; - - // Check if elements with layout shrink-wrap their children - // (IE 6 does this) - div.style.display = ""; - div.innerHTML = "
"; - jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2; - } - - div.innerHTML = "
t
"; - var tds = div.getElementsByTagName("td"); - - // Check if table cells still have offsetWidth/Height when they are set - // to display:none and there are still other visible table cells in a - // table row; if so, offsetWidth/Height are not reliable for use when - // determining if an element has been hidden directly using - // display:none (it is still safe to use offsets if a parent element is - // hidden; don safety goggles and see bug #4512 for more information). - // (only IE 8 fails this test) - jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0; - - tds[0].style.display = ""; - tds[1].style.display = "none"; - - // Check if empty table cells still have offsetWidth/Height - // (IE < 8 fail this test) - jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0; - div.innerHTML = ""; - - body.removeChild( div ).style.display = "none"; - div = tds = null; - }); - - // Technique from Juriy Zaytsev - // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ - var eventSupported = function( eventName ) { - var el = document.createElement("div"); - eventName = "on" + eventName; - - // We only care about the case where non-standard event systems - // are used, namely in IE. Short-circuiting here helps us to - // avoid an eval call (in setAttribute) which can cause CSP - // to go haywire. See: https://developer.mozilla.org/en/Security/CSP - if ( !el.attachEvent ) { - return true; - } - - var isSupported = (eventName in el); - if ( !isSupported ) { - el.setAttribute(eventName, "return;"); - isSupported = typeof el[eventName] === "function"; - } - el = null; - - return isSupported; - }; - - jQuery.support.submitBubbles = eventSupported("submit"); - jQuery.support.changeBubbles = eventSupported("change"); - - // release memory in IE - div = all = a = null; -})(); - - - -var rbrace = /^(?:\{.*\}|\[.*\])$/; - -jQuery.extend({ - cache: {}, - - // Please use with caution - uuid: 0, - - // Unique for each copy of jQuery on the page - // Non-digits removed to match rinlinejQuery - expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), - - // The following elements throw uncatchable exceptions if you - // attempt to add expando properties to them. - noData: { - "embed": true, - // Ban all objects except for Flash (which handle expandos) - "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", - "applet": true - }, - - hasData: function( elem ) { - elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - - return !!elem && !isEmptyDataObject( elem ); - }, - - data: function( elem, name, data, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache, - - // We have to handle DOM nodes and JS objects differently because IE6-7 - // can't GC object references properly across the DOM-JS boundary - isNode = elem.nodeType, - - // Only DOM nodes need the global jQuery cache; JS object data is - // attached directly to the object so GC can occur automatically - cache = isNode ? jQuery.cache : elem, - - // Only defining an ID for JS objects if its cache already exists allows - // the code to shortcut on the same path as a DOM node with no cache - id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando; - - // Avoid doing any more work than we need to when trying to get data on an - // object that has no data at all - if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) { - return; - } - - if ( !id ) { - // Only DOM nodes need a new unique ID for each element since their data - // ends up in the global cache - if ( isNode ) { - elem[ jQuery.expando ] = id = ++jQuery.uuid; - } else { - id = jQuery.expando; - } - } - - if ( !cache[ id ] ) { - cache[ id ] = {}; - - // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery - // metadata on plain JS objects when the object is serialized using - // JSON.stringify - if ( !isNode ) { - cache[ id ].toJSON = jQuery.noop; - } - } - - // An object can be passed to jQuery.data instead of a key/value pair; this gets - // shallow copied over onto the existing cache - if ( typeof name === "object" || typeof name === "function" ) { - if ( pvt ) { - cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); - } else { - cache[ id ] = jQuery.extend(cache[ id ], name); - } - } - - thisCache = cache[ id ]; - - // Internal jQuery data is stored in a separate object inside the object's data - // cache in order to avoid key collisions between internal data and user-defined - // data - if ( pvt ) { - if ( !thisCache[ internalKey ] ) { - thisCache[ internalKey ] = {}; - } - - thisCache = thisCache[ internalKey ]; - } - - if ( data !== undefined ) { - thisCache[ name ] = data; - } - - // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should - // not attempt to inspect the internal events object using jQuery.data, as this - // internal data object is undocumented and subject to change. - if ( name === "events" && !thisCache[name] ) { - return thisCache[ internalKey ] && thisCache[ internalKey ].events; - } - - return getByName ? thisCache[ name ] : thisCache; - }, - - removeData: function( elem, name, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var internalKey = jQuery.expando, isNode = elem.nodeType, - - // See jQuery.data for more information - cache = isNode ? jQuery.cache : elem, - - // See jQuery.data for more information - id = isNode ? elem[ jQuery.expando ] : jQuery.expando; - - // If there is already no cache entry for this object, there is no - // purpose in continuing - if ( !cache[ id ] ) { - return; - } - - if ( name ) { - var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ]; - - if ( thisCache ) { - delete thisCache[ name ]; - - // If there is no data left in the cache, we want to continue - // and let the cache object itself get destroyed - if ( !isEmptyDataObject(thisCache) ) { - return; - } - } - } - - // See jQuery.data for more information - if ( pvt ) { - delete cache[ id ][ internalKey ]; - - // Don't destroy the parent cache unless the internal data object - // had been the only thing left in it - if ( !isEmptyDataObject(cache[ id ]) ) { - return; - } - } - - var internalCache = cache[ id ][ internalKey ]; - - // Browsers that fail expando deletion also refuse to delete expandos on - // the window, but it will allow it on all other JS objects; other browsers - // don't care - if ( jQuery.support.deleteExpando || cache != window ) { - delete cache[ id ]; - } else { - cache[ id ] = null; - } - - // We destroyed the entire user cache at once because it's faster than - // iterating through each key, but we need to continue to persist internal - // data if it existed - if ( internalCache ) { - cache[ id ] = {}; - // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery - // metadata on plain JS objects when the object is serialized using - // JSON.stringify - if ( !isNode ) { - cache[ id ].toJSON = jQuery.noop; - } - - cache[ id ][ internalKey ] = internalCache; - - // Otherwise, we need to eliminate the expando on the node to avoid - // false lookups in the cache for entries that no longer exist - } else if ( isNode ) { - // IE does not allow us to delete expando properties from nodes, - // nor does it have a removeAttribute function on Document nodes; - // we must handle all of these cases - if ( jQuery.support.deleteExpando ) { - delete elem[ jQuery.expando ]; - } else if ( elem.removeAttribute ) { - elem.removeAttribute( jQuery.expando ); - } else { - elem[ jQuery.expando ] = null; - } - } - }, - - // For internal use only. - _data: function( elem, name, data ) { - return jQuery.data( elem, name, data, true ); - }, - - // A method for determining if a DOM node can handle the data expando - acceptData: function( elem ) { - if ( elem.nodeName ) { - var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; - - if ( match ) { - return !(match === true || elem.getAttribute("classid") !== match); - } - } - - return true; - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var data = null; - - if ( typeof key === "undefined" ) { - if ( this.length ) { - data = jQuery.data( this[0] ); - - if ( this[0].nodeType === 1 ) { - var attr = this[0].attributes, name; - for ( var i = 0, l = attr.length; i < l; i++ ) { - name = attr[i].name; - - if ( name.indexOf( "data-" ) === 0 ) { - name = name.substr( 5 ); - dataAttr( this[0], name, data[ name ] ); - } - } - } - } - - return data; - - } else if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - var parts = key.split("."); - parts[1] = parts[1] ? "." + parts[1] : ""; - - if ( value === undefined ) { - data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); - - // Try to fetch any internally stored data first - if ( data === undefined && this.length ) { - data = jQuery.data( this[0], key ); - data = dataAttr( this[0], key, data ); - } - - return data === undefined && parts[1] ? - this.data( parts[0] ) : - data; - - } else { - return this.each(function() { - var $this = jQuery( this ), - args = [ parts[0], value ]; - - $this.triggerHandler( "setData" + parts[1] + "!", args ); - jQuery.data( this, key, value ); - $this.triggerHandler( "changeData" + parts[1] + "!", args ); - }); - } - }, - - removeData: function( key ) { - return this.each(function() { - jQuery.removeData( this, key ); - }); - } -}); - -function dataAttr( elem, key, data ) { - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - data = elem.getAttribute( "data-" + key ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - !jQuery.isNaN( data ) ? parseFloat( data ) : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - jQuery.data( elem, key, data ); - - } else { - data = undefined; - } - } - - return data; -} - -// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON -// property to be considered empty objects; this property always exists in -// order to make sure JSON.stringify does not expose internal metadata -function isEmptyDataObject( obj ) { - for ( var name in obj ) { - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} - - - - -jQuery.extend({ - queue: function( elem, type, data ) { - if ( !elem ) { - return; - } - - type = (type || "fx") + "queue"; - var q = jQuery._data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( !data ) { - return q || []; - } - - if ( !q || jQuery.isArray(data) ) { - q = jQuery._data( elem, type, jQuery.makeArray(data) ); - - } else { - q.push( data ); - } - - return q; - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - fn = queue.shift(); - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - } - - if ( fn ) { - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift("inprogress"); - } - - fn.call(elem, function() { - jQuery.dequeue(elem, type); - }); - } - - if ( !queue.length ) { - jQuery.removeData( elem, type + "queue", true ); - } - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - } - - if ( data === undefined ) { - return jQuery.queue( this[0], type ); - } - return this.each(function( i ) { - var queue = jQuery.queue( this, type, data ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - - // Based off of the plugin by Clint Helfers, with permission. - // http://blindsignals.com/index.php/2009/07/jquery-delay/ - delay: function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; - type = type || "fx"; - - return this.queue( type, function() { - var elem = this; - setTimeout(function() { - jQuery.dequeue( elem, type ); - }, time ); - }); - }, - - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - } -}); - - - - -var rclass = /[\n\t\r]/g, - rspaces = /\s+/, - rreturn = /\r/g, - rspecialurl = /^(?:href|src|style)$/, - rtype = /^(?:button|input)$/i, - rfocusable = /^(?:button|input|object|select|textarea)$/i, - rclickable = /^a(?:rea)?$/i, - rradiocheck = /^(?:radio|checkbox)$/i; - -jQuery.props = { - "for": "htmlFor", - "class": "className", - readonly: "readOnly", - maxlength: "maxLength", - cellspacing: "cellSpacing", - rowspan: "rowSpan", - colspan: "colSpan", - tabindex: "tabIndex", - usemap: "useMap", - frameborder: "frameBorder" -}; - -jQuery.fn.extend({ - attr: function( name, value ) { - return jQuery.access( this, name, value, true, jQuery.attr ); - }, - - removeAttr: function( name, fn ) { - return this.each(function(){ - jQuery.attr( this, name, "" ); - if ( this.nodeType === 1 ) { - this.removeAttribute( name ); - } - }); - }, - - addClass: function( value ) { - if ( jQuery.isFunction(value) ) { - return this.each(function(i) { - var self = jQuery(this); - self.addClass( value.call(this, i, self.attr("class")) ); - }); - } - - if ( value && typeof value === "string" ) { - var classNames = (value || "").split( rspaces ); - - for ( var i = 0, l = this.length; i < l; i++ ) { - var elem = this[i]; - - if ( elem.nodeType === 1 ) { - if ( !elem.className ) { - elem.className = value; - - } else { - var className = " " + elem.className + " ", - setClass = elem.className; - - for ( var c = 0, cl = classNames.length; c < cl; c++ ) { - if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { - setClass += " " + classNames[c]; - } - } - elem.className = jQuery.trim( setClass ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - if ( jQuery.isFunction(value) ) { - return this.each(function(i) { - var self = jQuery(this); - self.removeClass( value.call(this, i, self.attr("class")) ); - }); - } - - if ( (value && typeof value === "string") || value === undefined ) { - var classNames = (value || "").split( rspaces ); - - for ( var i = 0, l = this.length; i < l; i++ ) { - var elem = this[i]; - - if ( elem.nodeType === 1 && elem.className ) { - if ( value ) { - var className = (" " + elem.className + " ").replace(rclass, " "); - for ( var c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[c] + " ", " "); - } - elem.className = jQuery.trim( className ); - - } else { - elem.className = ""; - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value, - isBool = typeof stateVal === "boolean"; - - if ( jQuery.isFunction( value ) ) { - return this.each(function(i) { - var self = jQuery(this); - self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); - }); - } - - return this.each(function() { - if ( type === "string" ) { - // toggle individual class names - var className, - i = 0, - self = jQuery( this ), - state = stateVal, - classNames = value.split( rspaces ); - - while ( (className = classNames[ i++ ]) ) { - // check each className given, space seperated list - state = isBool ? state : !self.hasClass( className ); - self[ state ? "addClass" : "removeClass" ]( className ); - } - - } else if ( type === "undefined" || type === "boolean" ) { - if ( this.className ) { - // store className if set - jQuery._data( this, "__className__", this.className ); - } - - // toggle whole className - this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; - } - }); - }, - - hasClass: function( selector ) { - var className = " " + selector + " "; - for ( var i = 0, l = this.length; i < l; i++ ) { - if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { - return true; - } - } - - return false; - }, - - val: function( value ) { - if ( !arguments.length ) { - var elem = this[0]; - - if ( elem ) { - if ( jQuery.nodeName( elem, "option" ) ) { - // attributes.value is undefined in Blackberry 4.7 but - // uses .value. See #6932 - var val = elem.attributes.value; - return !val || val.specified ? elem.value : elem.text; - } - - // We need to handle select boxes special - if ( jQuery.nodeName( elem, "select" ) ) { - var index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - // Don't return options that are disabled or in a disabled optgroup - if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && - (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { - - // Get the specific value for the option - value = jQuery(option).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - // Fixes Bug #2551 -- select.val() broken in IE after form.reset() - if ( one && !values.length && options.length ) { - return jQuery( options[ index ] ).val(); - } - - return values; - } - - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { - return elem.getAttribute("value") === null ? "on" : elem.value; - } - - // Everything else, we just grab the value - return (elem.value || "").replace(rreturn, ""); - - } - - return undefined; - } - - var isFunction = jQuery.isFunction(value); - - return this.each(function(i) { - var self = jQuery(this), val = value; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call(this, i, self.val()); - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - } else if ( typeof val === "number" ) { - val += ""; - } else if ( jQuery.isArray(val) ) { - val = jQuery.map(val, function (value) { - return value == null ? "" : value + ""; - }); - } - - if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { - this.checked = jQuery.inArray( self.val(), val ) >= 0; - - } else if ( jQuery.nodeName( this, "select" ) ) { - var values = jQuery.makeArray(val); - - jQuery( "option", this ).each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - this.selectedIndex = -1; - } - - } else { - this.value = val; - } - }); - } -}); - -jQuery.extend({ - attrFn: { - val: true, - css: true, - html: true, - text: true, - data: true, - width: true, - height: true, - offset: true - }, - - attr: function( elem, name, value, pass ) { - // don't get/set attributes on text, comment and attribute nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) { - return undefined; - } - - if ( pass && name in jQuery.attrFn ) { - return jQuery(elem)[name](value); - } - - var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), - // Whether we are setting (or getting) - set = value !== undefined; - - // Try to normalize/fix the name - name = notxml && jQuery.props[ name ] || name; - - // Only do all the following if this is a node (faster for style) - if ( elem.nodeType === 1 ) { - // These attributes require special treatment - var special = rspecialurl.test( name ); - - // Safari mis-reports the default selected property of an option - // Accessing the parent's selectedIndex property fixes it - if ( name === "selected" && !jQuery.support.optSelected ) { - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; - - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - - // If applicable, access the attribute via the DOM 0 way - // 'in' checks fail in Blackberry 4.7 #6931 - if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) { - if ( set ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } - - if ( value === null ) { - if ( elem.nodeType === 1 ) { - elem.removeAttribute( name ); - } - - } else { - elem[ name ] = value; - } - } - - // browsers index elements by id/name on forms, give priority to attributes. - if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { - return elem.getAttributeNode( name ).nodeValue; - } - - // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - if ( name === "tabIndex" ) { - var attributeNode = elem.getAttributeNode( "tabIndex" ); - - return attributeNode && attributeNode.specified ? - attributeNode.value : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - - return elem[ name ]; - } - - if ( !jQuery.support.style && notxml && name === "style" ) { - if ( set ) { - elem.style.cssText = "" + value; - } - - return elem.style.cssText; - } - - if ( set ) { - // convert the value to a string (all browsers do this but IE) see #1070 - elem.setAttribute( name, "" + value ); - } - - // Ensure that missing attributes return undefined - // Blackberry 4.7 returns "" from getAttribute #6938 - if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) { - return undefined; - } - - var attr = !jQuery.support.hrefNormalized && notxml && special ? - // Some attributes require a special call on IE - elem.getAttribute( name, 2 ) : - elem.getAttribute( name ); - - // Non-existent attributes return null, we normalize to undefined - return attr === null ? undefined : attr; - } - // Handle everything which isn't a DOM element node - if ( set ) { - elem[ name ] = value; - } - return elem[ name ]; - } -}); - - - - -var rnamespaces = /\.(.*)$/, - rformElems = /^(?:textarea|input|select)$/i, - rperiod = /\./g, - rspace = / /g, - rescape = /[^\w\s.|`]/g, - fcleanup = function( nm ) { - return nm.replace(rescape, "\\$&"); - }; - -/* - * A number of helper functions used for managing events. - * Many of the ideas behind this code originated from - * Dean Edwards' addEvent library. - */ -jQuery.event = { - - // Bind an event to an element - // Original by Dean Edwards - add: function( elem, types, handler, data ) { - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // TODO :: Use a try/catch until it's safe to pull this out (likely 1.6) - // Minor release fix for bug #8018 - try { - // For whatever reason, IE has trouble passing the window object - // around, causing it to be cloned in the process - if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { - elem = window; - } - } - catch ( e ) {} - - if ( handler === false ) { - handler = returnFalse; - } else if ( !handler ) { - // Fixes bug #7229. Fix recommended by jdalton - return; - } - - var handleObjIn, handleObj; - - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - } - - // Make sure that the function being executed has a unique ID - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure - var elemData = jQuery._data( elem ); - - // If no elemData is found then we must be trying to bind to one of the - // banned noData elements - if ( !elemData ) { - return; - } - - var events = elemData.events, - eventHandle = elemData.handle; - - if ( !events ) { - elemData.events = events = {}; - } - - if ( !eventHandle ) { - elemData.handle = eventHandle = function() { - // Handle the second event of a trigger and when - // an event is called after a page has unloaded - return typeof jQuery !== "undefined" && !jQuery.event.triggered ? - jQuery.event.handle.apply( eventHandle.elem, arguments ) : - undefined; - }; - } - - // Add elem as a property of the handle function - // This is to prevent a memory leak with non-native events in IE. - eventHandle.elem = elem; - - // Handle multiple events separated by a space - // jQuery(...).bind("mouseover mouseout", fn); - types = types.split(" "); - - var type, i = 0, namespaces; - - while ( (type = types[ i++ ]) ) { - handleObj = handleObjIn ? - jQuery.extend({}, handleObjIn) : - { handler: handler, data: data }; - - // Namespaced event handlers - if ( type.indexOf(".") > -1 ) { - namespaces = type.split("."); - type = namespaces.shift(); - handleObj.namespace = namespaces.slice(0).sort().join("."); - - } else { - namespaces = []; - handleObj.namespace = ""; - } - - handleObj.type = type; - if ( !handleObj.guid ) { - handleObj.guid = handler.guid; - } - - // Get the current list of functions bound to this event - var handlers = events[ type ], - special = jQuery.event.special[ type ] || {}; - - // Init the event handler queue - if ( !handlers ) { - handlers = events[ type ] = []; - - // Check for a special event handler - // Only use addEventListener/attachEvent if the special - // events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - // Bind the global event handler to the element - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add the function to the element's handler list - handlers.push( handleObj ); - - // Keep track of which events have been used, for global triggering - jQuery.event.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - global: {}, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, pos ) { - // don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - if ( handler === false ) { - handler = returnFalse; - } - - var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, - elemData = jQuery.hasData( elem ) && jQuery._data( elem ), - events = elemData && elemData.events; - - if ( !elemData || !events ) { - return; - } - - // types is actually an event object here - if ( types && types.type ) { - handler = types.handler; - types = types.type; - } - - // Unbind all events for the element - if ( !types || typeof types === "string" && types.charAt(0) === "." ) { - types = types || ""; - - for ( type in events ) { - jQuery.event.remove( elem, type + types ); - } - - return; - } - - // Handle multiple events separated by a space - // jQuery(...).unbind("mouseover mouseout", fn); - types = types.split(" "); - - while ( (type = types[ i++ ]) ) { - origType = type; - handleObj = null; - all = type.indexOf(".") < 0; - namespaces = []; - - if ( !all ) { - // Namespaced event handlers - namespaces = type.split("."); - type = namespaces.shift(); - - namespace = new RegExp("(^|\\.)" + - jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); - } - - eventType = events[ type ]; - - if ( !eventType ) { - continue; - } - - if ( !handler ) { - for ( j = 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; - - if ( all || namespace.test( handleObj.namespace ) ) { - jQuery.event.remove( elem, origType, handleObj.handler, j ); - eventType.splice( j--, 1 ); - } - } - - continue; - } - - special = jQuery.event.special[ type ] || {}; - - for ( j = pos || 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; - - if ( handler.guid === handleObj.guid ) { - // remove the given handler for the given type - if ( all || namespace.test( handleObj.namespace ) ) { - if ( pos == null ) { - eventType.splice( j--, 1 ); - } - - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - - if ( pos != null ) { - break; - } - } - } - - // remove generic event handler if no more handlers exist - if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { - if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - ret = null; - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - var handle = elemData.handle; - if ( handle ) { - handle.elem = null; - } - - delete elemData.events; - delete elemData.handle; - - if ( jQuery.isEmptyObject( elemData ) ) { - jQuery.removeData( elem, undefined, true ); - } - } - }, - - // bubbling is internal - trigger: function( event, data, elem /*, bubbling */ ) { - // Event object or event type - var type = event.type || event, - bubbling = arguments[3]; - - if ( !bubbling ) { - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - jQuery.extend( jQuery.Event(type), event ) : - // Just the event type (string) - jQuery.Event(type); - - if ( type.indexOf("!") >= 0 ) { - event.type = type = type.slice(0, -1); - event.exclusive = true; - } - - // Handle a global trigger - if ( !elem ) { - // Don't bubble custom events when global (to avoid too much overhead) - event.stopPropagation(); - - // Only trigger if we've ever bound an event for it - if ( jQuery.event.global[ type ] ) { - // XXX This code smells terrible. event.js should not be directly - // inspecting the data cache - jQuery.each( jQuery.cache, function() { - // internalKey variable is just used to make it easier to find - // and potentially change this stuff later; currently it just - // points to jQuery.expando - var internalKey = jQuery.expando, - internalCache = this[ internalKey ]; - if ( internalCache && internalCache.events && internalCache.events[ type ] ) { - jQuery.event.trigger( event, data, internalCache.handle.elem ); - } - }); - } - } - - // Handle triggering a single element - - // don't do events on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { - return undefined; - } - - // Clean up in case it is reused - event.result = undefined; - event.target = elem; - - // Clone the incoming data, if any - data = jQuery.makeArray( data ); - data.unshift( event ); - } - - event.currentTarget = elem; - - // Trigger the event, it is assumed that "handle" is a function - var handle = jQuery._data( elem, "handle" ); - - if ( handle ) { - handle.apply( elem, data ); - } - - var parent = elem.parentNode || elem.ownerDocument; - - // Trigger an inline bound script - try { - if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { - if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { - event.result = false; - event.preventDefault(); - } - } - - // prevent IE from throwing an error for some elements with some event types, see #3533 - } catch (inlineError) {} - - if ( !event.isPropagationStopped() && parent ) { - jQuery.event.trigger( event, data, parent, true ); - - } else if ( !event.isDefaultPrevented() ) { - var old, - target = event.target, - targetType = type.replace( rnamespaces, "" ), - isClick = jQuery.nodeName( target, "a" ) && targetType === "click", - special = jQuery.event.special[ targetType ] || {}; - - if ( (!special._default || special._default.call( elem, event ) === false) && - !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { - - try { - if ( target[ targetType ] ) { - // Make sure that we don't accidentally re-trigger the onFOO events - old = target[ "on" + targetType ]; - - if ( old ) { - target[ "on" + targetType ] = null; - } - - jQuery.event.triggered = true; - target[ targetType ](); - } - - // prevent IE from throwing an error for some elements with some event types, see #3533 - } catch (triggerError) {} - - if ( old ) { - target[ "on" + targetType ] = old; - } - - jQuery.event.triggered = false; - } - } - }, - - handle: function( event ) { - var all, handlers, namespaces, namespace_re, events, - namespace_sort = [], - args = jQuery.makeArray( arguments ); - - event = args[0] = jQuery.event.fix( event || window.event ); - event.currentTarget = this; - - // Namespaced event handlers - all = event.type.indexOf(".") < 0 && !event.exclusive; - - if ( !all ) { - namespaces = event.type.split("."); - event.type = namespaces.shift(); - namespace_sort = namespaces.slice(0).sort(); - namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)"); - } - - event.namespace = event.namespace || namespace_sort.join("."); - - events = jQuery._data(this, "events"); - - handlers = (events || {})[ event.type ]; - - if ( events && handlers ) { - // Clone the handlers to prevent manipulation - handlers = handlers.slice(0); - - for ( var j = 0, l = handlers.length; j < l; j++ ) { - var handleObj = handlers[ j ]; - - // Filter the functions by class - if ( all || namespace_re.test( handleObj.namespace ) ) { - // Pass in a reference to the handler function itself - // So that we can later remove it - event.handler = handleObj.handler; - event.data = handleObj.data; - event.handleObj = handleObj; - - var ret = handleObj.handler.apply( this, args ); - - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - - if ( event.isImmediatePropagationStopped() ) { - break; - } - } - } - } - - return event.result; - }, - - props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // store a copy of the original event object - // and "clone" to set read-only properties - var originalEvent = event; - event = jQuery.Event( originalEvent ); - - for ( var i = this.props.length, prop; i; ) { - prop = this.props[ --i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Fix target property, if necessary - if ( !event.target ) { - // Fixes #1925 where srcElement might not be defined either - event.target = event.srcElement || document; - } - - // check if target is a textnode (safari) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && event.fromElement ) { - event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; - } - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && event.clientX != null ) { - var doc = document.documentElement, - body = document.body; - - event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); - event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); - } - - // Add which for key events - if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { - event.which = event.charCode != null ? event.charCode : event.keyCode; - } - - // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) - if ( !event.metaKey && event.ctrlKey ) { - event.metaKey = event.ctrlKey; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && event.button !== undefined ) { - event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); - } - - return event; - }, - - // Deprecated, use jQuery.guid instead - guid: 1E8, - - // Deprecated, use jQuery.proxy instead - proxy: jQuery.proxy, - - special: { - ready: { - // Make sure the ready event is setup - setup: jQuery.bindReady, - teardown: jQuery.noop - }, - - live: { - add: function( handleObj ) { - jQuery.event.add( this, - liveConvert( handleObj.origType, handleObj.selector ), - jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); - }, - - remove: function( handleObj ) { - jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj ); - } - }, - - beforeunload: { - setup: function( data, namespaces, eventHandle ) { - // We only want to do this special case on windows - if ( jQuery.isWindow( this ) ) { - this.onbeforeunload = eventHandle; - } - }, - - teardown: function( namespaces, eventHandle ) { - if ( this.onbeforeunload === eventHandle ) { - this.onbeforeunload = null; - } - } - } - } -}; - -jQuery.removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } - } : - function( elem, type, handle ) { - if ( elem.detachEvent ) { - elem.detachEvent( "on" + type, handle ); - } - }; - -jQuery.Event = function( src ) { - // Allow instantiation without the 'new' keyword - if ( !this.preventDefault ) { - return new jQuery.Event( src ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || - src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; - - // Event type - } else { - this.type = src; - } - - // timeStamp is buggy for some events on Firefox(#3843) - // So we won't rely on the native value - this.timeStamp = jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -function returnFalse() { - return false; -} -function returnTrue() { - return true; -} - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - - // if preventDefault exists run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - - // otherwise set the returnValue property of the original event to false (IE) - } else { - e.returnValue = false; - } - }, - stopPropagation: function() { - this.isPropagationStopped = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - // if stopPropagation exists run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - // otherwise set the cancelBubble property of the original event to true (IE) - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse -}; - -// Checks if an event happened on an element within another element -// Used in jQuery.event.special.mouseenter and mouseleave handlers -var withinElement = function( event ) { - // Check if mouse(over|out) are still within the same parent element - var parent = event.relatedTarget; - - // Firefox sometimes assigns relatedTarget a XUL element - // which we cannot access the parentNode property of - try { - - // Chrome does something similar, the parentNode property - // can be accessed but is null. - if ( parent !== document && !parent.parentNode ) { - return; - } - // Traverse up the tree - while ( parent && parent !== this ) { - parent = parent.parentNode; - } - - if ( parent !== this ) { - // set the correct event type - event.type = event.data; - - // handle event if we actually just moused on to a non sub-element - jQuery.event.handle.apply( this, arguments ); - } - - // assuming we've left the element since we most likely mousedover a xul element - } catch(e) { } -}, - -// In case of event delegation, we only need to rename the event.type, -// liveHandler will take care of the rest. -delegate = function( event ) { - event.type = event.data; - jQuery.event.handle.apply( this, arguments ); -}; - -// Create mouseenter and mouseleave events -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - setup: function( data ) { - jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); - }, - teardown: function( data ) { - jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); - } - }; -}); - -// submit delegation -if ( !jQuery.support.submitBubbles ) { - - jQuery.event.special.submit = { - setup: function( data, namespaces ) { - if ( this.nodeName && this.nodeName.toLowerCase() !== "form" ) { - jQuery.event.add(this, "click.specialSubmit", function( e ) { - var elem = e.target, - type = elem.type; - - if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { - trigger( "submit", this, arguments ); - } - }); - - jQuery.event.add(this, "keypress.specialSubmit", function( e ) { - var elem = e.target, - type = elem.type; - - if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { - trigger( "submit", this, arguments ); - } - }); - - } else { - return false; - } - }, - - teardown: function( namespaces ) { - jQuery.event.remove( this, ".specialSubmit" ); - } - }; - -} - -// change delegation, happens here so we have bind. -if ( !jQuery.support.changeBubbles ) { - - var changeFilters, - - getVal = function( elem ) { - var type = elem.type, val = elem.value; - - if ( type === "radio" || type === "checkbox" ) { - val = elem.checked; - - } else if ( type === "select-multiple" ) { - val = elem.selectedIndex > -1 ? - jQuery.map( elem.options, function( elem ) { - return elem.selected; - }).join("-") : - ""; - - } else if ( elem.nodeName.toLowerCase() === "select" ) { - val = elem.selectedIndex; - } - - return val; - }, - - testChange = function testChange( e ) { - var elem = e.target, data, val; - - if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) { - return; - } - - data = jQuery._data( elem, "_change_data" ); - val = getVal(elem); - - // the current data will be also retrieved by beforeactivate - if ( e.type !== "focusout" || elem.type !== "radio" ) { - jQuery._data( elem, "_change_data", val ); - } - - if ( data === undefined || val === data ) { - return; - } - - if ( data != null || val ) { - e.type = "change"; - e.liveFired = undefined; - jQuery.event.trigger( e, arguments[1], elem ); - } - }; - - jQuery.event.special.change = { - filters: { - focusout: testChange, - - beforedeactivate: testChange, - - click: function( e ) { - var elem = e.target, type = elem.type; - - if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { - testChange.call( this, e ); - } - }, - - // Change has to be called before submit - // Keydown will be called before keypress, which is used in submit-event delegation - keydown: function( e ) { - var elem = e.target, type = elem.type; - - if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || - (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || - type === "select-multiple" ) { - testChange.call( this, e ); - } - }, - - // Beforeactivate happens also before the previous element is blurred - // with this event you can't trigger a change event, but you can store - // information - beforeactivate: function( e ) { - var elem = e.target; - jQuery._data( elem, "_change_data", getVal(elem) ); - } - }, - - setup: function( data, namespaces ) { - if ( this.type === "file" ) { - return false; - } - - for ( var type in changeFilters ) { - jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); - } - - return rformElems.test( this.nodeName ); - }, - - teardown: function( namespaces ) { - jQuery.event.remove( this, ".specialChange" ); - - return rformElems.test( this.nodeName ); - } - }; - - changeFilters = jQuery.event.special.change.filters; - - // Handle when the input is .focus()'d - changeFilters.focus = changeFilters.beforeactivate; -} - -function trigger( type, elem, args ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - // Don't pass args or remember liveFired; they apply to the donor event. - var event = jQuery.extend( {}, args[ 0 ] ); - event.type = type; - event.originalEvent = {}; - event.liveFired = undefined; - jQuery.event.handle.call( elem, event ); - if ( event.isDefaultPrevented() ) { - args[ 0 ].preventDefault(); - } -} - -// Create "bubbling" focus and blur events -if ( document.addEventListener ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - jQuery.event.special[ fix ] = { - setup: function() { - this.addEventListener( orig, handler, true ); - }, - teardown: function() { - this.removeEventListener( orig, handler, true ); - } - }; - - function handler( e ) { - e = jQuery.event.fix( e ); - e.type = fix; - return jQuery.event.handle.call( this, e ); - } - }); -} - -jQuery.each(["bind", "one"], function( i, name ) { - jQuery.fn[ name ] = function( type, data, fn ) { - // Handle object literals - if ( typeof type === "object" ) { - for ( var key in type ) { - this[ name ](key, data, type[key], fn); - } - return this; - } - - if ( jQuery.isFunction( data ) || data === false ) { - fn = data; - data = undefined; - } - - var handler = name === "one" ? jQuery.proxy( fn, function( event ) { - jQuery( this ).unbind( event, handler ); - return fn.apply( this, arguments ); - }) : fn; - - if ( type === "unload" && name !== "one" ) { - this.one( type, data, fn ); - - } else { - for ( var i = 0, l = this.length; i < l; i++ ) { - jQuery.event.add( this[i], type, handler, data ); - } - } - - return this; - }; -}); - -jQuery.fn.extend({ - unbind: function( type, fn ) { - // Handle object literals - if ( typeof type === "object" && !type.preventDefault ) { - for ( var key in type ) { - this.unbind(key, type[key]); - } - - } else { - for ( var i = 0, l = this.length; i < l; i++ ) { - jQuery.event.remove( this[i], type, fn ); - } - } - - return this; - }, - - delegate: function( selector, types, data, fn ) { - return this.live( types, data, fn, selector ); - }, - - undelegate: function( selector, types, fn ) { - if ( arguments.length === 0 ) { - return this.unbind( "live" ); - - } else { - return this.die( types, null, fn, selector ); - } - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - - triggerHandler: function( type, data ) { - if ( this[0] ) { - var event = jQuery.Event( type ); - event.preventDefault(); - event.stopPropagation(); - jQuery.event.trigger( event, data, this[0] ); - return event.result; - } - }, - - toggle: function( fn ) { - // Save reference to arguments for access in closure - var args = arguments, - i = 1; - - // link all the functions, so any of them can unbind this click handler - while ( i < args.length ) { - jQuery.proxy( fn, args[ i++ ] ); - } - - return this.click( jQuery.proxy( fn, function( event ) { - // Figure out which function to execute - var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; - jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); - - // Make sure that clicks stop - event.preventDefault(); - - // and execute the function - return args[ lastToggle ].apply( this, arguments ) || false; - })); - }, - - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -}); - -var liveMap = { - focus: "focusin", - blur: "focusout", - mouseenter: "mouseover", - mouseleave: "mouseout" -}; - -jQuery.each(["live", "die"], function( i, name ) { - jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { - var type, i = 0, match, namespaces, preType, - selector = origSelector || this.selector, - context = origSelector ? this : jQuery( this.context ); - - if ( typeof types === "object" && !types.preventDefault ) { - for ( var key in types ) { - context[ name ]( key, data, types[key], selector ); - } - - return this; - } - - if ( jQuery.isFunction( data ) ) { - fn = data; - data = undefined; - } - - types = (types || "").split(" "); - - while ( (type = types[ i++ ]) != null ) { - match = rnamespaces.exec( type ); - namespaces = ""; - - if ( match ) { - namespaces = match[0]; - type = type.replace( rnamespaces, "" ); - } - - if ( type === "hover" ) { - types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); - continue; - } - - preType = type; - - if ( type === "focus" || type === "blur" ) { - types.push( liveMap[ type ] + namespaces ); - type = type + namespaces; - - } else { - type = (liveMap[ type ] || type) + namespaces; - } - - if ( name === "live" ) { - // bind live handler - for ( var j = 0, l = context.length; j < l; j++ ) { - jQuery.event.add( context[j], "live." + liveConvert( type, selector ), - { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); - } - - } else { - // unbind live handler - context.unbind( "live." + liveConvert( type, selector ), fn ); - } - } - - return this; - }; -}); - -function liveHandler( event ) { - var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, - elems = [], - selectors = [], - events = jQuery._data( this, "events" ); - - // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) - if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { - return; - } - - if ( event.namespace ) { - namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)"); - } - - event.liveFired = this; - - var live = events.live.slice(0); - - for ( j = 0; j < live.length; j++ ) { - handleObj = live[j]; - - if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { - selectors.push( handleObj.selector ); - - } else { - live.splice( j--, 1 ); - } - } - - match = jQuery( event.target ).closest( selectors, event.currentTarget ); - - for ( i = 0, l = match.length; i < l; i++ ) { - close = match[i]; - - for ( j = 0; j < live.length; j++ ) { - handleObj = live[j]; - - if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) { - elem = close.elem; - related = null; - - // Those two events require additional checking - if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { - event.type = handleObj.preType; - related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; - } - - if ( !related || related !== elem ) { - elems.push({ elem: elem, handleObj: handleObj, level: close.level }); - } - } - } - } - - for ( i = 0, l = elems.length; i < l; i++ ) { - match = elems[i]; - - if ( maxLevel && match.level > maxLevel ) { - break; - } - - event.currentTarget = match.elem; - event.data = match.handleObj.data; - event.handleObj = match.handleObj; - - ret = match.handleObj.origHandler.apply( match.elem, arguments ); - - if ( ret === false || event.isPropagationStopped() ) { - maxLevel = match.level; - - if ( ret === false ) { - stop = false; - } - if ( event.isImmediatePropagationStopped() ) { - break; - } - } - } - - return stop; -} - -function liveConvert( type, selector ) { - return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&"); -} - -jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup error").split(" "), function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - if ( fn == null ) { - fn = data; - data = null; - } - - return arguments.length > 0 ? - this.bind( name, data, fn ) : - this.trigger( name ); - }; - - if ( jQuery.attrFn ) { - jQuery.attrFn[ name ] = true; - } -}); - - -/*! - * Sizzle CSS Selector Engine - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true, - rBackslash = /\\/g, - rNonWord = /\W/; - -// Here we check if the JavaScript engine is using some sort of -// optimization where it does not always call our comparision -// function. If that is the case, discard the hasDuplicate value. -// Thus far that includes Google Chrome. -[0, 0].sort(function() { - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function( selector, context, results, seed ) { - results = results || []; - context = context || document; - - var origContext = context; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var m, set, checkSet, extra, ret, cur, pop, i, - prune = true, - contextXML = Sizzle.isXML( context ), - parts = [], - soFar = selector; - - // Reset the position of the chunker regexp (start from head) - do { - chunker.exec( "" ); - m = chunker.exec( soFar ); - - if ( m ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - } while ( m ); - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context ); - - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) { - selector += parts.shift(); - } - - set = posProcess( selector, set ); - } - } - - } else { - // Take a shortcut and set the context if the root selector is an ID - // (but not if it'll be faster if the inner selector is an ID) - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - - ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? - Sizzle.filter( ret.expr, ret.set )[0] : - ret.set[0]; - } - - if ( context ) { - ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - - set = ret.expr ? - Sizzle.filter( ret.expr, ret.set ) : - ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray( set ); - - } else { - prune = false; - } - - while ( parts.length ) { - cur = parts.pop(); - pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - Sizzle.error( cur || selector ); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - - } else if ( context && context.nodeType === 1 ) { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - - } else { - for ( i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function( results ) { - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort( sortOrder ); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[ i - 1 ] ) { - results.splice( i--, 1 ); - } - } - } - } - - return results; -}; - -Sizzle.matches = function( expr, set ) { - return Sizzle( expr, null, null, set ); -}; - -Sizzle.matchesSelector = function( node, expr ) { - return Sizzle( expr, null, null, [node] ).length > 0; -}; - -Sizzle.find = function( expr, context, isXML ) { - var set; - - if ( !expr ) { - return []; - } - - for ( var i = 0, l = Expr.order.length; i < l; i++ ) { - var match, - type = Expr.order[i]; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - var left = match[1]; - match.splice( 1, 1 ); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace( rBackslash, "" ); - set = Expr.find[ type ]( match, context, isXML ); - - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = typeof context.getElementsByTagName !== "undefined" ? - context.getElementsByTagName( "*" ) : - []; - } - - return { set: set, expr: expr }; -}; - -Sizzle.filter = function( expr, set, inplace, not ) { - var match, anyFound, - old = expr, - result = [], - curLoop = set, - isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); - - while ( expr && set.length ) { - for ( var type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - var found, item, - filter = Expr.filter[ type ], - left = match[1]; - - anyFound = false; - - match.splice(1,1); - - if ( left.substr( left.length - 1 ) === "\\" ) { - continue; - } - - if ( curLoop === result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( var i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - var pass = not ^ !!found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - - } else { - curLoop[i] = false; - } - - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - // Improper expression - if ( expr === old ) { - if ( anyFound == null ) { - Sizzle.error( expr ); - - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -Sizzle.error = function( msg ) { - throw "Syntax error, unrecognized expression: " + msg; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - - match: { - ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ - }, - - leftMatch: {}, - - attrMap: { - "class": "className", - "for": "htmlFor" - }, - - attrHandle: { - href: function( elem ) { - return elem.getAttribute( "href" ); - }, - type: function( elem ) { - return elem.getAttribute( "type" ); - } - }, - - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !rNonWord.test( part ), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag ) { - part = part.toLowerCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - - ">": function( checkSet, part ) { - var elem, - isPartStr = typeof part === "string", - i = 0, - l = checkSet.length; - - if ( isPartStr && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; - } - } - - } else { - for ( ; i < l; i++ ) { - elem = checkSet[i]; - - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - - "": function(checkSet, part, isXML){ - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); - }, - - "~": function( checkSet, part, isXML ) { - var nodeCheck, - doneName = done++, - checkFn = dirCheck; - - if ( typeof part === "string" && !rNonWord.test( part ) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } - - checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); - } - }, - - find: { - ID: function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [m] : []; - } - }, - - NAME: function( match, context ) { - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], - results = context.getElementsByName( match[1] ); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - - TAG: function( match, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( match[1] ); - } - } - }, - preFilter: { - CLASS: function( match, curLoop, inplace, result, not, isXML ) { - match = " " + match[1].replace( rBackslash, "" ) + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { - if ( !inplace ) { - result.push( elem ); - } - - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - - ID: function( match ) { - return match[1].replace( rBackslash, "" ); - }, - - TAG: function( match, curLoop ) { - return match[1].replace( rBackslash, "" ).toLowerCase(); - }, - - CHILD: function( match ) { - if ( match[1] === "nth" ) { - if ( !match[2] ) { - Sizzle.error( match[0] ); - } - - match[2] = match[2].replace(/^\+|\s*/g, ''); - - // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' - var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( - match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - // calculate the numbers (first)n+(last) including if they are negative - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - else if ( match[2] ) { - Sizzle.error( match[0] ); - } - - // TODO: Move to normal caching system - match[0] = done++; - - return match; - }, - - ATTR: function( match, curLoop, inplace, result, not, isXML ) { - var name = match[1] = match[1].replace( rBackslash, "" ); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - // Handle if an un-quoted value was used - match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - - PSEUDO: function( match, curLoop, inplace, result, not ) { - if ( match[1] === "not" ) { - // If we're dealing with a complex expression, or a simple one - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - - if ( !inplace ) { - result.push.apply( result, ret ); - } - - return false; - } - - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - - POS: function( match ) { - match.unshift( true ); - - return match; - } - }, - - filters: { - enabled: function( elem ) { - return elem.disabled === false && elem.type !== "hidden"; - }, - - disabled: function( elem ) { - return elem.disabled === true; - }, - - checked: function( elem ) { - return elem.checked === true; - }, - - selected: function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - parent: function( elem ) { - return !!elem.firstChild; - }, - - empty: function( elem ) { - return !elem.firstChild; - }, - - has: function( elem, i, match ) { - return !!Sizzle( match[3], elem ).length; - }, - - header: function( elem ) { - return (/h\d/i).test( elem.nodeName ); - }, - - text: function( elem ) { - // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) - // use getAttribute instead to test this case - return "text" === elem.getAttribute( 'type' ); - }, - radio: function( elem ) { - return "radio" === elem.type; - }, - - checkbox: function( elem ) { - return "checkbox" === elem.type; - }, - - file: function( elem ) { - return "file" === elem.type; - }, - password: function( elem ) { - return "password" === elem.type; - }, - - submit: function( elem ) { - return "submit" === elem.type; - }, - - image: function( elem ) { - return "image" === elem.type; - }, - - reset: function( elem ) { - return "reset" === elem.type; - }, - - button: function( elem ) { - return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; - }, - - input: function( elem ) { - return (/input|select|textarea|button/i).test( elem.nodeName ); - } - }, - setFilters: { - first: function( elem, i ) { - return i === 0; - }, - - last: function( elem, i, match, array ) { - return i === array.length - 1; - }, - - even: function( elem, i ) { - return i % 2 === 0; - }, - - odd: function( elem, i ) { - return i % 2 === 1; - }, - - lt: function( elem, i, match ) { - return i < match[3] - 0; - }, - - gt: function( elem, i, match ) { - return i > match[3] - 0; - }, - - nth: function( elem, i, match ) { - return match[3] - 0 === i; - }, - - eq: function( elem, i, match ) { - return match[3] - 0 === i; - } - }, - filter: { - PSEUDO: function( elem, match, i, array ) { - var name = match[1], - filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; - - } else if ( name === "not" ) { - var not = match[3]; - - for ( var j = 0, l = not.length; j < l; j++ ) { - if ( not[j] === elem ) { - return false; - } - } - - return true; - - } else { - Sizzle.error( name ); - } - }, - - CHILD: function( elem, match ) { - var type = match[1], - node = elem; - - switch ( type ) { - case "only": - case "first": - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - if ( type === "first" ) { - return true; - } - - node = elem; - - case "last": - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - - return true; - - case "nth": - var first = match[2], - last = match[3]; - - if ( first === 1 && last === 0 ) { - return true; - } - - var doneName = match[0], - parent = elem.parentNode; - - if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { - var count = 0; - - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - - parent.sizcache = doneName; - } - - var diff = elem.nodeIndex - last; - - if ( first === 0 ) { - return diff === 0; - - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } - } - }, - - ID: function( elem, match ) { - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - - TAG: function( elem, match ) { - return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; - }, - - CLASS: function( elem, match ) { - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - - ATTR: function( elem, match ) { - var name = match[1], - result = Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value !== check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - - POS: function( elem, match, i, array ) { - var name = match[2], - filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS, - fescape = function(all, num){ - return "\\" + (num - 0 + 1); - }; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); -} - -var makeArray = function( array, results ) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -// Perform a simple check to determine if the browser is capable of -// converting a NodeList to an array using builtin methods. -// Also verifies that the returned array holds DOM nodes -// (which is not the case in the Blackberry browser) -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; - -// Provide a fallback method if it does not work -} catch( e ) { - makeArray = function( array, results ) { - var i = 0, - ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - - } else { - if ( typeof array.length === "number" ) { - for ( var l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - - } else { - for ( ; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder, siblingCheck; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - return a.compareDocumentPosition ? -1 : 1; - } - - return a.compareDocumentPosition(b) & 4 ? -1 : 1; - }; - -} else { - sortOrder = function( a, b ) { - var al, bl, - ap = [], - bp = [], - aup = a.parentNode, - bup = b.parentNode, - cur = aup; - - // The nodes are identical, we can exit early - if ( a === b ) { - hasDuplicate = true; - return 0; - - // If the nodes are siblings (or identical) we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - - // If no parents were found then the nodes are disconnected - } else if ( !aup ) { - return -1; - - } else if ( !bup ) { - return 1; - } - - // Otherwise they're somewhere else in the tree so we need - // to build up a full list of the parentNodes for comparison - while ( cur ) { - ap.unshift( cur ); - cur = cur.parentNode; - } - - cur = bup; - - while ( cur ) { - bp.unshift( cur ); - cur = cur.parentNode; - } - - al = ap.length; - bl = bp.length; - - // Start walking down the tree looking for a discrepancy - for ( var i = 0; i < al && i < bl; i++ ) { - if ( ap[i] !== bp[i] ) { - return siblingCheck( ap[i], bp[i] ); - } - } - - // We ended someplace up the tree so do a sibling check - return i === al ? - siblingCheck( a, bp[i], -1 ) : - siblingCheck( ap[i], b, 1 ); - }; - - siblingCheck = function( a, b, ret ) { - if ( a === b ) { - return ret; - } - - var cur = a.nextSibling; - - while ( cur ) { - if ( cur === b ) { - return -1; - } - - cur = cur.nextSibling; - } - - return 1; - }; -} - -// Utility function for retreiving the text value of an array of DOM nodes -Sizzle.getText = function( elems ) { - var ret = "", elem; - - for ( var i = 0; elems[i]; i++ ) { - elem = elems[i]; - - // Get the text from text nodes and CDATA nodes - if ( elem.nodeType === 3 || elem.nodeType === 4 ) { - ret += elem.nodeValue; - - // Traverse everything else, except comment nodes - } else if ( elem.nodeType !== 8 ) { - ret += Sizzle.getText( elem.childNodes ); - } - } - - return ret; -}; - -// Check to see if the browser returns elements by name when -// querying by getElementById (and provide a workaround) -(function(){ - // We're going to inject a fake input element with a specified name - var form = document.createElement("div"), - id = "script" + (new Date()).getTime(), - root = document.documentElement; - - form.innerHTML = ""; - - // Inject it into the root element, check its status, and remove it quickly - root.insertBefore( form, root.firstChild ); - - // The workaround has to do additional checks after a getElementById - // Which slows things down for other browsers (hence the branching) - if ( document.getElementById( id ) ) { - Expr.find.ID = function( match, context, isXML ) { - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - - return m ? - m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? - [m] : - undefined : - []; - } - }; - - Expr.filter.ID = function( elem, match ) { - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - } - - root.removeChild( form ); - - // release memory in IE - root = form = null; -})(); - -(function(){ - // Check to see if the browser returns only elements - // when doing getElementsByTagName("*") - - // Create a fake element - var div = document.createElement("div"); - div.appendChild( document.createComment("") ); - - // Make sure no comments are found - if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function( match, context ) { - var results = context.getElementsByTagName( match[1] ); - - // Filter out possible comments - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - } - - // Check to see if an attribute returns normalized href attributes - div.innerHTML = ""; - - if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - div.firstChild.getAttribute("href") !== "#" ) { - - Expr.attrHandle.href = function( elem ) { - return elem.getAttribute( "href", 2 ); - }; - } - - // release memory in IE - div = null; -})(); - -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, - div = document.createElement("div"), - id = "__sizzle__"; - - div.innerHTML = "

"; - - // Safari can't handle uppercase or unicode characters when - // in quirks mode. - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function( query, context, extra, seed ) { - context = context || document; - - // Only use querySelectorAll on non-XML documents - // (ID selectors don't work in non-HTML documents) - if ( !seed && !Sizzle.isXML(context) ) { - // See if we find a selector to speed up - var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); - - if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { - // Speed-up: Sizzle("TAG") - if ( match[1] ) { - return makeArray( context.getElementsByTagName( query ), extra ); - - // Speed-up: Sizzle(".CLASS") - } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { - return makeArray( context.getElementsByClassName( match[2] ), extra ); - } - } - - if ( context.nodeType === 9 ) { - // Speed-up: Sizzle("body") - // The body element only exists once, optimize finding it - if ( query === "body" && context.body ) { - return makeArray( [ context.body ], extra ); - - // Speed-up: Sizzle("#ID") - } else if ( match && match[3] ) { - var elem = context.getElementById( match[3] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id === match[3] ) { - return makeArray( [ elem ], extra ); - } - - } else { - return makeArray( [], extra ); - } - } - - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(qsaError) {} - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - var oldContext = context, - old = context.getAttribute( "id" ), - nid = old || id, - hasParent = context.parentNode, - relativeHierarchySelector = /^\s*[+~]/.test( query ); - - if ( !old ) { - context.setAttribute( "id", nid ); - } else { - nid = nid.replace( /'/g, "\\$&" ); - } - if ( relativeHierarchySelector && hasParent ) { - context = context.parentNode; - } - - try { - if ( !relativeHierarchySelector || hasParent ) { - return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); - } - - } catch(pseudoError) { - } finally { - if ( !old ) { - oldContext.removeAttribute( "id" ); - } - } - } - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - // release memory in IE - div = null; - })(); -} - -(function(){ - var html = document.documentElement, - matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector, - pseudoWorks = false; - - try { - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( document.documentElement, "[test!='']:sizzle" ); - - } catch( pseudoError ) { - pseudoWorks = true; - } - - if ( matches ) { - Sizzle.matchesSelector = function( node, expr ) { - // Make sure that attribute selectors are quoted - expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); - - if ( !Sizzle.isXML( node ) ) { - try { - if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { - return matches.call( node, expr ); - } - } catch(e) {} - } - - return Sizzle(expr, null, null, [node]).length > 0; - }; - } -})(); - -(function(){ - var div = document.createElement("div"); - - div.innerHTML = "
"; - - // Opera can't find a second classname (in 9.6) - // Also, make sure that getElementsByClassName actually exists - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return; - } - - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) { - return; - } - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function( match, context, isXML ) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - - // release memory in IE - div = null; -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem.sizcache = doneName; - elem.sizset = i; - } - - if ( elem.nodeName.toLowerCase() === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - - if ( elem ) { - var match = false; - - elem = elem[dir]; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem.sizcache = doneName; - elem.sizset = i; - } - - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -if ( document.documentElement.contains ) { - Sizzle.contains = function( a, b ) { - return a !== b && (a.contains ? a.contains(b) : true); - }; - -} else if ( document.documentElement.compareDocumentPosition ) { - Sizzle.contains = function( a, b ) { - return !!(a.compareDocumentPosition(b) & 16); - }; - -} else { - Sizzle.contains = function() { - return false; - }; -} - -Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; - - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -var posProcess = function( selector, context ) { - var match, - tmpSet = [], - later = "", - root = context.nodeType ? [context] : context; - - // Position selectors must be done after the filter - // And so must :not(positional) so we move all PSEUDOs to the end - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet ); - } - - return Sizzle.filter( later, tmpSet ); -}; - -// EXPOSE -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.filters; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - -})(); - - -var runtil = /Until$/, - rparentsprev = /^(?:parents|prevUntil|prevAll)/, - // Note: This RegExp should be improved, or likely pulled from Sizzle - rmultiselector = /,/, - isSimple = /^.[^:#\[\.,]*$/, - slice = Array.prototype.slice, - POS = jQuery.expr.match.POS, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend({ - find: function( selector ) { - var ret = this.pushStack( "", "find", selector ), - length = 0; - - for ( var i = 0, l = this.length; i < l; i++ ) { - length = ret.length; - jQuery.find( selector, this[i], ret ); - - if ( i > 0 ) { - // Make sure that the results are unique - for ( var n = length; n < ret.length; n++ ) { - for ( var r = 0; r < length; r++ ) { - if ( ret[r] === ret[n] ) { - ret.splice(n--, 1); - break; - } - } - } - } - } - - return ret; - }, - - has: function( target ) { - var targets = jQuery( target ); - return this.filter(function() { - for ( var i = 0, l = targets.length; i < l; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - not: function( selector ) { - return this.pushStack( winnow(this, selector, false), "not", selector); - }, - - filter: function( selector ) { - return this.pushStack( winnow(this, selector, true), "filter", selector ); - }, - - is: function( selector ) { - return !!selector && jQuery.filter( selector, this ).length > 0; - }, - - closest: function( selectors, context ) { - var ret = [], i, l, cur = this[0]; - - if ( jQuery.isArray( selectors ) ) { - var match, selector, - matches = {}, - level = 1; - - if ( cur && selectors.length ) { - for ( i = 0, l = selectors.length; i < l; i++ ) { - selector = selectors[i]; - - if ( !matches[selector] ) { - matches[selector] = jQuery.expr.match.POS.test( selector ) ? - jQuery( selector, context || this.context ) : - selector; - } - } - - while ( cur && cur.ownerDocument && cur !== context ) { - for ( selector in matches ) { - match = matches[selector]; - - if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { - ret.push({ selector: selector, elem: cur, level: level }); - } - } - - cur = cur.parentNode; - level++; - } - } - - return ret; - } - - var pos = POS.test( selectors ) ? - jQuery( selectors, context || this.context ) : null; - - for ( i = 0, l = this.length; i < l; i++ ) { - cur = this[i]; - - while ( cur ) { - if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { - ret.push( cur ); - break; - - } else { - cur = cur.parentNode; - if ( !cur || !cur.ownerDocument || cur === context ) { - break; - } - } - } - } - - ret = ret.length > 1 ? jQuery.unique(ret) : ret; - - return this.pushStack( ret, "closest", selectors ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - if ( !elem || typeof elem === "string" ) { - return jQuery.inArray( this[0], - // If it receives a string, the selector is used - // If it receives nothing, the siblings are used - elem ? jQuery( elem ) : this.parent().children() ); - } - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - var set = typeof selector === "string" ? - jQuery( selector, context ) : - jQuery.makeArray( selector ), - all = jQuery.merge( this.get(), set ); - - return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? - all : - jQuery.unique( all ) ); - }, - - andSelf: function() { - return this.add( this.prevObject ); - } -}); - -// A painfully simple check to see if an element is disconnected -// from a document (should be improved, where feasible). -function isDisconnected( node ) { - return !node || !node.parentNode || node.parentNode.nodeType === 11; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return jQuery.nth( elem, 2, "nextSibling" ); - }, - prev: function( elem ) { - return jQuery.nth( elem, 2, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( elem.parentNode.firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.makeArray( elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ), - // The variable 'args' was introduced in - // https://github.com/jquery/jquery/commit/52a0238 - // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. - // http://code.google.com/p/v8/issues/detail?id=1050 - args = slice.call(arguments); - - if ( !runtil.test( name ) ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; - - if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - - return this.pushStack( ret, name, args.join(",") ); - }; -}); - -jQuery.extend({ - filter: function( expr, elems, not ) { - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 ? - jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : - jQuery.find.matches(expr, elems); - }, - - dir: function( elem, dir, until ) { - var matched = [], - cur = elem[ dir ]; - - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - nth: function( cur, result, dir, elem ) { - result = result || 1; - var num = 0; - - for ( ; cur; cur = cur[dir] ) { - if ( cur.nodeType === 1 && ++num === result ) { - break; - } - } - - return cur; - }, - - sibling: function( n, elem ) { - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, keep ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep(elements, function( elem, i ) { - var retVal = !!qualifier.call( elem, i, elem ); - return retVal === keep; - }); - - } else if ( qualifier.nodeType ) { - return jQuery.grep(elements, function( elem, i ) { - return (elem === qualifier) === keep; - }); - - } else if ( typeof qualifier === "string" ) { - var filtered = jQuery.grep(elements, function( elem ) { - return elem.nodeType === 1; - }); - - if ( isSimple.test( qualifier ) ) { - return jQuery.filter(qualifier, filtered, !keep); - } else { - qualifier = jQuery.filter( qualifier, filtered ); - } - } - - return jQuery.grep(elements, function( elem, i ) { - return (jQuery.inArray( elem, qualifier ) >= 0) === keep; - }); -} - - - - -var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, - rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, - rtagName = /<([\w:]+)/, - rtbody = /", "" ], - legend: [ 1, "
", "
" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - col: [ 2, "", "
" ], - area: [ 1, "", "" ], - _default: [ 0, "", "" ] - }; - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -// IE can't serialize and - - - - - - CRCE - ${param.title} - - - - -
- - - - - - - - - - - - - - - - - - - - -
- - - -
- -
-
- - - - -
${message}
-
- -
${message}
-
-
- - -
diff --git a/modules/crce-webui/src/main/webapp/jsp/plugins.jsp b/modules/crce-webui/src/main/webapp/jsp/plugins.jsp deleted file mode 100644 index ff12f87d..00000000 --- a/modules/crce-webui/src/main/webapp/jsp/plugins.jsp +++ /dev/null @@ -1,49 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - - -
- - -
-
- -
- edit -
-
-
-
-
Description: ${plugin.pluginDescription}
-
Priority: ${plugin.pluginPriority} [edit]
-
Version: ${plugin.pluginVersion} [edit]
-
Keywords: -
    - -
  • ${keyword}
  • -
    -
-
-
-
-
- - -
-
No plugins.
-
-
- - - - -
- - \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/store.jsp b/modules/crce-webui/src/main/webapp/jsp/store.jsp deleted file mode 100644 index e122822d..00000000 --- a/modules/crce-webui/src/main/webapp/jsp/store.jsp +++ /dev/null @@ -1,178 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - - -
- -
- - -
${resource.satisfied} - - - - uspech1 - - - neuspech1 - - - - "> - -
-
Properties: [edit] -
    -
  • Id: ${resource.id}
  • -
  • Symbolic name: ${resource.symbolicName}
  • -
  • Size: ${resource.size}
  • -
  • Export Meta-Data: LINK
  • -
-
    - -
  • - ${newProperty.name} - - - - -
    ${property.name}${property.type}${property.value}
    -
  • -
    -
-
-
Categories: [edit] -
    - -
  • ${category}
  • -
    -
-
-
-
Capabilities: [add new] -
    - -
  • - ${capability.name} [edit] - - - - -
    ${property.name}${property.type}${property.value}
    - -
      - -
    • - ${newProperty.name} - - - - -
      ${property.name}${property.type}${property.value}
      -
    • -
      -
    - -
  • -
    -
-
-
Requirements: [edit] - - - - - ${requirement.satisfied} - - - - - - - - - - - ${requirement.satisfied} - - - - class="uspech" - - - class="neuspech" - - - - > - - - - - - - - - - - -
NameFilterMultipleOptionalExtend
Comment
Unsatisfied requirements:
${requirement.name}${requirement.filter}${requirement.multiple}${requirement.optional}${requirement.extend}
${requirement.comment}
-
-
-
-
- - -
-
No resources in store.
-
-
- - - - - - -
- -
-
-
- -
-
- -
-
-
-
-
- - \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/tags.jsp b/modules/crce-webui/src/main/webapp/jsp/tags.jsp deleted file mode 100644 index 5069d6c2..00000000 --- a/modules/crce-webui/src/main/webapp/jsp/tags.jsp +++ /dev/null @@ -1,146 +0,0 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - - -
- -
- - - Store: - - - Store: - - - - - - Buffer: - - - Buffer: - - - - -
- - - - -
- -
${resource.satisfied} - - - - uspech1 - - - neuspech1 - - - - "> - -
-
Properties: -
    -
  • Id: ${resource.id}
  • -
  • Symbolic name: ${resource.symbolicName}
  • -
  • Size: ${resource.size}
  • -
-
-
Categories: -
    - -
  • ${category}
  • -
    -
-
-
Capabilities: -
    - -
  • - ${capability.name} - - - - - - - - -
    ${property.name}${property.type}${property.value}
    -
  • -
    -
-
-
Requirements: - - - - - ${requirement.satisfied} - - - - class="uspech" - - - class="neuspech" - - - - > - - - - - - - - - - -
NameFilterMultipleOptionalExtend
Comment
${requirement.name}${requirement.filter}${requirement.multiple}${requirement.optional}${requirement.extend}
${requirement.comment}
-
-
-
-
-
- - -
- - \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/test.jsp b/modules/crce-webui/src/main/webapp/test.jsp deleted file mode 100644 index d6d47d25..00000000 --- a/modules/crce-webui/src/main/webapp/test.jsp +++ /dev/null @@ -1,142 +0,0 @@ -<%@page import="cz.zcu.kiv.crce.plugin.Plugin"%> -<%@page import="cz.zcu.kiv.crce.metadata.Requirement"%> -<%@page import="cz.zcu.kiv.crce.metadata.Property"%> -<%@page import="cz.zcu.kiv.crce.metadata.Capability"%> -<%@page import="cz.zcu.kiv.crce.repository.Buffer"%> -<%@page import="cz.zcu.kiv.crce.webui.internal.Activator"%> -<%@page import="cz.zcu.kiv.crce.metadata.Resource"%> - -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> -<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> - - <% - //String hello = (String) session.getAttribute("hello"); - Resource[] resources = (Resource[]) session.getAttribute("resources"); - Plugin[] plugins = (Plugin[]) session.getAttribute("plugins"); - Resource[] store = (Resource[]) session.getAttribute("store"); - if(/*hello!=null &&*/ resources!=null && plugins!=null && store!=null) - { - //out.print(hello); - out.print("Resources size : "+resources.length+" Plugin size: "+plugins.length+" Store length: "+store.length); - } - else out.print("DIED"); - %> - - - - - - - - - - - - - - - Software components storage - - - - -
- -
-
logo
-
Software components storage
- -
-
- - -
-
-
-
- - - -
- - -
- -
-
Id: ${resource.id}
-
Symbolic name: ${resource.symbolicName}
-
URI: ${resource.uri}
-
Relative URI: ${resource.relativeUri}
-
Size: ${resource.size}
-
Categories: -
    - -
  • ${category}
  • -
    -
-
-
Capabilities: -
    - -
  • ${capability.name}
  • -
    -
-
-
Requirements: -
    - -
  • ${requirement.name} - ${requirement.filter}
  • -
    -
-
-
-
-
- - -
- -
© ASWI project 2011
- -
- - - - - diff --git a/modules/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java b/modules/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java deleted file mode 100644 index f3d39f55..00000000 --- a/modules/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package cz.zcu.kiv.crce.webui.internal; - -import static org.junit.Assert.*; - - -import java.io.IOException; -import java.net.MalformedURLException; - -import org.junit.Ignore; -import org.junit.Test; - -import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; -import com.gargoylesoftware.htmlunit.WebClient; -import com.gargoylesoftware.htmlunit.html.HtmlPage; - - -@Ignore -public class ResourceServletTest { - - - @Test - public void testDoGetHttpServletRequestHttpServletResponse() { - WebClient webClient = new WebClient(); - HtmlPage currentPage; - try { - currentPage =(HtmlPage) webClient.getPage("http://localhost:8090/crce/resource"); - - String pageAsText = currentPage.asText(); - assertTrue("Page does not contains uri: cz.zcu.kiv.crce.repository.api", pageAsText.contains("cz.zcu.kiv.crce.repository.api")); - } catch (FailingHttpStatusCodeException e) { - fail("FHSCE: " + e.toString()); - } catch (MalformedURLException e) { - fail("MUE: " + e.toString()); - } catch (IOException e) { - fail("IOE: " + e.toString()); - } - } - - -} diff --git a/modules/pom.xml b/modules/pom.xml index 2a4caec0..927021b4 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -57,22 +57,26 @@ pom - + provision + crce-metadata-osgi-bundle + crce-external-repository - crce-handler-metrics - + crce-webui-vaadin + crce-rest-v2 + crce-optimizer-functions + crce-compatibility-api crce-compatibility-dao-api crce-compatibility-dao-mongodb @@ -82,10 +86,6 @@ crce-webservices-indexer - - crce-webui-vaadin - provision - crce-external-repository diff --git a/modules/pom/pom.xml b/modules/pom/pom.xml index 85743560..c3f315fd 100644 --- a/modules/pom/pom.xml +++ b/modules/pom/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/modules/provision/pom.xml b/modules/provision/pom.xml index ad5df4d5..999711a5 100644 --- a/modules/provision/pom.xml +++ b/modules/provision/pom.xml @@ -1,43 +1,45 @@ - + - 4.0.0 + 4.0.0 - - ../pom - cz.zcu.kiv.crce - crce-modules-parent - 2.1.1-SNAPSHOT - + + ../pom + cz.zcu.kiv.crce + crce-modules-parent + 2.1.1-SNAPSHOT + - provision + provision - CRCE - Provision + CRCE - Provision - pom - - - + pom + - + - - org.osgi - org.osgi.core - - - org.osgi - org.osgi.compendium - + - + + org.osgi + org.osgi.core + + + org.osgi + org.osgi.compendium + - + + + org.ops4j.pax.web pax-web-jetty-bundle @@ -59,125 +61,126 @@ pax-web-descriptor - - - - org.apache.felix - org.apache.felix.configadmin - - - org.apache.felix - org.apache.felix.dependencymanager - - - org.apache.felix - org.apache.felix.dependencymanager.shell - - - org.apache.felix - org.apache.felix.gogo.runtime - - - - - org.apache.felix - org.apache.felix.dependencymanager.runtime - - - org.apache.felix - org.apache.felix.eventadmin - - - org.apache.felix - org.apache.felix.scr - - - org.apache.felix - org.apache.felix.webconsole - - - org.apache.felix - org.apache.felix.shell - - - org.apache.felix - org.apache.felix.bundlerepository - - - org.apache.felix - org.apache.felix.fileinstall - - - org.apache.felix - org.osgi.service.obr - - - - - - asm - asm-all - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.commons-vfs - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.bcel - - - org.apache.servicemix.bundles - org.apache.servicemix.bundles.jaxp-ri - - - com.google.code.gson - gson - - - org.codehaus.groovy - groovy-all - - - commons-fileupload - commons-fileupload - - - commons-io - commons-io - - - de.twentyeleven.skysail - org.json-osgi - - - - org.mybatis - mybatis - - - - com.h2database - h2 - - - - - org.apache.xbean - xbean-finder - - - org.apache.xbean - xbean-bundleutils - - - - - - cz.zcu.kiv.crce - crce-core - pom - - + + + org.hibernate.javax.persistence + hibernate-jpa-2.1-api + 1.0.0.Final + + + + + + org.apache.felix + org.apache.felix.configadmin + + + org.apache.felix + org.apache.felix.dependencymanager + + + org.apache.felix + org.apache.felix.dependencymanager.shell + + + org.apache.felix + org.apache.felix.gogo.runtime + + + + + org.apache.felix + org.apache.felix.dependencymanager.runtime + + + org.apache.felix + org.apache.felix.eventadmin + + + org.apache.felix + org.apache.felix.scr + + + org.apache.felix + org.apache.felix.webconsole + + + org.apache.felix + org.apache.felix.shell + + + org.apache.felix + org.apache.felix.bundlerepository + + + org.apache.felix + org.apache.felix.fileinstall + + + org.apache.felix + org.osgi.service.obr + + + + + + org.ow2.asm + asm-all + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.commons-vfs + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.bcel + + + org.apache.servicemix.bundles + org.apache.servicemix.bundles.jaxp-ri + + + com.google.code.gson + gson + + + org.codehaus.groovy + groovy-all + + + commons-fileupload + commons-fileupload + + + commons-io + commons-io + + + de.twentyeleven.skysail + org.json-osgi + + + org.apache.xbean + xbean-finder + + + + org.mybatis + mybatis + + + + com.h2database + h2 + + + + + + cz.zcu.kiv.crce + crce-core + pom + + diff --git a/pom.xml b/pom.xml index 0663881d..cee06dbe 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ CRCE - Reactor - + pom build core modules diff --git a/pom/pom.xml b/pom/pom.xml index 42cef4a2..38a92be9 100644 --- a/pom/pom.xml +++ b/pom/pom.xml @@ -74,7 +74,7 @@ - Central repository - must be listed first as a default repo for downloading of artifacts + central http://uk.maven.org/maven2 @@ -86,7 +86,7 @@ http://relisa-dev.kiv.zcu.cz:8081/nexus/content/groups/public - Fallback repositories + maven.kalwi.eu.snapshots kalwi.eu snapshots repository diff --git a/third-party/httpclient/pom.xml b/third-party/httpclient/pom.xml index 1c5151f9..eb67b4e7 100644 --- a/third-party/httpclient/pom.xml +++ b/third-party/httpclient/pom.xml @@ -8,7 +8,7 @@ cz.zcu.kiv.crce wrapper-bundle-settings - 2.1.0-SNAPSHOT + 2.1.2-SNAPSHOT cz.zcu.kiv.crce.wrapper diff --git a/third-party/httpcore/pom.xml b/third-party/httpcore/pom.xml index 49dcaa70..6e87a875 100644 --- a/third-party/httpcore/pom.xml +++ b/third-party/httpcore/pom.xml @@ -8,7 +8,7 @@ cz.zcu.kiv.crce wrapper-bundle-settings - 2.1.0-SNAPSHOT + 2.1.2-SNAPSHOT cz.zcu.kiv.crce.wrapper diff --git a/third-party/jna-platform/osgi.bnd b/third-party/jna-platform/osgi.bnd new file mode 100644 index 00000000..4c08335c --- /dev/null +++ b/third-party/jna-platform/osgi.bnd @@ -0,0 +1,9 @@ +#-------------------------------------------------------------------------- +# Use this file to add customized Bnd instructions for the wrapped library +#-------------------------------------------------------------------------- + +# +# this unpacks the contents of the wrapped jar artifact inside the bundle +# to also inline dependencies of this artifact add Embed-Transitive: true +# +Embed-Dependency: *;scope=compile|runtime;type=!pom;inline=true diff --git a/third-party/jna-platform/pom.xml b/third-party/jna-platform/pom.xml new file mode 100644 index 00000000..cff5297a --- /dev/null +++ b/third-party/jna-platform/pom.xml @@ -0,0 +1,37 @@ + + + + 4.0.0 + + + cz.zcu.kiv.crce + wrapper-bundle-settings + 2.1.2-SNAPSHOT + + + cz.zcu.kiv.crce.wrapper + net.java.dev.jna.jna-platform + 4.0.0 + bundle + + ${bundle.symbolicName} ${wrapped.version} [osgi] + + + net.java.dev.jna.jna-platform + net.java.dev.jna + jna-platform + 4.0.0 + + + + + ${wrapped.groupId} + ${wrapped.artifactId} + ${wrapped.version} + true + + + + diff --git a/third-party/lpsolve/osgi.bnd b/third-party/lpsolve/osgi.bnd new file mode 100644 index 00000000..a0bec077 --- /dev/null +++ b/third-party/lpsolve/osgi.bnd @@ -0,0 +1,21 @@ +#-------------------------------------------------------------------------- +# Use this file to add customized Bnd instructions for the wrapped library +#-------------------------------------------------------------------------- + +# +# this unpacks the contents of the wrapped jar artifact inside the bundle +# to also inline dependencies of this artifact add Embed-Transitive: true +# +Embed-Dependency: *;scope=compile|runtime;type=!pom;inline=true + +Bundle-NativeCode: libs/linux/x64/liblpsolve55j.so; \ + osname=Linux ; \ + processor=x86-64, \ + \ + libs/win/x64/lpsolve55j.dll; \ + osname=Win32 ; \ + processor=x86-64, \ + \ + libs/win/x86/lpsolve55j.dll; \ + osname=Win32 ; \ + processor=x86 diff --git a/third-party/lpsolve/pom.xml b/third-party/lpsolve/pom.xml new file mode 100644 index 00000000..43b04c93 --- /dev/null +++ b/third-party/lpsolve/pom.xml @@ -0,0 +1,45 @@ + + + + 4.0.0 + + + cz.zcu.kiv.crce + compiled-bundle-settings + 2.1.2-SNAPSHOT + + + cz.zcu.kiv.crce.wrapper + com.datumbox.lpsolve + 5.5.2.3 + bundle + + ${bundle.symbolicName} ${version} [osgi] + + + com.datumbox.lpsolve + lpsolve + + + + + + org.apache.maven.plugins + maven-pmd-plugin + + true + + + + org.codehaus.mojo + findbugs-maven-plugin + + true + + + + + + diff --git a/third-party/lpsolve/src/main/java/lpsolve/AbortListener.java b/third-party/lpsolve/src/main/java/lpsolve/AbortListener.java new file mode 100644 index 00000000..80a05ba8 --- /dev/null +++ b/third-party/lpsolve/src/main/java/lpsolve/AbortListener.java @@ -0,0 +1,44 @@ +/* + This software is a Java wrapper for the lp_solve optimization library. + + Copyright (C) 2004 Juergen Ebert (juergen.ebert@web.de) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package lpsolve; + +/** + * Classes that implement this interface may be passed + * to the putAbortfunc method of the LpSolve class. + * + * @author Juergen Ebert + * @see LpSolve#putAbortfunc + * @see "lp_solve documentation for 'put_abortfunc'" + */ +public interface AbortListener { + + /** + * When set, the abort routine is called regularly during solve(). + * The user can do whatever he wants in this routine. + * + * @param problem the problem this Listener was defined for + * @param userhandle the userhandle object that was passed to putAbortfunc + * @return if true, then lp_solve aborts the solver and returns with an appropriate code + * @throws LpSolveException + */ + public boolean abortfunc(LpSolve problem, Object userhandle) throws LpSolveException; + +} diff --git a/third-party/lpsolve/src/main/java/lpsolve/BbListener.java b/third-party/lpsolve/src/main/java/lpsolve/BbListener.java new file mode 100644 index 00000000..e56fe874 --- /dev/null +++ b/third-party/lpsolve/src/main/java/lpsolve/BbListener.java @@ -0,0 +1,46 @@ +/* + This software is a Java wrapper for the lp_solve optimization library. + + Copyright (C) 2004 Juergen Ebert (juergen.ebert@web.de) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package lpsolve; + +/** + * Classes that implement this interface may be passed + * to the putbbBranchfunc and putbbNodefunc method + * of the LpSolve class. + * + * @author Juergen Ebert + * @see LpSolve#putBbBranchfunc + * @see LpSolve#putBbNodefunc + * @see "lp_solve documentation for 'put_bb_branchfunc'" + * @see "lp_solve documentation for 'put_bb_nodefunc'" + */ +public interface BbListener { + + /** + * TODO: add documentation when available + * + * @param problem the problem this Listener was defined for + * @param userhandle the userhandle object that was passed to putLogfunc + * @param buf the log message + * @throws LpSolveException + */ + public int bbfunc(LpSolve problem, Object userhandle, int message) throws LpSolveException; + +} diff --git a/third-party/lpsolve/src/main/java/lpsolve/LogListener.java b/third-party/lpsolve/src/main/java/lpsolve/LogListener.java new file mode 100644 index 00000000..869a3e77 --- /dev/null +++ b/third-party/lpsolve/src/main/java/lpsolve/LogListener.java @@ -0,0 +1,44 @@ +/* + This software is a Java wrapper for the lp_solve optimization library. + + Copyright (C) 2004 Juergen Ebert (juergen.ebert@web.de) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package lpsolve; + +/** + * Classes that implement this interface may be passed + * to the putLogfunc method of the LpSolve class. + * + * @author Juergen Ebert + * @see LpSolve#putLogfunc + * @see "lp_solve documentation for 'put_logfunc'" + */ +public interface LogListener { + + /** + * When set, the log routine is called when lp_solve has someting + * to report (error conditions or so). + * + * @param problem the problem this Listener was defined for + * @param userhandle the userhandle object that was passed to putLogfunc + * @param buf the log message + * @throws LpSolveException + */ + public void logfunc(LpSolve problem, Object userhandle, String buf) throws LpSolveException; + +} diff --git a/third-party/lpsolve/src/main/java/lpsolve/LpSolve.java b/third-party/lpsolve/src/main/java/lpsolve/LpSolve.java new file mode 100644 index 00000000..5a344475 --- /dev/null +++ b/third-party/lpsolve/src/main/java/lpsolve/LpSolve.java @@ -0,0 +1,1706 @@ +/* + This software is a Java wrapper for the lp_solve optimization library. + + Copyright (C) 2004 Juergen Ebert (juergen.ebert@web.de) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package lpsolve; + +import java.util.HashMap; +import java.util.Map; + + +/** + * Object wrapper for a problem structure of the lp_solve library. + * Offers access to all lp_solve methods. + * + * @author Juergen Ebert + */ +public class LpSolve { + + public static final int FALSE = 0; + public static final int TRUE = 1; + public static final int AUTOMATIC = 2; + public static final int DYNAMIC = 4; + + public static final int FR = 0; + public static final int LE = 1; + public static final int GE = 2; + public static final int EQ = 3; + public static final int OF = 4; + + public static final int SIMPLEX_PRIMAL_PRIMAL = 5; + public static final int SIMPLEX_DUAL_PRIMAL = 6; + public static final int SIMPLEX_PRIMAL_DUAL = 9; + public static final int SIMPLEX_DUAL_DUAL = 10; + public static final int SIMPLEX_DEFAULT = SIMPLEX_DUAL_PRIMAL; + + /* Presolve defines */ + public static final int PRESOLVE_NONE = 0; + public static final int PRESOLVE_ROWS = 1; + public static final int PRESOLVE_COLS = 2; + public static final int PRESOLVE_LINDEP = 4; + public static final int PRESOLVE_SOS = 32; + public static final int PRESOLVE_REDUCEMIP = 64; + public static final int PRESOLVE_KNAPSACK = 128; + public static final int PRESOLVE_ELIMEQ2 = 256; + public static final int PRESOLVE_IMPLIEDFREE = 512; + public static final int PRESOLVE_REDUCEGCD = 1024; + public static final int PRESOLVE_PROBEFIX = 2048; + public static final int PRESOLVE_PROBEREDUCE = 4096; + public static final int PRESOLVE_ROWDOMINATE = 8192; + public static final int PRESOLVE_COLDOMINATE = 16384; + public static final int PRESOLVE_MERGEROWS = 32768; + public static final int PRESOLVE_IMPLIEDSLK = 65536; + public static final int PRESOLVE_COLFIXDUAL = 131072; + public static final int PRESOLVE_BOUNDS = 262144; + public static final int PRESOLVE_DUALS = 524288; + public static final int PRESOLVE_SENSDUALS = 1048576; + + /* Basis crash options */ + public static final int CRASH_NOTHING = 0; + public static final int CRASH_MOSTFEASIBLE = 2; + + /* Strategy codes to avoid or recover from degenerate pivots */ + public static final int ANTIDEGEN_NONE = 0; + public static final int ANTIDEGEN_FIXEDVARS = 1; + public static final int ANTIDEGEN_COLUMNCHECK = 2; + public static final int ANTIDEGEN_STALLING = 4; + public static final int ANTIDEGEN_NUMFAILURE = 8; + public static final int ANTIDEGEN_LOSTFEAS = 16; + public static final int ANTIDEGEN_INFEASIBLE = 32; + public static final int ANTIDEGEN_DYNAMIC = 64; + public static final int ANTIDEGEN_DURINGBB = 128; + public static final int ANTIDEGEN_RHSPERTURB = 256; + public static final int ANTIDEGEN_BOUNDFLIP = 512; + + /* REPORT defines */ + public static final int NEUTRAL = 0; + public static final int CRITICAL = 1; + public static final int SEVERE = 2; + public static final int IMPORTANT = 3; + public static final int NORMAL = 4; + public static final int DETAILED = 5; + public static final int FULL = 6; + + /* MESSAGE defines */ + public static final int MSG_NONE = 0; + public static final int MSG_PRESOLVE = 1; + public static final int MSG_ITERATION = 2; + public static final int MSG_INVERT = 4; + public static final int MSG_LPFEASIBLE = 8; + public static final int MSG_LPOPTIMAL = 16; + public static final int MSG_LPEQUAL = 32; + public static final int MSG_LPBETTER = 64; + public static final int MSG_MILPFEASIBLE = 128; + public static final int MSG_MILPEQUAL = 256; + public static final int MSG_MILPBETTER = 512; + public static final int MSG_MILPSTRATEGY = 1024; + public static final int MSG_MILPOPTIMAL = 2048; + public static final int MSG_PERFORMANCE = 4096; + public static final int MSG_INITPSEUDOCOST = 8192; + + /* Improvement defines */ + public static final int IMPROVE_NONE = 0; + public static final int IMPROVE_SOLUTION = 1; + public static final int IMPROVE_DUALFEAS = 2; + public static final int IMPROVE_THETAGAP = 4; + public static final int IMPROVE_BBSIMPLEX = 8; + + /* Scaling types */ + public static final int SCALE_NONE = 0; + public static final int SCALE_EXTREME = 1; + public static final int SCALE_RANGE = 2; + public static final int SCALE_MEAN = 3; + public static final int SCALE_GEOMETRIC = 4; + public static final int SCALE_CURTISREID = 7; /* Override to optimal Curtis-Reid scaling */ + + /* Alternative scaling weights */ + public static final int SCALE_LINEAR = 0; + public static final int SCALE_QUADRATIC = 8; + public static final int SCALE_LOGARITHMIC = 16; + public static final int SCALE_USERWEIGHT = 31; + public static final int SCALE_POWER2 = 32; /* As is or rounded to power of 2 */ + public static final int SCALE_EQUILIBRATE = 64; /* Make sure that no scaled number is above 1 */ + public static final int SCALE_INTEGERS = 128; /* Apply to integer column variables */ + public static final int SCALE_DYNUPDATE = 256; + public static final int SCALE_ROWSONLY = 512; + public static final int SCALE_COLSONLY = 1024; + + /* Pricing methods */ + public static final int PRICER_FIRSTINDEX = 0; + public static final int PRICER_DANTZIG = 1; + public static final int PRICER_DEVEX = 2; + public static final int PRICER_STEEPESTEDGE = 3; + + /* Pricing strategies */ + public static final int PRICE_METHODDEFAULT = 0; + public static final int PRICE_PRIMALFALLBACK = 4; /* In case of Steepest Edge, fall back to DEVEX in primal */ + public static final int PRICE_MULTIPLE = 8; /* Multiple pricing (as of v5 only binary) */ + public static final int PRICE_PARTIAL = 16; /* Enable partial pricing */ + public static final int PRICE_ADAPTIVE = 32; /* Temporarily use First Index if cycling is detected */ + public static final int PRICE_HYBRID = 64; /* NOT IMPLEMENTED */ + public static final int PRICE_RANDOMIZE = 128; /* Adds a small randomization effect to the selected pricer */ + public static final int PRICE_AUTOPARTIAL = 512; + public static final int PRICE_LOOPLEFT = 1024; /* Scan entering/leaving columns left rather than right */ + public static final int PRICE_LOOPALTERNATE = 2048; /* Scan entering/leaving columns alternatingly left/right */ + public static final int PRICE_HARRISTWOPASS = 4096; + public static final int PRICE_TRUENORMINIT = 16384; + + /* B&B strategies */ + public static final int NODE_FIRSTSELECT = 0; + public static final int NODE_GAPSELECT = 1; + public static final int NODE_RANGESELECT = 2; + public static final int NODE_FRACTIONSELECT = 3; + public static final int NODE_PSEUDOCOSTSELECT = 4; + public static final int NODE_PSEUDONONINTSELECT = 5; /* Kjell Eikland special #1 */ + public static final int NODE_PSEUDORATIOSELECT = 6; /* Kjell Eikland special #2 */ + public static final int NODE_USERSELECT = 7; + + public static final int NODE_WEIGHTREVERSEMODE = 8; + public static final int NODE_BRANCHREVERSEMODE = 16; + public static final int NODE_GREEDYMODE = 32; + public static final int NODE_PSEUDOCOSTMODE = 64; + public static final int NODE_DEPTHFIRSTMODE = 128; + public static final int NODE_RANDOMIZEMODE = 256; + public static final int NODE_DYNAMICMODE = 1024; + public static final int NODE_RESTARTMODE = 2048; + public static final int NODE_BREADTHFIRSTMODE = 4096; + public static final int NODE_AUTOORDER = 8192; + public static final int NODE_RCOSTFIXING = 16384; + public static final int NODE_STRONGINIT = 32768; + + public static final int BRANCH_CEILING = 0; + public static final int BRANCH_FLOOR = 1; + public static final int BRANCH_AUTOMATIC = 2; + public static final int BRANCH_DEFAULT = 3; + + /* Solver status values */ + public static final int UNKNOWNERROR = -5; + public static final int DATAIGNORED = -4; + public static final int NOBFP = -3; + public static final int NOMEMORY = -2; + public static final int NOTRUN = -1; + public static final int OPTIMAL = 0; + public static final int SUBOPTIMAL = 1; + public static final int INFEASIBLE = 2; + public static final int UNBOUNDED = 3; + public static final int DEGENERATE = 4; + public static final int NUMFAILURE = 5; + public static final int USERABORT = 6; + public static final int TIMEOUT = 7; + public static final int RUNNING = 8; + public static final int PRESOLVED = 9; + + /* Branch & Bound and Lagrangean extra status values */ + public static final int PROCFAIL = 10; + public static final int PROCBREAK = 11; + public static final int FEASFOUND = 12; + public static final int NOFEASFOUND = 13; + + + /** + * Value of the pointer to the lprec structure in the C stub DLL. + */ + private long lp = 0; + + /** + * Callback listener set by putAbortfunc + */ + private AbortListener abortListener = null; + + /** + * User handle set by putAbortfunc + */ + private Object abortUserhandle = null; + + /** + * Callback listener set by putLogfunc + */ + private LogListener logListener = null; + + /** + * User handle set by putLogfunc + */ + private Object logUserhandle = null; + + /** + * Callback listener set by putMsgfunc + */ + private MsgListener msgListener = null; + + /** + * User handle set by putMsgfunc + */ + private Object msgUserhandle = null; + + /** + * Callback listener set by putBbBranchfunc + */ + private BbListener bbBranchListener = null; + + /** + * User handle set by putBbBranchfunc + */ + private Object bbBranchUserhandle = null; + + /** + * Callback listener set by putBbNodefunc + */ + private BbListener bbNodeListener = null; + + /** + * User handle set by putBbNodefunc + */ + private Object bbNodeUserhandle = null; + + /** + * Static initializer to load the stub library + */ + static { + System.loadLibrary("lpsolve55j"); + init(); + } + + /** + * Native helper method to cache method and field IDs. + */ + private static native void init(); + + + // ======================================================================== + // Constructors + // ======================================================================== + + /** + * Constructs a new LpSolve instance + */ + private LpSolve(long lp) { + this.lp = lp; + } + + // ======================================================================== + // Public static factory methods + // ======================================================================== + + /** + * Creates a new problem. Upon successful completion, the lprec attribute + * in this class contains the value of the pointer to the lprec + * structure. + * + * @param rows Initial number of rows. + * @param columns Initial number of columns. + * @throws LpSolveException if lp_solve could not create the problem + */ + public static native LpSolve makeLp(int rows, int columns) throws LpSolveException; + + /** + * Read an lp model from file and create a new problem. + */ + public static native LpSolve readLp(String filename, int verbose, String lpName) + throws LpSolveException; + + /** + * Read an mps model from file and create a new problem. + */ + public static native LpSolve readMps(String filename, int verbose) + throws LpSolveException; + + /** + * Read a model in free MPS format from file and create a new problem. + */ + public static native LpSolve readFreeMps(String filename, int verbose) + throws LpSolveException; + + /** + * Read a model via the External Language Interface and create a new problem. + */ + public static native LpSolve readXLI(String xliname, String modelname, + String dataname, String options, int verbose) throws LpSolveException; + + + // ======================================================================== + // Other static methods + // ======================================================================== + + /** + * Returns the full version number of the underlying lp_solve library. + * + * @return VersionInfo object with full version info + */ + public static native VersionInfo lpSolveVersion(); + + + // ======================================================================== + // Overridden methods of the base class + // ======================================================================== + + + /* (non-Javadoc) + * @see java.lang.Object#finalize() + */ + protected void finalize() throws Throwable { + if (lp != 0) { + removeLp(lp); + deleteLp(); + } + super.finalize(); + } + + /** + * Return the value of the lp attribute. + * @return the value of the lp attribute + */ + public long getLp() { + return lp; + } + + + // ======================================================================== + // Native methods. + // ======================================================================== + + /** + * Copy an existing lprec structure to a new lprec structure. + * Creates an independent new problem. + */ + public native LpSolve copyLp() throws LpSolveException; + + /** + * Set the name of the problem. + */ + public native void setLpName(String name) throws LpSolveException; + + /** + * Allocate memory for the specified size. + */ + public native void resizeLp(int rows, int columns) throws LpSolveException; + + /** + * Get the name of the problem. + */ + public native String getLpName() throws LpSolveException; + + /** + * Add a constraint to the problem. + */ + public native void addConstraint(double[] row, int constrType, double rh) throws LpSolveException; + + /** + * Add a constraint to the problem. + */ + public native void strAddConstraint(String row, int constrType, double rh) throws LpSolveException; + + /** + * Add a constraint to the problem. + */ + public native void addConstraintex(int count, double[] row, int[] colno, int constrType, double rh) throws LpSolveException; + + /** + * Remove a constraint from the problem. + */ + public native void delConstraint(int rownr) throws LpSolveException; + + /** + * Returns if constraint type specified in mask is active. + */ + public native boolean isConstrType(int row, int mask); + + /** + * Add a Lagrangian constraint to the problem. + */ + public native void addLagCon(double[] row, int constrType, double rh) throws LpSolveException; + + /** + * Add a Lagrangian constraint to the problem. + */ + public native void strAddLagCon(String row, int constrType, double rh) throws LpSolveException; + + /** + * Add a column to the problem. + */ + public native void addColumn(double[] column) throws LpSolveException; + + /** + * Add a column to the problem. + */ + public native void addColumnex(int count, double[] column, int[] rowno) throws LpSolveException; + + /** + * Add a column to the problem. + */ + public native void strAddColumn(String column) throws LpSolveException; + + /** + * Remove a column from the problem. + */ + public native void delColumn(int columnnr) throws LpSolveException; + + /** + * Set a constraint in the lp. + */ + public native void setRow(int rowno, double[] row) throws LpSolveException; + + /** + * Set a constraint in the lp. + */ + public native void setRowex(int rowno, int count, double[] row, int[] colno) throws LpSolveException; + + /** + * Set a column in the lp. + */ + public native void setColumn(int colno, double[] column) throws LpSolveException; + + /** + * Set a column in the lp. + */ + public native void setColumnex(int colno, int count, double[] column, int[] rowno) throws LpSolveException; + + /** + * Check if a column is already present in the problem. + */ + public native int columnInLp(double[] column); + + /** + * Set the name of a constraint (row) in the problem. + */ + public native void setRowName(int rownr, String name) throws LpSolveException; + + /** + * Gets the name of a constraint (row) in the problem. + */ + public native String getRowName(int rownr) throws LpSolveException; + + /** + * Gets the name of a constraint (row) in the problem. + */ + public native String getOrigrowName(int rownr) throws LpSolveException; + + /** + * Set the name of a column in the problem. + */ + public native void setColName(int colnr, String name) throws LpSolveException; + + /** + * Gets the name of a column in the problem. + */ + public native String getColName(int colnr) throws LpSolveException; + + /** + * Gets the name of a column in the problem. + */ + public native String getOrigcolName(int colnr) throws LpSolveException; + + /** + * Set the right hand side (RHS) vector (column 0). + */ + public native void setRhVec(double[] rh) throws LpSolveException; + + /** + * Set the right hand side (RHS) vector (column 0). + */ + public native void strSetRhVec(String rh) throws LpSolveException; + + /** + * Set the value of the right hand side (RHS) vector (column 0) for one row. + */ + public native void setRh(int row, double value) throws LpSolveException; + + /** + * Get the value of the right hand side (RHS) vector (column 0) for one row. + * NOTE: Returns 0 even if the row index is out of bounds, in accordance + * to the behaviour of the lp_solve routine! + */ + public native double getRh(int row); + + /** + * Set the type of a constraint. + */ + public native void setConstrType(int rownr, int constrType) throws LpSolveException; + + /** + * Get the type of a constraint. + */ + public native short getConstrType(int rownr) throws LpSolveException; + + /** + * Add a SOS constraint. + */ + public native void addSOS(String name, int sostype, int priority, int count, + int[] sosvars, double[] weights) throws LpSolveException; + + /** + * Returns if the variable is SOS or not. + */ + public native boolean isSOSVar(int colnr) throws LpSolveException; + + /** + * Set the objective function (row 0) of the matrix. + */ + public native void setObjFn(double[] row) throws LpSolveException; + + /** + * Set the objective function (row 0) of the matrix. + */ + public native void strSetObjFn(String row) throws LpSolveException; + + /** + * Set the objective function (row 0) of the matrix. + */ + public native void setObjFnex(int count, double[] row, int[] colno) throws LpSolveException; + + /** + * Set the objective function (row 0) of the matrix. + */ + public native void setObj(int column, double value) throws LpSolveException; + + /** + * Set a single element in the matrix. + */ + public native void setMat(int row, int column, double value) throws LpSolveException; + + /** + * Get a single element from the matrix. + */ + public native double getMat(int row, int column); + + /** + * Get all row elements from the matrix. + * Passed in arrays must be allocated by the caller of the method. + */ + public native void getRow(int rownr, double[] row) throws LpSolveException; + + /** + * Get the non-zero row elements from the matrix. + * Passed in arrays must be allocated by the caller of the method. + */ + public native int getRowex(int rownr, double[] row, int[] nzcols) throws LpSolveException; + + /** + * Get all row elements from the matrix. + * Returned array is allocated by the method. + * This is an additional method which is not implemented by lp_solve. + * Internally, get_row is used. + */ + public native double[] getPtrRow(int rownr) throws LpSolveException; + + /** + * Get all column elements from the matrix. + * Passed in arrays must be allocated by the caller of the method. + */ + public native void getColumn(int colnr, double[] column) throws LpSolveException; + + /** + * Get the non-zero column elements from the matrix. + * Passed in arrays must be allocated by the caller of the method. + */ + public native int getColumnex(int colnr, double[] column, int[] nzrows) throws LpSolveException; + + /** + * Get all column elements from the matrix. + * Returned array is allocated by the method. + * This is an additional method which is not implemented by lp_solve. + * Internally, get_column is used. + */ + public native double[] getPtrColumn(int columnrnr) throws LpSolveException; + + /** + * Set objective function to maximize. + */ + public native void setMaxim(); + + /** + * Set objective function to minimize. + */ + public native void setMinim(); + + /** + * Set objective function sense. + */ + public native void setSense(boolean maximize); + + /** + * Returns objective function direction. + */ + public native boolean isMaxim(); + + /** + * Set the lower bound of a variable. + */ + public native void setLowbo(int colnr, double value) throws LpSolveException; + + /** + * Get the lower bound of a variable. + */ + public native double getLowbo(int colnr) throws LpSolveException; + + /** + * Set the upper bound of a variable. + */ + public native void setUpbo(int colnr, double value) throws LpSolveException; + + /** + * Get the upper bound of a variable. + */ + public native double getUpbo(int colnr) throws LpSolveException; + + /** + * Sets if the variable is free. + */ + public native void setUnbounded(int colnr) throws LpSolveException; + + /** + * Returns if the variable is free. + */ + public native boolean isUnbounded(int colnr); + + /** + * Returns if the variable is negative. + */ + public native boolean isNegative(int colnr); + + /** + * Set the upper and lower bound of a variable. + */ + public native void setBounds(int colnr, double lower, double upper) throws LpSolveException; + + /** + * Specifies if set bounds may only be tighter or also less restrictive. + */ + public native void setBoundsTighter(boolean tighten); + + /** + * Returns if set bounds may only be tighter or also less restrictive. + */ + public native boolean getBoundsTighter(); + + /** + * Set the range on a constraint. + */ + public native void setRhRange(int rownr, double range) throws LpSolveException; + + /** + * Gets the range on a constraint. + */ + public native double getRhRange(int rownr) throws LpSolveException; + + /** + * Set the type of the variable. Integer or floating point. + */ + public native void setInt(int colnr, boolean mustBeInteger) throws LpSolveException; + + /** + * Get the type of the variable. Integer or floating point. + */ + public native boolean isInt(int colnr); + + /** + * Set the type of the variable. Binary or floating point. + */ + public native void setBinary(int colnr, boolean mustBeBin) throws LpSolveException; + + /** + * Gets the type of the variable. Binary integer or floating point. + */ + public native boolean isBinary(int colnr); + + /** + * Set the type of the variable. semi-continious or not. + */ + public native void setSemicont(int colnr, boolean mustBeSc) throws LpSolveException; + + /** + * Get the type of the variable. semi-continious or not. + */ + public native boolean isSemicont(int colnr); + + /** + * Specifies the practical value for "infinite". + */ + public native void setInfinite(double value); + + /** + * Returns the value of "infinite". + */ + public native double getInfinite(); + + /** + * Checks if the provided absolute of the value is larger or equal to "infinite". + */ + public native boolean isInfinite(double value); + + /** + * Specifies the tolerance that is used to determine whether a floating-point + * number is in fact an integer. + */ + public native void setEpsint(double value); + + /** + * Returns the tolerance that is used to determine whether a floating-point + * number is in fact an integer + */ + public native double getEpsint(); + + /** + * Specifies the value that is used as a tolerance for the Right Hand Side (RHS) + * to determine whether a value should be considered as 0 + */ + public native void setEpsb(double value); + + /** + * Returns the value that is used as a tolerance for the Right Hand Side (RHS) + * to determine whether a value should be considered as 0. + */ + public native double getEpsb(); + + /** + * Specifies the value that is used as a tolerance for reduced costs + * to determine whether a value should be considered as 0. + */ + public native void setEpsd(double value); + + /** + * Returns the value that is used as a tolerance for the reduced costs + * to determine whether a value should be considered as 0. + */ + public native double getEpsd(); + + /** + * Specifies the value that is used as a tolerance for rounding values to zero. + */ + public native void setEpsel(double value); + + /** + * Returns the value that is used as a tolerance for rounding values to zero. + */ + public native double getEpsel(); + + /** + * Specifies the value that is used as a tolerance pivot element to determine + * whether a value should be considered as 0. + */ + public native void setEpspivot(double value); + + /** + * Returns the value that is used as a tolerance pivot element to determine + * whether a value should be considered as 0. + */ + public native double getEpspivot(); + + /** + * Specifies the value that is used as perturbation scalar for degenerative problems. + */ + public native void setEpsperturb(double value); + + /** + * Returns the value that is used as perturbation scalar for degenerative problems. + */ + public native double getEpsperturb(); + + /** + * This is a simplified way of specifying multiple eps thresholds that are "logically" consistent. + */ + public native void setEpslevel(int epslevel) throws LpSolveException; + + /** + * Returns an extra status after a call to a function. + */ + public native int getStatus(); + + /** + * Specifies the MIP gap value. + */ + public native void setMipGap(boolean absolute, double value); + + /** + * Returns the MIP gap value. + */ + public native double getMipGap(boolean absolute); + + /** + * Set the verbose level. + */ + public native void setVerbose(int verbose); + + /** + * Returns the verbose level. + */ + public native int getVerbose(); + + /** + * Set a timeout. + */ + public native void setTimeout(long timeout); + + /** + * Gets the timout. + */ + public native long getTimeout(); + + /** + * Gets the time elapsed since start of solve. + */ + public native double timeElapsed(); + + /** + * Sets a flag if all intermediate valid solutions must be printed while solving. + */ + public native void setPrintSol(int printSol); + + /** + * Returns a flag if all intermediate valid solutions must be printed while solving. + */ + public native int getPrintSol(); + + /** + * Sets a flag if all intermediate results and the branch-and-bound decisions + * must be printed while solving. + */ + public native void setDebug(boolean debug); + + /** + * Returns a flag if all intermediate results and the branch-and-bound decisions + * must be printed while solving. + */ + public native boolean isDebug(); + + /** + * Sets a flag if pivot selection must be printed while solving. + */ + public native void setTrace(boolean trace); + + /** + * Returns a flag if pivot selection must be printed while solving. + */ + public native boolean isTrace(); + + /** + * Sets a flag if Lagrangian progression must be printed while solving. + */ + public native void setLagTrace(boolean lagTrace); + + /** + * Returns a flag if Lagrangian progression must be printed while solving. + */ + public native boolean isLagTrace(); + + /** + * Specifies which add routine performs best. + */ + public native boolean setAddRowmode(boolean turnon); + + /** + * Returns a flag which of the add routines perform best. + */ + public native boolean isAddRowmode(); + + /** + * Specifies if special handling must be done to reduce degeneracy/cycling while solving. + */ + public native void setAntiDegen(int antiDegen); + + /** + * Returns if the degeneracy rule specified in testmask is active. + */ + public native boolean isAntiDegen(int testmask); + + /** + * Returns the used degeneracy rule. + */ + public native int getAntiDegen(); + + /** + * Specifies if a presolve must be done before solving. + */ + public native void setPresolve(int doPresolve, int maxloops); + + /** + * Returns if presolve level specified in testmask is active. + */ + public native boolean isPresolve(int testmask); + + /** + * Returns the current presolve setting. + */ + public native int getPresolve(); + + /** + * Returns the number of times presolve is done. + */ + public native int getPresolveloops(); + + /** + * Sets the maximum number of pivots between a reinversion of the matrix. + */ + public native void setMaxpivot(int maxNumInv); + + /** + * Returns the maximum number of pivots between a reinversion of the matrix. + */ + public native int getMaxpivot(); + + /** + * Specifies the branch-and-bound rule. + */ + public native void setBbRule(int bbRule); + + /** + * Returns the branch-and-bound rule. + */ + public native int getBbRule(); + + /** + * Sets the maximum branch-and-bound depth. + */ + public native void setBbDepthlimit(int bbMaxlevel); + + /** + * Returns the maximum branch-and-bound depth. + */ + public native int getBbDepthlimit(); + + /** + * Returns the number of equal solutions. + */ + public native int getSolutioncount(); + + /** + * Sets the solution number that must be returned. + */ + public native void setSolutionlimit(int limit); + + /** + * Returns the solution number that must be returned. + */ + public native int getSolutionlimit(); + + /** + * Set initial "at least better than" guess for objective function. + */ + public native void setObjBound(double objBound); + + /** + * Returns initial "at least better than" guess for objective function. + */ + public native double getObjBound(); + + /** + * Specifies which branch to take first in branch-and-bound algorithm. + */ + public native void setBbFloorfirst(int floorFirst); + + /** + * Returns which branch to take first in branch-and-bound algorithm. + */ + public native int getBbFloorfirst(); + + /** + * Specifies, for the specified variable, which branch to take first + * in branch-and-bound algorithm. + */ + public native void setVarBranch(int colnr, int branchMode) throws LpSolveException; + + /** + * Returns, for the specified variable, which branch to take first + * in branch-and-bound algorithm. + */ + public native int getVarBranch(int colnr) throws LpSolveException; + + /** + * Set the weights on variables. + */ + public native void setVarWeights(double[] weights) throws LpSolveException; + + /** + * Returns, for the specified variable, the priority the variable has + * in the branch-and-bound algorithm. + */ + public native int getVarPriority(int colnr) throws LpSolveException; + + /** + * Specifies if the branch-and-bound algorithm stops at first found solution. + */ + public native void setBreakAtFirst(boolean breakAtFirst); + + /** + * Returns if the branch-and-bound algorithm stops at first found solution. + */ + public native boolean isBreakAtFirst(); + + /** + * Specifies if the branch-and-bound algorithm stops when the object value + * is better than a given value. + */ + public native void setBreakAtValue(double breakAtValue); + + /** + * Returns the value at which the branch-and-bound algorithm stops + * when the object value is better than this value. + */ + public native double getBreakAtValue(); + + /** + * Specifies which scaling algorithm must be used. + */ + public native void setScaling(int scalemode); + + /** + * Specifies which scaling algorithm is used. + */ + public native int getScaling(); + + /** + * Returns if scaling mode specified in testmask is active. + */ + public native boolean isScalemode(int testmask); + + /** + * Returns if scaling type specified in scaletype is active. + */ + public native boolean isScaletype(int scaletype); + + /** + * Specifies which scaling algorithm is used. + */ + public native boolean isIntegerscaling(); + + /** + * Sets the relative scaling convergence criterion for the active scaling mode; + * the integer part specifies the maximum number of iterations. + */ + public native void setScalelimit(double scalelimit); + + /** + * Returns the relative scaling convergence criterion for the active scaling mode; + * the integer part specifies the maximum number of iterations. + */ + public native double getScalelimit(); + + /** + * Specifies the iterative improvement level. + */ + public native void setImprove(int improve); + + /** + * Returns the iterative improvement level. + */ + public native int getImprove(); + + /** + * Specifies the pivot rule. + */ + public native void setPivoting(int pivRule); + + /** + * Returns the pivot rule. + */ + public native int getPivoting(); + + /** + * Returns if pivot strategy specified in testmask is active. + */ + public native boolean isPivMode(int testmask); + + /** + * Checks if the specified pivot rule is active. + */ + public native boolean isPivRule(int rule); + + /** + * Sets the desired combination of primal and dual simplex algorithms. + */ + public native void setPreferdual(boolean dodual); + + /** + * Sets the desired combination of primal and dual simplex algorithms. + */ + public native void setSimplextype(int simplextype); + + /** + * Returns the desired combination of primal and dual simplex algorithms. + */ + public native int getSimplextype(); + + /** + * Set negative value below which variables are split into a negative + * and a positive part. + */ + public native void setNegrange(double negRange); + + /** + * Returns the negative value below which variables are split + * into a negative and a positive part. + */ + public native double getNegrange(); + + /** + * Returns the total number of iterations with Branch-and-bound of the last solution. + */ + public native long getTotalIter(); + + /** + * Returns the deepest Branch-and-bound level of the last solution. + */ + public native int getMaxLevel(); + + /** + * Returns the total number of nodes processed in branch-and-bound. + */ + public native long getTotalNodes(); + + /** + * Returns the number of rows (constraints) in the problem. + */ + public native int getNrows(); + + /** + * Returns the number of original rows (constraints) in the problem. + */ + public native int getNorigRows(); + + /** + * Returns the number of Lagrangian rows in the lp. + */ + public native int getLrows(); + + /** + * Returns the number of columns (variables) in the problem. + */ + public native int getNcolumns(); + + /** + * Returns the number of original columns (variables) in the problem. + */ + public native int getNorigColumns(); + + /** + * Returns the number of non-zero elements in the matrix. + */ + public native int getNonzeros(); + + /** + * Returns the original row/column where a constraint/variable was before presolve. + */ + public native int getOrigIndex(int index); + + /** + * Returns the index in the lp of the original row/column. + */ + public native int getLpIndex(int index); + + /** + * Sets an initial basis of the lp. + */ + public native void setBasis(int[] bascolumn, boolean nonbasic) throws LpSolveException; + + /** + * Guess a basis for the lp. + */ + public native void guessBasis(double[] guessvector, int[] basisvector) throws LpSolveException; + + /** + * Returns the basis of the lp. + */ + public native void getBasis(int[] bascolumn, boolean nonbasic) throws LpSolveException; + + /** + * Resets the basis to the initial basis. + */ + public native void resetBasis(); + + /** + * Sets the starting base to an all slack basis (the default simplex starting basis). + */ + public native void defaultBasis(); + + /** + * Specifies which basis crash mode must be used. + */ + public native void setBasiscrash(int mode); + + /** + * Returns which basis crash mode must be used. + */ + public native int getBasiscrash(); + + /** + * Unscales the model. + */ + public native void unscale(); + + /** + * Set basis factorization package. + */ + public native void setBFP(String filename) throws LpSolveException; + + /** + * Returns if the native (build-in) basis factorization package (BFP) is used, + * or an external package. + */ + public native boolean isNativeBFP(); + + /** + * Returns if there is a basis factorization package (BFP) available. + */ + public native boolean hasBFP(); + + /** + * Solve the model. + */ + public native int solve() throws LpSolveException; + + /** + * Solve the model via Lagrangian relaxation. + */ + /* + * According to Peter Notebaert, this method is temporarily unavailable + * but might be added again in later versions. + + public native int lagSolve(double startBound, int numIter) throws LpSolveException; + */ + + /** + * Returns the description of a returncode of the solve function. + */ + public native String getStatustext(int statuscode); + + /** + * Checks if provided solution is a feasible solution. + */ + public native boolean isFeasible(double[] values, double threshold) throws LpSolveException; + + /** + * Returns the value of the objective function. + */ + public native double getObjective() throws LpSolveException; + + /** + * Returns the value of the objective function. + */ + public native double getWorkingObjective() throws LpSolveException; + + /** + * Returns the values of the variables. + * Passed in arrays must be allocated by the caller of the method. + */ + public native void getVariables(double[] var) throws LpSolveException; + + /** + * Returns the values of the variables. + * Returned array is allocated by the method. + */ + public native double[] getPtrVariables() throws LpSolveException; + + /** + * Returns the values of the constraints. + * Passed in arrays must be allocated by the caller of the method. + */ + public native void getConstraints(double[] var) throws LpSolveException; + + /** + * Returns the values of the constraints. + * Returned array is allocated by the method. + */ + public native double[] getPtrConstraints() throws LpSolveException; + + /** + * Returns the solution of the model. + * Passed in arrays must be allocated by the caller of the method. + */ + public native void getPrimalSolution(double[] pv) throws LpSolveException; + + /** + * Returns the solution of the model. + * Returned array is allocated by the method. + */ + public native double[] getPtrPrimalSolution() throws LpSolveException; + + /** + * Returns the solution of the model. + */ + public native double getVarPrimalresult(int index) throws LpSolveException; + + /** + * Returns the sensitivity of the constraints and the variables. + * Passed in arrays must be allocated by the caller of the method. + */ + public native void getSensitivityRhs(double[] duals, double[] dualsfrom, double[] dualstill) throws LpSolveException; + + /** + * Returns the sensitivity of the constraints and the variables. + * Returned arrays are allocated by the method. + * The returned array contains two elements of type double[]. + * element [0] is the duals array, element [1] is the dualsfrom array, + * element [2] is the dualstill array. + */ + public native double[][] getPtrSensitivityRhs() throws LpSolveException; + + /** + * Returns the sensitivity of the constraints and the variables. + * Passed in arrays must be allocated by the caller of the method. + */ + public native void getDualSolution(double[] duals) throws LpSolveException; + + /** + * Returns the sensitivity of the constraints and the variables. + * Returned array is allocated by the method. + */ + public native double[] getPtrDualSolution() throws LpSolveException; + + /** + * Returns the sensitivity of the constraints and the variables. + */ + public native double getVarDualresult(int index) throws LpSolveException; + + /** + * Returns the sensitivity of the objective function. + * Passed in arrays must be allocated by the caller of the method. + */ + public native void getSensitivityObj(double[] objfrom, double[] objtill) throws LpSolveException; + + /** + * Returns the sensitivity of the objective function. + * Returned arrays are allocated by the method. + * The returned array contains two elements of type double[]. + * element [0] is the objfrom array, element [1] is the objtill array. + */ + public native double[][] getPtrSensitivityObj() throws LpSolveException; + + /** + * Returns the sensitivity of the objective function. + * Passed in arrays must be allocated by the caller of the method. + */ + public native void getSensitivityObjex(double[] objfrom, double[] objtill, + double[] objfromvalue, double[] objtillvalue) throws LpSolveException; + + /** + * Returns the sensitivity of the objective function. + * Returned arrays are allocated by the method. + * The returned array contains four elements of type double[]. + * element [0] is the objfrom array, element [1] is the objtill array, + * element [2] is the objfromvalue array, element [3] is the objtillvalue array. + */ + public native double[][] getPtrSensitivityObjex() throws LpSolveException; + + /** + * Returns the Lamdba vectors (Lagrangian optimization). + * Passed in array must be allocated by the caller of the method. + */ + public native void getLambda(double[] lambda) throws LpSolveException; + + /** + * Returns the Lamdba vectors (Lagrangian optimization). + * Returned array is allocated by the method. + */ + public native double[] getPtrLambda() throws LpSolveException; + + /** + * Frees all resources allocated to this problem. + */ + public native void deleteLp(); + + /** + * Write an lp model to a file. + */ + public native void writeLp(String filename) throws LpSolveException; + + /** + * Write an mps model to a file. + */ + public native void writeMps(String filename) throws LpSolveException; + + /** + * Write a model in free MPS format to a file. + */ + public native void writeFreeMps(String filename) throws LpSolveException; + + /** + * Read basis from a file and set as default basis. The info text + * is returned as method result. + */ + public native String readBasis(String filename) throws LpSolveException; + + /** + * Writes current basis to a file. + */ + public native void writeBasis(String filename) throws LpSolveException; + + /** + * Read settings from a parameter file. + */ + public native void readParams(String filename, String options) throws LpSolveException; + + /** + * Write settings to a parameter file. + */ + public native void writeParams(String filename, String options) throws LpSolveException; + + /** + * Resets parameters back to their default values. + */ + public native void resetParams(); + + /** + * Prints the lp model. This function is meant for debugging purposes. + * By default, the output is stdout. However this can be changed via a call + * to setOutputfile. + */ + public native void printLp(); + + /** + * Prints the values of the constraints of the lp. + * This can only be done after a successful solve. + * This function is meant for debugging purposes. By default, the output is stdout. + * However this can be changed via a call to setOutputfile. + */ + public native void printConstraints(int columns); + + /** + * Prints the values of the duals of the lp. + * This can only be done after a successful solve. + * This function is meant for debugging purposes. By default, the output is stdout. + * However this can be changed via a call to setOutputfile. + */ + public native void printDuals(); + + /** + * Prints the scales of the lp. + * This can only be done after a successful solve. + * This function is meant for debugging purposes. By default, the output is stdout. + * However this can be changed via a call to setOutputfile. + */ + public native void printScales(); + + /** + * Prints the tableau. + * This can only be done after a successful solve. + * This function is meant for debugging purposes. By default, the output is stdout. + * However this can be changed via a call to setOutputfile. + */ + public native void printTableau(); + + /** + * Prints the objective value of the lp. + * This can only be done after a successful solve. + * This function is meant for debugging purposes. By default, the output is stdout. + * However this can be changed via a call to setOutputfile. + */ + public native void printObjective(); + + /** + * Prints the solution (variables) of the lp. + * This can only be done after a successful solve. + * This function is meant for debugging purposes. By default, the output is stdout. + * However this can be changed via a call to setOutputfile. + */ + public native void printSolution(int columns); + + /** + * Prints a string. + */ + public native void printStr(String str); + + /** + * Defines the output for the print_* functions. + */ + public native void setOutputfile(String filename) throws LpSolveException; + + /** + * Do a generic readable data dump of key lp_solve model variables; + * principally for run difference and debugging purposes. + */ + public native void printDebugdump(String filename) throws LpSolveException; + + /** + * Set External Language Interfaces package. + */ + public native void setXLI(String filename) throws LpSolveException; + + /** + * Write a model to a file via the External Language Interface. + */ + public native void writeXLI(String filename, String options, boolean results) throws LpSolveException; + + /** + * Returns if there is an external language interface (XLI) set. + */ + public native boolean hasXLI(); + + /** + * Returns if a build-in External Language Interfaces (XLI) is available or not. + */ + public native boolean isNativeXLI(); + + /** + * Gets the index of a given column or row name in the lp. + * A return value of -1 indicates that the name does not exist. + */ + public native int getNameindex(String name, boolean isRow); + + /** + * Create the dual of the current model. + */ + public native void dualizeLp() throws LpSolveException; + + /** + * Returns if variable or constraint names are used. + */ + public native boolean isUseNames(boolean isRow); + + /** + * Sets if variable or constraint names are used. + */ + public native void setUseNames(boolean isRow, boolean useNames); + + /** + * Gets the value of a constraint according to provided variable values. + */ + public native double getConstrValue(int rownr, int count, double[] primsolution, int[] nzindex); + + /** + * This is an internal function that has been published for special purposes. It should generally not be used. + */ + public native int setBasisvar(int basisPos, int enteringCol); + + + // ======================================================================== + // Callback methods. + // ======================================================================== + + /** + * Calls the native lp_solve method put_abortfunc + */ + private native void registerAbortfunc(); + + /** + * Register an AbortListener for callback. + * + * @param listener the listener that should be called by lp_solve + * @param userhandle an arbitrary object that is passed to the listener on call + */ + public void putAbortfunc(AbortListener listener, Object userhandle) throws LpSolveException { + abortListener = listener; + abortUserhandle = (listener != null) ? userhandle : null; + addLp(this); + registerAbortfunc(); + } + + /** + * Calls the native lp_solve method put_logfunc + */ + private native void registerLogfunc(); + + /** + * Register an LogListener for callback. + * + * @param listener the listener that should be called by lp_solve + * @param userhandle an arbitrary object that is passed to the listener on call + */ + public void putLogfunc(LogListener listener, Object userhandle) throws LpSolveException { + logListener = listener; + logUserhandle = (listener != null) ? userhandle : null; + addLp(this); + registerLogfunc(); + } + + /** + * Calls the native lp_solve method put_msgfunc + */ + private native void registerMsgfunc(int mask); + + /** + * Register an MsgListener for callback. + * + * @param listener the listener that should be called by lp_solve + * @param userhandle an arbitrary object that is passed to the listener on call + */ + public void putMsgfunc(MsgListener listener, Object userhandle, int mask) throws LpSolveException { + msgListener = listener; + msgUserhandle = (listener != null) ? userhandle : null; + addLp(this); + registerMsgfunc(mask); + } + + /** + * Calls the native lp_solve method put_bb_branchfunc + */ + private native void registerBbBranchfunc(); + + /** + * Register an BbBranchListener for callback. + * + * @param listener the listener that should be called by lp_solve + * @param userhandle an arbitrary object that is passed to the listener on call + */ + public void putBbBranchfunc(BbListener listener, Object userhandle) throws LpSolveException { + bbBranchListener = listener; + bbBranchUserhandle = (listener != null) ? userhandle : null; + addLp(this); + registerBbBranchfunc(); + } + + /** + * Calls the native lp_solve method put_bb_nodefunc + */ + private native void registerBbNodefunc(); + + /** + * Register an BbNodeListener for callback. + * + * @param listener the listener that should be called by lp_solve + * @param userhandle an arbitrary object that is passed to the listener on call + */ + public void putBbNodefunc(BbListener listener, Object userhandle) throws LpSolveException { + bbNodeListener = listener; + bbNodeUserhandle = (listener != null) ? userhandle : null; + addLp(this); + registerBbNodefunc(); + } + + /** + * Stores references to LpSolve objects. The key to this map + * is the lp_solve lprec pointer value. + */ + private static Map lpMap = new HashMap(); + + /** + * Adds a LpSolve object to the lpMap + * @param problem the problem to add + */ + private static synchronized void addLp(LpSolve problem) { + lpMap.put(new Long(problem.lp), problem); + } + + /** + * Retrieves a LpSolve object from the lpMap. + * @param lp lprec pointer value + * @return the LpSolve object or null, if not found + */ + private static synchronized LpSolve getLp(long lp) { + return (LpSolve)lpMap.get(new Long(lp)); + } + + /** + * Removes a LpSolve object from the lpMap. + * @param lp lprec pointer value + */ + private static synchronized void removeLp(long lp) { + lpMap.remove(new Long(lp)); + } + + +} diff --git a/third-party/lpsolve/src/main/java/lpsolve/LpSolveException.java b/third-party/lpsolve/src/main/java/lpsolve/LpSolveException.java new file mode 100644 index 00000000..ec6e4c38 --- /dev/null +++ b/third-party/lpsolve/src/main/java/lpsolve/LpSolveException.java @@ -0,0 +1,44 @@ +/* + This software is a Java wrapper for the lp_solve optimization library. + + Copyright (C) 2004 Juergen Ebert (juergen.ebert@web.de) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package lpsolve; + +/** + * Exception thrown by the native methods in the C stub DLL. + * + * @author Juergen Ebert + */ +public class LpSolveException extends Exception { + + /** + * + */ + public LpSolveException() { + super(); + } + + /** + * @param arg0 + */ + public LpSolveException(String arg0) { + super(arg0); + } + +} diff --git a/third-party/lpsolve/src/main/java/lpsolve/MsgListener.java b/third-party/lpsolve/src/main/java/lpsolve/MsgListener.java new file mode 100644 index 00000000..b8d58e4b --- /dev/null +++ b/third-party/lpsolve/src/main/java/lpsolve/MsgListener.java @@ -0,0 +1,46 @@ +/* + This software is a Java wrapper for the lp_solve optimization library. + + Copyright (C) 2004 Juergen Ebert (juergen.ebert@web.de) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package lpsolve; + +/** + * Classes that implement this interface may be passed + * to the putMsgfunc method of the LpSolve class. + * + * @author Juergen Ebert + * @see LpSolve#putMsgfunc + * @see "lp_solve documentation for 'put_msgfunc'" + */ +public interface MsgListener { + + /** + * This routine is called when a situation specified in the mask parameter + * of putMsgfunc occurs. + * Note that this routine is called while solving the model. + * This can be usefull to follow the solving progress. + * + * @param problem the problem this Listener was defined for + * @param userhandle the userhandle object that was passed to putMsgfunc + * @param msg event code why this method was called + * @throws LpSolveException + */ + public void msgfunc(LpSolve problem, Object userhandle, int msg) throws LpSolveException; + +} diff --git a/third-party/lpsolve/src/main/java/lpsolve/VersionInfo.java b/third-party/lpsolve/src/main/java/lpsolve/VersionInfo.java new file mode 100644 index 00000000..6d7732b8 --- /dev/null +++ b/third-party/lpsolve/src/main/java/lpsolve/VersionInfo.java @@ -0,0 +1,73 @@ +/* + This software is a Java wrapper for the lp_solve optimization library. + + Copyright (C) 2004 Juergen Ebert (juergen.ebert@web.de) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package lpsolve; + +/** + * Contains the full version info for a lp_solve library instance. + * + * @author Juergen Ebert + */ +public class VersionInfo { + + private int _majorversion; + private int _minorversion; + private int _release; + private int _build; + + /** + * Creates a new instance of this class + */ + public VersionInfo(int major, int minor, int release, int build) { + _majorversion = major; + _minorversion = minor; + _release = release; + _build = build; + } + + /** + * @return value of the build attribute + */ + public int getBuild() { + return _build; + } + + /** + * @return value of the majorversion attribute + */ + public int getMajorversion() { + return _majorversion; + } + + /** + * @return value of the minorversion attribute + */ + public int getMinorversion() { + return _minorversion; + } + + /** + * @return value of the release attribute + */ + public int getRelease() { + return _release; + } + +} diff --git a/third-party/lpsolve/src/main/resources/libs/linux/x64/liblpsolve55j.so b/third-party/lpsolve/src/main/resources/libs/linux/x64/liblpsolve55j.so new file mode 100644 index 0000000000000000000000000000000000000000..227e41fdf51a9164418210b940392f28e1f6e486 GIT binary patch literal 127393 zcmeFad0-XA(l$OUVGBw`P{b`DDj-T&1>C|C3=kkJQN$%=gM=lCS&&6EvM3=J2#5-} zMXn;^7EvT1VAvyqL_m#*8bNRZs1X+;qWqq!?w(XmW)ArNzVH3(n|p_z=b7s2>gww1 zo;l~lN5dle)~r#(GDj`zc8gH)D#e8A8x_+kWkRiPRvjzUYGGZ)vH@DgtynZx)ib4K z1+y5jb?9n>);pmE^Oi0X0~Ku6P?e@$O+c#GTGwl>7tS|vV>-(AIMZ=H zj*|{OJS?B1D61~&`5pr`u?^+BIER{saNQH9@zc-XV}M)Xq~kszNBCkN{3N&zIB9qf zp}Ys>a4jw9f!CsZ9_Jf4U)J}pL3sf%9f_J#Nd5Z~xG+uZ$MpeR_eR+Rd@RnVfexX}MfsP$-vYQN&IfSPu@U8CC{Hq~ z`p+o93vquo&a*gI;B0_145vK)1AGsN7g6p)NoisTt{>5I6H$JSbC9l7NAusKyh3xe zbUz6GjB^$4{ebfb&J)1lC@sjmiozVDiNo=$D)`?S`1b|P8@fMmoCZ&!Of@%9zK(l4 zeB{M#YoX7*uW@q-&g0;}KzWJ2f03}C>fcBI;3&lXt~i_N`^Dhq@g4O~L(Lxr+==r+ ztuGnZ!8rSBd>Yqu)BxV2Im&NmaGj=c7VvfY`UPCm(FFRBpzN%9;v#Up2jva|IGO-A z6ZeU`l>Wid6#PDQX>GvuF`6I5EiaHy$3>Cd`zNGOlDBs7qTI1(Xc0s*IHU1jc zr*QoT%E>t8QK~_jE-%9USF}td$_Vfu=zFqgt7V4ivPj>27UeE*c~V$hZ^yl#fZxGs zjwTCt*b4#^*A5Y_x^+OJKP(o?`zsAChMzvQJ&H=SD<_oI2~mm&KGfgxt611 zD!6q5(`6L6MmYQ8dMC=?anjKM;~S6bT%0R_Z%3KQcPuLa_rApSwcxhlydLLP;I$~} zNY>@s3OfI8a;_}vD_q}>GhT3Cpxy$U&w!h&b$o*Br8uv|xdkU39rQiA-iqrMDBEf7 zG|B>;ALG0Xc22~-Z*jc{=XR=~k0RjPaMpuN1I;Z4reiS5+3M12uQ`Ih;rfKe^Qgr6 zGKz+pBbht(b#3VV9(W~@IC8)*R+rWjLSAoy^c__^kNe+MVX6YC{$D+sokwez_%Z6Z zuAia%T}SBai0jT8UxzYCU)R#*`4(?M_bpog`PL!1n|*})3p@$>ws`2g1#(eZ_BqH5 z#`S8H@8KMd>v|~fM0poVI=<4SLdfs9_(*fDaot?pe@a{%dEas?qiS* z!r2ML<0$8w8@kN)!ESJqZts1Rky_v;l#_6lfeX}ekf7xjf=|KqAe^H#N7WY5Kl+#s zzBSIhI9uV=+kU>g0smeAog=_^#CbVRa}2=sEDb(H8ES5z{71|E7uN%DcE{NUTmj0v zQND%pcbxa)Iuz$8IL)yJ7Zt$o;#{D~+jRLFxC&ff2%8R~{7lr-B2|i8asNj!HBm<6 z{7B!u->2TyqE=mTZ7$!2d}9Mp=IiTqTF+eI89q9NxHSRbA)Fyv<|mYOUF1)KTLQTz zID>J0J<7|pToSJ7II9Z&_X+$v2KR5mxm?RN()Y)q+^w&v*sSjx>UDkbfFVR#U(4Pv zICGh=@1>$#gR?u%VYqoW&N3q;%BC2rqq+{!7wdaBfV)UvcR@K&%lw7%GR>Q!mZ;xS zlMf5-6(i_U2BCdA4nw{d&Kq^TJW*dssDD!gm@2N#<=?odp>;NfjtgA$EYVyzWJlwi z?;>OLQTgXN?w=9DANa^7;@-31{_De2m50CupzMaTwzz*4@EDx(=%MeA)8#WLV?-Sz zdlk5m0Cltv41W;(KL+@e^?h)O(0hl^y=59l`|t!m74_upCpG`7&;51~x=RSw#`So} zT%)-!as8oB9U<=b@@ZXfrceFd8ZXo3!&=MDK5|6gfb)RnDId`M3C0$4YNY6 zCXKIXY28w>pl1D``VGFhFerwBD$G#7}=%3@8FaE5_tnhp*JZy+{ z&5Gh$kJasH-S_hHkY$h6&daOSvvJFMZEF$(v^IiZn}v61mJV0OnT7K)oHQpN$2lA49Gw5bIS;4F!wYduIfM3kG>@ObxdbO2 zOHoojeGVr*3z*|YT<76@3Fm(W|1z$ZYrF#G>-zc)UA~3#ZJh7or2Xk?oNIA<9qVv! z15T5d3bpJeQD+OT>Dg}w&LW(-#-cLL>4I8SQ)yDtAgc?##B8vmusGbsP2YpfBpR+{%f^jt;7e~9y*r_IhIG){P4D&SeFyC$=zR-4SH67tpY5ONwrW`GOFp^f?YCm@kFWds z;X$82u%OMfh0|KSfA@xihi8ubCaG=E)>W5gwAm1{>!Q~4zPms9zHu-0OYL;`(68H% zeP&faMEg+_1A~8<_ebBs&s%Q}+!Ptx>w>R(|5EF-_5U>aeZt>yVV4{){O*bHui}=z z-{rQWx6aEcT>DwQ)L~Qa?EB`9+<{x0CyZD#c*kqICVc$v7fEXide3}g{l}4i241|{ zTCu(Oi3{uY-T!v8HtP;Ae0bP^V<~S;y?(=y*;zwxom^|-jPCz@^ud&myIi^Wi&nk< zzBI9Xe&;vO798lbd_nr_drsXrHSOj{{`q0en9XIg&rIv|!7m3J*U8PlA$CdBqs^Q2 z{c~SHH!EPq>6u}DrX1;cd-9dLhBf~o>Fn<3Zv0_hc>Pg*j(xVR&$e}M-|_o~B{RQR zxpnwU|JfhW^tzG;cU)*?-XBqTWk6Qgu}ikq$@})IzXCSj6@K>ql)UDjy!YUtoa83c zqON}Z@K1+cK6Pv3=lk>y`|QL$2g~<9`CG5i&)qtATlACH?aO-UAcRZTvt-E8uoDLtm{tv@OMjgr?kM^B8bKkb6oLzYL6z5DTq z1yf!P{&dXp;ME`gzAxgQvd+<;?Y;5!!|fl*PI@!tg+T-MuQ{;)GN^@d!mvrtvz;8eaw!4ffX4~?zpGR&vm-i?Q!FnhP&tWzb}5% zl)8roe0OZ$&lk?`{>a~5`&UeSvUBe#S3KGz{FQnQKTQ5(+oA=ZtcY!X^zZ97Mdw$% z(kuJhquVYU)a=Q)7upYa_h{JRvRy^DE#H4xuU@+X(wBTtc4w=&(U-@sTs!xd3s*Oc zZnI?9>AD-P3%}ykMO#A_En2hS<6E2DKlQnVbH}akvooaqn>${sxMAR(@!c~I9qQO= z>h(npP8_=L!44sp-yi<|vcE&-H@@fHP>uBo_v&%Dj zUOr>X+Fiw8q+UMx{hSkD%r4s-HSLn!A@?uNxVBrLPYBb@ZJagkjaqkHJbT&N z9((uSckTOaYTx$M_uuSm{lTzFA53W2s&m1pH9w6W7$5L)x08c5Ebq6Z_xktp4)%WP z^x^B4ty$0m+>h_np7P*{2Or$9;#5WXv&~=qd)3di-t6A^nkCyGZWPpa_w;v;&so;? z(3!D!?W!3+Zhg-qCmNhO(X-Y+PY?Zm<>CA`dB3lE@d9hW+!3p5-n{ms`;Khh@zUJ~mb@c1c&)**Y}HjOUR3{R}^+#a<(w@<)7ae^Uk2#<~%!Z!8@N6=FQ() z(C&pRALwu>{nh2${_K@#s|@G zT{phLh3@x8e{b~|m)AVjwc#Fl z@->h3^nH)~R?A}?i#_7Mkw-iaY2e=9hduJxERXm+<&m#$@$lye4?Srf^W}Gsd3uw_ z_} zb#SA{d|cuYw{1N314$lnd%z>lFY(x4ZT8U9(&IVn4v)Ol(Zl~^Jo5QwkA28qk9dgm z7_XN-_7B&1%&%j??(^|kkM(G|$M_!i7{~v5#Ak&^{6~58_hOHDnCYSCeUCgm!($&l z!y}&z^N6=+J;w2SkNHyUk#Bo?*g4QE-a5LE*DjCoTIv!1b3Ed$pNIaNJ^b9t!*5+Y z{Bwhc|6@Jo;{cERpY5?fJmis=rh1Iy84rG_$3E?5kA1~_kG$H-V}5<@v5rJ}jLUG3 zxa#2HhuR+diU&OA@1-0+fmW-nYHPhu@36b^J_r0}MNHOwFJ4art!BFwal7U>plpe6 z0z9C<_=;tbk5cw?ptZko4aVa%--YLUpmpJIiugtIukgMu(5g!xNaGl)`Bpq%0x8CY-EJv;xdKN6-EN#7m#cloWtrAr?xTMd6b4zpoNYF_g|@>U}y|KLtVnD{xP{rQLXr;)E$ zN6F`|QSwNGd^FZ^8>!>gv^z|XW8S5z-4ZSTH}7)-ts5IE{x{9H)a|y^?HYe3W8Tns zjcTXlkw*CVQP0O6EfoKa<`Xr){c6Q8(frqe%Kn+#74fR(hv|7VPR}D_f0ufy-D4e< z9`hZZ1KQ82dz1nrUrXoP1G^M&{JCG}y=nC29vm~(ZEG^Gzk$||A1T7N!#>wY?(3w`4G10A>PwkW-(zb|ONo!qT>Gw;5?t{+FHpk((+$w|CIXprxf=o&L7w7at|$kNYA5ZnkzjfZ_m|w zY#%*CwSQV`{}_8-#0BM(L@lq?^Y6Z>-OjpQGr#KUc1xS8cD0+Vox!SK$G=k=%=*|J zko2tAc@^QxN1*m|C#|5f=36&Xdfwith+x%>wOa2tI{cw{Gk>qv=07=i(MhfA_;m-pr$#T0YlDzLs7$<8<71 zRn@FnIuAdm^Kg63uhe_Q~@lT2Gjdp8nczi9Yk< zTb=jn`o#a7R;u0LA60{Sy4|LFpYRHO=@7>p&EKK(N!O!_cv$m`bl#q$^L97Q)A!>j zP9C5yCE_q~{(z2$Js&H<8LF`2^*k!NPRY;Ld~-eS4fVL2IGoy2+5gG+O3>t!)q1=t ze8#J`p4WF=tn{1twX?C(^MX&DJgf8YD}O5e2emz&b-UN-c8xu8Hz_@Ru2A}CYWa6{ ze*5_wMVL65pz~E%ov$z*_&BcfeVv^BaN{ z-{L#P8^0B{Q2b+h-WmD&TK??zK+k(yA*Hy|Ax-1J@zQx#LrVY z{-gB*rOma5*H!I4uujRFeZ{`|ivMM^;!S^hU8wj?A1U7W=N`RYe5cn7W9L(P9HV^3 zae~(Wyw(qQ@zDVaX&e{pJeH#Q`Fj1`rt`e%?}u%aeD6Tz=VMy_+uFoe|DIR}J&t$y zjN>~Em7Z&S=5<}22d?~8DgH(4zZVmV?ELit)vn2(`&%piwVH}I&&AK{d3xrkQZQWW z>7f1domOD{_Jy8zGfyhPC0ag6$N!gy713YwbL*&f@6-8qvgXrTDE==US4RILy$=3; zjk43s(<^j*-mD$@r`EGtk8f0|B8>l+B2kbZ-YrzTX?L#n+v499Z|u*}<9nCSJl&x4 zLy0!TDuKiZJ8#R0CztlRj}9qy2pLHzjZUyc`C*?UU2=`g_-ICI6gm_j5gt?KUamQO&=l z{Eg!|9lTW)41%?`$j!otv~eoyI((FJgN1U>HZ$o z{WX3F(EGh3Un)VvZ`Sd=x0Q16Os%KkWy+qbzEFgTp9y-NUa8+}4bt*<3nl-io?i%8 zK4$BE_&<6dK2G!fb^ILD@e`r>%XK`g@QH^D^!VQ3Grk{af8MO~s)@HFwN+eY`RMsZ z?-N?;`C{yh)9n`f$oJI!J@&UUuv1M{PS^f?=77Sc-EFu}E?LRpmSC{=VrGKksWlC;7a;t*i6oYOUY&_ul48|Cc`NV;d}3 zl$VyDQtjqxdz$F=>nZJLqi60_O8%X1l%R>L$1hd<8$N!{*7J8$xso5C=k>=JFKYL@ zcNPCO@&z4>^*VKJeI^?rlEp4$=1atx)yzRAG$>R{9gZQ-rZ|w2t$oI?heM z9@Ftqgpa?Rx%>*7MisFVJx~$wyCjJ@4A_Ovry;x9-69kLq*WYI7dP5U`k`?;ICZACX!@~`^L>qpxve$RzU|6VPB zgPwQS=y_-SKlMf>KdG6L*V`Sdy^gnrKPv^s{*Kx|ll60@@&78_?n{l79zAWWF&Ibk z+Z3ILTWWj$YNgtp{8Lr^z4SPKvPbd8&J^v>qdGpdyRA#~d>N$Yi}Bk=JukNDd4Y7n zM}^kEQ^$#suh4NDF1YdrOt}easG&obF)6aSYNffbF&hJTlkovnC}%aM)O-ykH&HF4N8HD|3@xT@@MosGJc5A^X}AEr66AG`4SV2^w-nx z$4WF`8+nWLpVs-mwdU7o|3_>88~rDAK2P$=tMoU5NY5EX%-wtnt?NpT6O8A&P0gX7{d z)6x>+!zM}<9Xj_(7@v@l5RnoWGk$2o=&;Cc(PL9$$0o#OR1xbQmYklMro?*3q{hT0 zWlRo3Pb$sq(BaO6jDZOmi7D~@`cyG!SSNH`2!=qgZ&JeebIEmv++a3^rG;sc-J{2j zRvM~k?uZ%@Dam8bTYlI%<;PcP;AS*1EF&f(Dek;_+7V+jEF&!`c}&#szP_W^K`GOB zdnd-ErE?e4xk6;3Y`9~Gp%|u^^aMv+HTkNc(Se-TGc7G_D>ywfhJ3c|TSH+s{u(@Bd zGCNFZhD$nxM2}6;dZ86E2oJvP>mNlB40(it5?;Azp6Q>kjtP;EfGtk-Ql z%v}ScJ9O`vkr5M@*qc&8at888LQH&EWaPwQA<-7{P4wX8h?JOkYfSXmi4!ytl{}uP z{?HITJ~cgM{KSOlh}2$gZiG8Sql1$?BC8B(f{`v;@lR zU7^5T2sb-)=|3ncnp1wS$%A4hBvk4e5I3wN<=75gGH6AJPB2MdinxzpnqGK%afi7> zq$f5uIvKqsOpAxHF>+#(MI8~hW$<2NdJkL7W6Gf=KIok{6kDM|6?p|yh!6yFZRA02eGRlOBiWi{?_Gqu$# zB?XB(`8=BIGcRCT*AsJyHg?|R7B z%9`=1?)^+lNKeR!j7f``kZ$pHbgBZbIw9LDCOs*AVoaKa>*!bmT&0owl-+m5jL%H4 zC>1KJqbD-qS_x{S(i12frgIaS=?T%vj9kT&(jDof^yqU4k5`M_T?uLF6g%TnDR8j( zP1J;I3ox6k!InK?68C|uQOH$3DSZ&OlM@q0MD(*@QnCYFr4wV)Nf1Rem0mKv`bM%0 zm98?TRT6Mo^_0#`PN(Q}SA`DqAjhS}q$hHZd6*S+ZQO)~5^(~wPINnAkqRxlc2Ve}vaJf)q!4)WF-ubwzl zF_QG?i46~yypEk|cXKB_UeObgniTwyQ@Mx1T87Of?m`~Z%6&XJfkBDMtGJ3D89zR9 zqPsY{byrLpC07IuVvGk02`id%tfstri;9tHNfR77auHR936-Q*<-1eT#-S^f3k}tN zNRiR!SZ*L%wca`8lhXU*;V}uz6V3L~=Gx0N+Q4OEn?6Z-11~QObgjWz(bK!bQ!--4 z)6Q9iX$C>wTc&$f85lDuB4J{}cpi%hF_WUlGjeSluHY8>;pGX-s|Jz?dQ}*dFb12) zF=~xTHo#RH*~yWnOyyr1#tciEkUAcoo1CiDrwi=Wf~-T0oKKy|w1m+KX%wWq?%@H# zK-X51(j${54$V{nkeW0xI*qQqMF(QQC{{>x0$sa`qQ6j^l0j1v*Cefgt2DaiNK-fc zOG97338`r**m99-xRI~DG#gn`>{k}bc;hubX#$>INi{ES3VLZ5HF$t%IrLK_DIL!- z31hHNfFL;sp2TKMGOjHprE^0ZJgCBkG4LnN!(*iVjuk04LuD*;)r>wGS<_vr=PC;i z_QG3)aXpbo&Au&`i0Bx~hD5p6gW@XnsG;+zmz1un^-W4k&mhk_wMH{@j@DGQDy{jc zhu*0ykJU9}GKY)K@QQG4OjS~kP)-%~{N(Nn@?mV>@hK^3$`oLF#2#JAxVA$sl-0OX z=dK3rSUq~BWG3T94_d`Z4 zxpvhIn;l`Y-@j(q(K9(CsSlEFG8+;DgyALVsy->bQXX05T;i~xQl88?R|V*gkH^;A zDd6AGxITJ_)gzyfVh~g_ns+jI{ZYXg&{_k{pC*rQ7J7%O2luo@cPk+=Fe&xUm{gTyl2W6`;M%KUElTZ9@Fxnb>Oq6Gs)r1BrH~9u zO;1fo%g9WNW$A=U=w*heL8hFmhHis4uucmM{OM-_qupCt>DJFPFa%eAwBoK-=_RN1 zsl^-WJU*L&68IqADD#j~x*V^@`m-$7=<<+Kx-gZD2kFvJPwBSqs;4AvrRhWS49;jt z=Gs*&+INI;jV-sX=_-wu9ci+{zcjYy2@{g=LXx+f>E_y1Gq$MsY(H%>Z%);fhg?6U z&a?OE#n8l|&a-M-Vzhd2byWvp-qfWJPa2bG9*22jmmZy=Dc6eVebtKOj`OLA*N6#Y z_>CoX70<@%+O-k9dQE1XNTLwVbbzZg`Vy5Io5F#VNf%yH5h)L8vGIK6DwmXwjZe}9 zY8RUxT)0Z1*TWK$kzT3$>3roSHxLmyf#oLfm8TrHM*94;i@pwwQFCSjN>^P7zrn-s zBtl)l6}@J17ere_6Ys*OiLPqU)L^_f#A`fyNzLA+*M`9S*4(pFZ&Bf#!qfsbHdR^x z_TK_FMotC)!e}2aJ^Ll&!wPkYnM>~wT|1nVu0B&3PVZyjJN=1*_d_*26p`v!g15oR zFY~)16cVYR)1nmUp7kT_pPJxohAsyjf;*;92Y%0 zCdp%kV`1LW#b-`1A2#v6jTLaf1tt_{)fhV zN`N8s^C1CRrIDt_JwJEh#>_~omT9ObVBEc})Ssm(aetqs(O5elyunz1vaC&YOeyx$ zGZvtTQa4K9Ir0jwc-&XBTWnA8v@-?l~#`=e3*wfMR;S9FsX9Fh)?0G zet&0J=Vp>Ow@W`V+Eh0HQ9Qpa^2olboo}~S6>LHLha94r`njihcF~7ciE))9NTP?r`dHJ7=JCZ=GS3N>0gC&L6IUX$2)g~Grhv0%A&7#Ll zniP#!py?^}tC5V!(Gx?g@%ToE`a*V>E;ps85KhmCkGtUpfSbA!oZwu=Iag!i;-b?D zb+Don;$t%Kwe#p$Y>V;ymWCgFB;Zp)sdy|ztve(7_39nn@utqsRmYpUSiMJ#=-I1Z zbcdTdDSE_+=uQy%zjEM*H~Of&GR*&WsegQlW-G7$H*COHfNOPIZlkm&PTGn3u!#k2s*7r!m zzPHCAr~|BTG?&q4A%3}A(<;;QBYb|B>EIOg%Sim}Uj4T%Ng0kH!P9^9&m7GJKUna= zf$zf=428jzqy<=&*37;2Q~klHe&fnIlW^lf*dA7Ce4B z?Hsv+Z|t!6I}U=!Ps^PnPw-6~*0NRzzME(_U-0;o3(ip>c>IYE=O`3Beq!$&MS`dQ zHmEs@1wUT2TO#;gf-e<3{`7%!*n-EOK5&k5!Q&_4&QT$F{E36gdVe#Jr7W}n>A0_zf1fMAQHiAzTJpR;!b4(Ka4GxR{_OIaalYi%!EqMIt1Lw#U zJpN>Xb1W8odxyn;`&aO^A27!X!FMnu%6!4=C7h$FBH6da48ae7a?CP_z%SR zmI&VbEeNVsD)^g)9$WC{Z++11a=~{O@)d$Nf0Kc4(;wo(LGgbJU#WlU3I0~W2MPW* z!8a4U`P&P0J6P~{2>I564;6ff;Cl+bo8Ws1K2-3%1s^W>K7x-FJpFfy%`rmoVTMFG zO7MLJpD6e{1)nPTaKTR!d_Tcw3Euqe2)aF6@B@T=uHYjCzgX}C1)nGQL4sc)_&-G) z<_mtXkS`E?q~Hq$KSc0Ff*&gQV!;m+e2L(P3%*qFQG&Mxf0y9P1%J2TD+E76@K$4nAmj@LpDg$y!KVnmSn%>Wr9|)#3i(pOrwQH`JpK38%~3A+ zbVH)75PXKvB@FhY|q2Rw1e39S}2)8Ufww Xm_x6_S*09Z=2ighLt6Ask3Jgz!}CE@D{r!rnfxHaKXjF%E_LpYN0Lc(nchccc+_y)oujHeTBM>v@A6v8(W z4q}`}_$I;@6D~i)<4-t*a4F-FggX!}W;~Q|N5X}S`xEX&IG=GZ!kr1{G44UQ z3*lVG9SL_OoW-~;;hPDkGHyw@8{tumn-lI%IFfN=!aWFwGHyWl7Q!KnYZAVda4_T3 z9|PY;IEe8{!nYH)7#|~i2jTL+c>D>65-w$YfN)R3#f zJjUw?hY`+YyozvN!dZ-0626mgD&u8@!wHXKyp(W1!jX&@67Ekpl<^$G0|R33Ex9Fl5u0gBMFBxZb0~6!Xb=n z626acFyqrZf$t|A#P}rP2MAk?j}eY0T>dAIKjBe?OBo*^97DL6@m|8QgbNw(BpgRL zpYdkG@r3gjuOpm5IG6D%!lMaiF1uBN;CwJeF`M<2i)K z5e{KIo$z?V!HlO6o;mp z(+TG@?nO9*a313xgfj`}GVVxtBH=8?Z3#a_IF)fr!jlM(V%(hYWWte*8xx*FIFxY% z!cz%{Fs@1XVZy*BdXAsV3yqWM!!g-9>5uQajm+>mXj}y*fypr$}gi{$WBRre%D8@?(XA_QOypZr5 z!l8`k5Y8bS!gxC2{}2vlJcaOF!a5|c>D?H5-w#tlJEk;#f*m% zUP!o*aeu;363%Dbi|``Cd5n7yeu{7|7vgg!35pAiSDzF5`}b-zS{KxGmu|gi{%}BwRpv z6yxTE*Ak9o+?en>!l8^C5dMI02;-WB*AotAe0m4)2Esv%PZHip*kXK)@P~xUf93Hf zTu8W-@d3h{2p2QnOL#NkLdH7@Zy}t|cr)Rxg!34$BfO1pF5^{%w-e4{ypr$^!l{gx z5iTM;it$py9}$jZypZrt!l8`k5dN5O2;=F5cM%R|JcaOX!aV1( zdHe|%6E0;ulJKX5iy03kyq9nxmW5Ndrhca$J_$$I8jB64;NI01B>FvN@6Aog0lJGZ#Eyl+P ze@nRh7ao7YrG!fvA0Yf4;bO*n2_GU{$ap8=!-Vr0ZzlXb;XKCc2p=Jw%Xk&xqlB{< zuO$2f;Z(-U2-}25F(Vnk8uyezZ1@7+>!7f zgtHj8C47o-D&v-fD+rHb+??>Agd-U@CVZN3DB}i%{~{d1xF+EU&4lSIvt@aV z*Ab@w%1>D?<5h&~5YA$}l5kzZsf?Equ19zjX~d`6dHULI>~^Hmaz2o45 zt}V%}$1|0ZTUAZ2p_03jP7 z(9P}a)i8`2jT{?xT-D{ypTfeU+E`6t#!hEB`^Kt*QJn7T^NUi4!XkA0>p9VVS0;W0|}rjb+0 z7COdL_3XFG*zMmiAj=n&0LmavJMvgnWkZ$(ju@5UnM{#mT z7pOK?(d|queahzErmm8+Uq3+|WkvHz@-KEtSP2y2WJR-;qQ~iWJ4aEPqsYi5E4iPh zL9VtV*Rrad-2)9e(>2(c@7Ylppn*68lGeZrIW#dTMk?&JvOR9m z8;PJaJUfayLte4%D^>3*!e>mYure+R&*6I&d~XQFikexry-4a3jYhFen2=9kr0ryQ z-RVnZi>9?bP@?8*z;ExHPANn7^I&4e%$QbgWn6%6*QDNLhm{y|hnk`}bp_;YgG7vZL0cF0JLri(#~J|_S5QMTw-V-jNvID&Guv!dNjX^?K7A+GYcC%RfvCP z(NhUJXj_?0wfuM9J+AkQp%W@*ptP5rWq!?RCEWPhRT9)jGH9d?Gz4r8;qHOSge zmuZh6ZP?iiI2eoVhb!-t*eL)xVP~8O_#X_!%=gHndLRaK1oA-iq)C)QL+&~d30%!* zAj)~pg{gr^$E@))5W`9Ti>P1*qIVUIw%rLY3#t#qK&qCAYCI4(`_wtB)+ZW>gYR;` z&TAlwV5%92^_Vg<3!QkrPI68k8CpMj{LIQ5(vb1BgU{IyC9#CA#( zInzooBMPRX$46A&G&=)VLN%I31xfW1{TmfI`M62=pWW&~Bcf~tLs_&9zKjQ`xH&O}wG6t~hNBFz5!G$GE8DC)W!q02)$YKYx2G`RjYWw)q4G|tJqn=uTtNOUfbac} zfysC(JEgoM#-ayBwaQNIrl8X!X=Sb)3)=bXv54eqW>V;}_=-1jv^7C?dH@sF84G%* zuN(`?ey2$P98@SmEu@?t*smnI7~ya=QyXOQ|;OIu?PD}UGvFddw!V%vvEt!ks({)_<+Qn6iB zd8gF=0HFFHVSH*(m(OqY*z-2qyACxhdnvC=oV5Nk33#1a^vvqhxE2CuITI{%Y6eowl^T}fRyp#veWPsH*$ih#ozSLL*g230&)$)fdBV1ky_~QJs@w?k;8oZ$O49yPrs3*h zJ+xS3|6&(wu|UjEKaHNC@yp&}_rcQPh`DxTvy!Ba?C{vp>y9keIzwfDNvGP+n^=F4 z#pr1m4+*U>9i8@NMhI>e(@p#B zZ<$B3r%l_y@|>umoXlOgRf?2jcR-+=Y;+NIFbZb!>x`1MWP<%PDa@fKCe@5$^Jrz{ z7bao(CmRKY2Aily0($hp5LyLPLd*`M~zF3SFeA0F3%nx0#Ox6qp2=0fFWmELor3OV2MUYkRT8?uX# z-mrVl4qJ~E%Q4fLL}*0~rlndzJYvcmMt)FZ_AQUuw=`zo`l-G7Als;F&jR>YwP(uO z*CVR_RqejAcG6dVYgbP+^^^g4bZJm_epf&?Mztlo< z3u4>xVyIb)oE%{mAM;uViDF|-Omh2OM8hWgYUGCtAY4TAzKpVXcuqjk%Vx90*+S*3 zVX%@?2BjMN{VI8Iiq2sr_EnhV$QDQrGYV^j$5q&GD&y7WKJ$92j0d3E$uMB3+E6Kl zQKVg)aXbR)uRLcU5-F#~5-e`2uk^eL-QkPFYlW3>$Icn=!8q5H*iA@*mbdFNz%yKS z7&2B^k>ejHlKCZ{dC27Fss~WJ1oqkXT8uNrDOO*+^FtHhq7dzHmCuSZvyi%^vt485 zAX<58HkaEEQW~JtSAjd#O_0<2^Dk7BW@;P-rllPI$C({gOv`hze;o^bbnHD(9Zm;^ zXa#KZ*3Xm$a0wo4@H{{klvKCCseQ4m-4($__IuQhbix!X8p#zx4X-U~oUcc9w5g*8 zPTy!99|;k)c)j*H-?hmistAu`gf7PP!?PAYS)s;a^ad;q|ZzSo`z+YCPe*$_KOR zY2aHpnIny&WSN}E)n(t6vX8?K$KvX;Pe|Dw{!`JtQuZyWw{o(W5N|JKJ0iUOjImQ& z%jj8hLVJe8i6gDQTxzQKc1i6{4Y}nUscZP(a<+n$ z|CSs3w0!7Ovu*f_WAQ7B#jpJ9_++072xI*>*g>g{i>r?6-kPfwuxHC~N zy-zT}j)m2=x0l+NA+qw9?8_&aUh zFWW4Iedn`Hlpef7D=;Ir9y7?#h`IWy1d&2%!02d(ndL`E^>KMdE8tOIdCqZ3^l7ic zzmK|0?FauyS5)$G;y6z&bVyT6}U(B5Xa{;E^=1S)C&C1>QAs}_>bXRwH`Az z{{i-2qk&J29y02ykKI>$MAXm2eD|;Y4J~f$X$M@rhU3R+QhOm{_218_9$H1^*p2X? zCF;vIBhJ~Q1D{ll{-vH-lwFTbJ05qnq=AnmJJC-+ z*-Yw?@7}iT((c0NQ2JpvPsVz6k1fzO*kk*pcV!#S)QB|=Xzhn~p0}Njj;nlh{Di(& z_l_g}^T%SYFND|sZB~0rDJVBtt=gM5>`eFDHl8=cR@imx;JCywZm2ZwS}fiF*0_tb z0%M%}ySwAA0pwV*3!~s{iK9RI_g3U+1^%rFK>z#Cc zM~&+Gw>t9J_CK`4O~35>Q(D~gebzarf1FQ^baaS3aIQygxyiU%>+m0IlOg3tb0{8$ z`K=SnNcDy2HjTegzstO(-9-wv~F}97n?5E@iRQKjYt%*}(ec0nNT4o#GU&;vjt}VzxVCyT190)C%a|_r=L?~n>WJZf8XZK)!IzJ zZ1EFAb!3~_82f+U=9aC>Rh9jWk=fE?MCMkj6$tOBmCW_CB1ezoul`yE&z0Q(|K9ex z)vO5E?B*|-!S-!Y{WTfv8q_$?ZIfgAd>!agN^o6{5 zuH5Q$WIHN2D<9>nf4di%r4^Xe>An})Q+TdXxlQXaqcQ;-ynpM_KQ~n!*?TZ|{;iJH zK02CW7j-@!m80^YkB(pbuS?ZuMu=9xGvim}_p}?%Em}pr+4s>eC&wOHR$Va`oZAO5C6Td1B@E2Bg*lX|5>EJe2isinyuc2 zUyf1YslcB`batl5e_<7Py!_T5H!P&ZC?~1{1XowDxu28Hq^*Yerb4xM+e5WN^KQGB zTEwfp+djQP8zkRt`_){rQJHEqcT*1v)ime*Yt1kCXue%JtD5G%|5|e&AI-JZez%(D z6YKqXgFdmxc!-ZSBGi^af3$&*=C{&b?)YtxqRm{1{joCD27$4~2OCR~Onp9qS3|oA z`y~DterrzHR%a4;1$Mf2fe7p@*rKMe=hCRYci{Um$n{DW*;j6_Q;S_S&+Pr6x@Wd# zAp#5VU737%W<_}Rz&w0gW--1klk0?|@3&^m2bbm>pZdEd=EFjKNVmeuxDMW00c#4> zoT;k@OMOj)zXZ`}R!eN2A)IGr+ydb|61MligP245o0arQUx7Ui(?EUFH;-T2&!gA& z^YA6ZS)~{#XjrT?EN1DsN<%UDV)a>Jf!)T@FrPKdCk^vS!wX77u0_9a%FL}a_%0Q< zMNm^@vB8;{>PxCohzg$1rG0Y3g6s(;GdN@2cWK1+eb;Ubx$T$BWI3bAp4qc`t>+5sa_X@uma8 z^j0gBPscx->C*8LO0=@$uNLTzU&T=(Iz9^XTYdEk-{Q_5_#USBiu0b@Go}@&xmAFn zEV4VO1xPrd$li@EDkr?kqyH+6{;M>%o>FrQ$$;h-C4(ZB3{I>3q$atVTjLSgv_>La z-m}-Kj4Z;1em{3B1;^VMarPQ9-wptCfm$Sey!PS@>9ryiE-m$Xs;5+u{ooqyHJjZ> z7AQOIhiF#I_@N|THT9YqW0r}RNtyaO2EK2v21t3ziTL?6%qMWm8Tc!x3;p%VhFpVR z5>Zyb$8P}#r<*Qdn5XH8k2W(&twkmFTko@>m7i%lGhBW5(RZjZk#nZ)vhS9O$gwYg z?4$jbW8cI5!K^fki(?=1RKTrn_I+rwp|S76s`fp0f_|qPp1q;jS@PEEATFM&hax^a zr}nk2DQ573r9)wO&IY<^{|E)yv)bV@XEpt6_|@$0S;0(kkuz7_XKmqgH-z98zNmsg z=^cUp{0lT&_8yv$bDyGHP{c;e?ea)J+({tMVgnT)-btB}5nzA%q1ekhj^!kQvzUlW3 z=C^xN!$_-dx4N11gvpd{CLMdv$E0j@z|EvKWKug{lLknWBAt0c8?Eetg?+LMXXAHV z#yH<^Ke4g2{#ZyHnd?&z;S><3UY{PfVvMVo3 z&E<>@RL#m59G*oS%3Si9k^fPcwKb?k1zqJ zOolo(ORM{M6{(}VnYDrbwKA`OAl=f9!ZUSgj{O2B zA8#H$ceSp~*53LKtEav~oYdR*&|u_n_u+Y(l1(@>U`pPOHP<8ltIWZtO-?oQE`WPM z-)(H^$MeibfKF}#B#a0f-; z4mi7y6M^yU2Y!6yIJ4u(t^EBdl^9Hr?YR>ME~oBLkllz2$FOR%&vV`xV;?|@<8(wn z)6o;|G&--0-N?pnBx5(i*oiP!&9duNwJNi0i&IU0)eF_`aQc{)&#j>+QCQ-5V_R;2 zj7^(cKY#Cwer_bMP(Q=eMX62k^8cg56I5VS8J+r$<(?hxs;X7#@LsrH`N^}x^WS#q zaC0m|ZXK>o9o|hYq7DyN7p3+9TsR$eUxmzQ=5FBTs&uZMW2I;4mAz%G)I+iYK6bM( zISdxwU@TmP&Yh=Wr|8LqRy`4BPoj}?%!x=}!v??UZrFEyVAw)(Ho5My^Ed1P7sF1Y zgXb`84eUUF5XjnN%dvxW^Vm=_>`&?j8J2|$$78`*D*0n3D8X#N?HETZp5k9dCww*9 z$WQf21ya#SPHccZbZ5F2o!mkZ-#gJ zN^K;)qz+UM9o+QFPAoX3*>WXo#w@c4tUn_O9L_k}JK0GH_A zklkHKHXCY=hk<1e+07A|w}e$RdX9d3V}5>pB?*oqrP!>5+59F($va#4Y%pvve&eqX)dpR)un$S$^$-+g_}cR%4ab0cry)o!{GF0k;;yx_FrVCe6~%MuLuxq`SgweuK@ErcMs;( zp9-@gdj$p)5k|AP*!}>Sq1woHRlZS1a^}gPzbHYE@#F45mp;d0P*zccesU`V;;d4v z){UywI#ab5soJJ$)rwR#<>#u^{=Oa65~GK?iT1YK;}fNcF0+RK`9ZT`()k^LBk1cCW*SBU15sGXvjR$x{z zbH8Q~xBQN@$R41WY4}e4i@ZO3k@jaVBDRf3dy=s;5xx3X@bue_3e+zkjZQ$!;53Ow z8z7wUI7NT)BXd&aWMGRN=_n(85F=@%`&R}VTkA+)Z=~N6(iEB{%96Y)mi)dj(KY#VEXw%1^GI{8(IKca>+m&EO5udopHEze$!SxG;< z;a?vvw*NrSoE*#%*=SY>Dx3SCtNS8i8_lBsnvl8wzPc|$v(YSain;%^y02b)YyHKz z50@hd>CF~JD<{uf{1kGr`Ktsc!?XXv-&3(iBdE9&e?yTT-bSlTz8EVt}KDhL+auL-%^AqQ)C`B}UU&%*e714iyKA%~xO8#uNnny>Z6hK z4M6>>{}vdVsZxCr0<1^{*b4N)Dx*(WF(5^7XMqYZ_Q74W)|dsH15Am(#^RhE3hbW$ zWuZdUEwqPYW>K2u4;u^Yr&REXOxb7_{pT3W{Y-VgN`T!$_p9XF`KkpGW}H+CFm1MW zN3Ysr+LY0s%Bxy!gsLW@+-s#RbzlT z&k7~syLw_n(B;N%ux2rWt&IMTO4VW6q^gOS;9;R^f82~}F;tCqUKkeRhf@1E0!t1H z*@Y@iAE1_QLU+p+auvP1S`W|CB1Q{TA&J^66+;VD)dyo|^OZ-fA4WUJX$8@%QxR2m zhWE&F9*7cqJOaTCuh^<_Q;zf+C5^xDf-XBlK)Y!5*@sy<%!cLEi^AmxUSOBA`~N|B zWQY9*KjQb2wZeYGl%&C3>}*jdE3N!;RmUAba^N^_Vz+>MODuC+=}D}&7h)W^)IEuw{bNsUpo^dXN})XU0^_yUa5 zEn($VH{y#(=@*E4-iTxCO8u@H3twU`LT#xX3bRz7hvCm>CSrK=knI;^X4wcyTJTGC zS)xl?1BoxvWuY$B#sCX7x;33F*hXz+hvg$*=c|03OQK~jB0XbzooT`nkR;{{qU1 zYuYI*leW?1K(yAhW@l7;18U1EFf^C|MJifK>AsT-UgwMqr*wo4Qy@=mmA+Mxn`bW`JbHJ(AnyNiX)#%UeBAzh5&Ku@po5okh6Lk=+HC;v3?t?XD z^w+TwX!&%*K89?JH1)7~2rK0LOpJL5E3~&O8JCAJdciiemSCq7EHzc=JMhEhy_p(^J zmu{-%|57bmHi<{Jl ztN8L>7T3WzSX^SaAS2GbES^TkU@J{4tY1%?UfOnzbM-RS_@~OUxbh}g-jsSt@2ALl zwtXFjR`!w_qh)azd87<##IiUALse~AoJL9uY5ml1bZCf+NQ*PXn<>H4NVS1JXDdL@ zKx!*so?6Uypr-8ik*B!dRX2>eNDUH@z>iI3WDMo7-yk6~X;vQ1kn3RewYSqzdqWWjsQ(>0VH}BCJ zjxIS-ItEFq+Ec+HCE+t#SCA=BAdFVbqs-Agd9tM#Ud=`a7mKr>o{Zh(br;c_urBjINmduFsQr{2tk8ZlZ|!RysV zs|6{IC#9aFHJVZnP2}A$+!-z3NaPV#D}4YBuj98Nm?*^*ME2Y#nMa)QRuB0Y)4^CT zzwa@QjM_tPs`k-95{A#Qfg%RWerBo9_oQ2?hVWOf^!KF8?IGx*Y>FIZBdmkC|FUCJ zss0wbPGq|ms(#V0KJX{Q4njq_U4rm(Q@p(``Vi=)*hwCfwN9h%Pcfk65@Y8hq;5U> z<=T1qXV9+K8qJ?UtNJrc-A+!_e)}7QhnwZW)YOpkX=?of<&bkWm7eR~)aEv5>L?68 zXRn5wZ&O7c;}J_uP4#N3>Og-Fb18tU4D_QOeYl7ex0H%$YM8KO#rTK*W~dIM$AxyV zPAH9T)Vc_*7E-H)b}F)p+vvRA8qK{6Z@9Y5X{3d2#KhHu$ZT%v#*w;sFLhPjvU|RZ zTN3BFD-I^bf#;_8(~T+*Il76Z910gG~*+DT~s7XQ$MD9ERfc_Kay~&hod`XxBq4W(P8~ zK8=IQVui%>bF=+lUNZPa6F02bH_qmL}o^$HdsZ*y;E%)|~ zv<8+SGml)GO5u>E-$e2kWpdUc?WQAPSd^x6A57aOfBDecyAHjeLd1N0aTSSA12Z!- zj^pUUein~u@~Z4x*hZa{S(P0lQaEPD%g7GfnUT9J-K-#5BIXXttyP!UH|r}YWLeD= z7s1Y}X$DWAS-t899rvSdbF+kr=$zy;ZHIn0y@%yD@viQfiInYjFe ziXP{76ngVFU=2j%{pDRJ!{=|#R%9rfSQ#RmnUEV+QsD( z3b$9G$rP8hm|ptDWgY3g4Uwmh%Rh9X*x>4yQFP^35 zeXTV1-K=bod2YIL72B!S(TR()`-Ub3nt>*fWxpjyNXxL=fM;$t=O~Bj%d?VvW*Ps? zZ!OgiMh)iBP}M(Ii0X4K)yt{w1~e`0f-^9GW95T>lE2Gv;q2M9dd}@Qq?2==^{`Ie zx;S21LMJWwaR&X)ih7fOT5%oaWYyJtj=V<9pezCLg5J^6$2{4GK^vY?aXfk)D&(#* zaq^nVdt5^w>&B~dkp>pv80&U=0>RWsS;A zpr0=5LpoH0z)(OdN2HtYrSn6w%;#>TLZL9-j1XB`5=LgZiR zF=^NuL`k~C%<0zo)#2R;Cj9;ep&&*}R>u8S&WU{FH6LE2aOW37i}@+Nq`@y2=p@qm z>hPP-&u#(*IAyn|e}N|4Mr}4VL5`2ReJvebL*V_{1(j)SyoFw`_Sj0XN|EHP;2MszaIqqt|zDTv+p?A zm-e$ctHEGuUT^Pr=Sc%pp1ci1!d!{UXBSW<$D@+8x^%<(PuxXW%g{_dyF^w-?h<-? zf3Ub591+@wQEi*a2eL`e5xw^_*p{x|95oJ`Ug^$#WyO||`L$d}@X)j@h6-dGIAr=Q zhDKQYq=F@JAS~Z6WBKD`xeSX<=?TspED!ABYNSKX^=xcrH8Sa36)Eh~D^ZQP2bE7h z8V<{rlOs$%m6q*?BK;jp{fgfO(-IcJEpIr;g_%o}9d2Kdv4z&p53E^$$Gs6{Pa$yZ zY+6D#eMl`Z+0;82QSo!kxt!;Exf{oyP~wT|5H=@c3cIKWUa&Lg?+3t~Q!M647ky!# zvTR4vo#%+gr&k=;!Aa&y)JVFBD)|zo{hTJgs>u^mWTj$6Wts_(e}Mw#+Eo-BK(!~x zF=mfnW**pQ*c>NeIeHHT0{vb%drhjG-Ep>PzGaAgPw79M->7R$v)>)EQ9Q(sC;M;3 z8q>1xn1+XGrz7~ytx==x^kHbt&Ex~w8q;W-O3M4C<`d1`m`)-3NT1Trewk37JWI4o zyyjX)IfvFBaIM)=<@cxdhowJ~k4%1-p>+k)P&yW}v#N5o-48e(GbaSO6v|}U!`Z%c zragJNy|5-4 zAc3b2*BGhkZ$uKctxEk}=Wre&ktwNyctywsbPYqsZ`>phR2|1noB z{xI#zPlcw{$*c+fOcAa{Ux0s$1UL`WOE^OAjd!~^4C*Gj6^ zp7*UNwF`BnON_!3Oh4bcs3^6I)@6BQm2=7dQE}d+!M44V?e%nfW(nz^;{mt6gpD4QvK$rVa%(bwJ&J~fHa0sT@1S28miE#Xq5S7~sc#oc zte(@8Y5VZqU=tB`UQ<@Nl3gnYpRJzLi<=!7B_fAZtywh{MRA2k2YXGP!#VY|)GKN4 zrDMlVL&vUY$j&n774A;8I%Eaq`Kg6gXUIHv{--pl;-}!FQj}BgEflb}0Z_I2!l;0? z&48izJ&xaB7Z7{RS^;Zw)}p9^zlDTH&7ne4M@yNt^!M!qCH3CW(am2B9UTQWyfSq3 z8BYuyz39(FN4u{dI(pXchK`7t*4*)ILE=N3+EyZ@CF6~&RGA6BZ8hjb@s&nKiOgU zPNSlqFWRy`v?`#d;B#lK8N6*`p)qUax2eQ|v(_H+8ZL$&hU#L)|lIb>TU9l4SB=$W9Ryo25J*5upl0YHF(4RPyo7QC0Tk9 z9r%n&SE4NFuW$5XS!G=^T$?efDpH>@DU`V|@ZF|vllZRIYqF#!5etUvkAv@^J==~s zag!a5nF|BoZR{|K@2VZMQ7x2ZS6kuBwBF~dh3-9g}jYEzgLVJ!bg!a6A$7qGzN`lQ$Oh`a-apx(8RD zWr1LQ1Gws1j(u?%YY-5K#zTRoKuBD~1C2o_O^6F$FziK$Qc=_(FxKEf@~96;KII{) zIvMuSMZhl@$*3?k;Rjqy7vHB8I`~hDi;}U(G8Ch)^CHU}3qexU z+US+W!tvr7=&7T+;VX}bTR|}K46onsshL~Drjk=ViI%8rrgSo2vj+H~DNrjkz*JAz z+bCsWLgpgfW~!50L|~;gZNL#N zsZL|`}Y3Sb}b5n#byhH)%TS);&CoSwD;XJWb54SWFy&3(WKj%rKt4P##%;kN-V z0d@fMaKo}2*b3|e{sb%-Y8Xf3M7sodGSCfd21bF`0o#CdcfSMpFJL$DAl&Hc1I_>z z6hI%a1b7N=y10Q41EawGarD~;>;ZNF*Q`Q$;Pb#f;O;n&FWB2KDuE@yl|VP}PGA)H zHn0u27f$FqfRlmUzyPohcqOo4ALs*?0RIhi14rOCOB6T<*amC?b^vbzb^~7l_5tbf zl7f8=V=V5sl>qMox`AH#-lGKz!1<4>;OiAUjf^Ig?M1512_-Z4QvDU0iOXD;O0*b9?2>JRsr3> z6~HL41K0+92iO73$3t4(z$#!L@B&}~&V)7rOMu&eZr~6+#uo)n0=5B{0y}_L0K0+D z0sDYo0SgW^j3e;OIm>;`@Z>;q1_9_8^g&AGr5;JrXM@H=1>_^TUG9(X>m1Nbzs z8#w4jln0&!EWpD~^je1!;A=oP@PKxd2c8CO16~d60KNz82JUqe$^+>|8wG{%C$I$g zEYJ-sz8U3#tAK65_kkV2<8MKEAia&G54g{*C_e)64J-k60Nub1e?)oUm48BcVB75| z5B%F5C=aCfr1b#{??ib#68R>u1Q_Z-d0+|{1&+82<%xbb$^(0V-N1A1L3v>KUX&kc z7@qr39{4TL4gB5xC=WdP0h9;EfgQlz9z=QI&A>k3jE7JjPuvcE80CTQ0o}m6A3=HG ziI1T?@SG=59{3kvH*k+Glm}k&G|C@=@&63U1D8IF^1usUKzZPeFQPnf?Mo;RJbyFF z18ZJJdEnS?lt0oi2E2muz;}Uep!Zdj2i^y40}g!+<$?6qL%V^`1N(sEUq^X7k$)Yq z1o$n`4Xl3y<$?DB+kiv=it@k)U^j5;-%uWS@D`NEZyJm@Q69Jj=my^X7Rm#!dK=|| z-vB#+?srfgc*MIX4{Qe(;HM&^wxT?+{_iLcd=MA~=5IrJ;96h@@W}U29{3or4|whS zD34#}9Q6;B2M+E*dElkMC~zyV4fyL1P##$JA<6^q1NH$cKSFu@*y&AR32;;|$^-8Q zMu8hYMtR`)Pf#BCEU+8+i+`egu3@-<1$!7q0$2iE4|D@Nfl=Uxz&2pvrzj6x4D1G8 z0_+2J0t@zp-+?8-vd>T+csei&TnB6eJ`U^vegf;PT`>;}FC>;wJ?EWo8k zcj5nIz#mHl8@?ap={h{op_Dz;6ZrE%3GN2fxRm{x0ypcHsAbpNp}j)1NaCIUM{+y7q&A zv;*G-eg*it{_%routWV_;9umx?*V@U_!XM=H>XHD3vPJ=xgd zKPSg9V&GS4_(kAv03TD0ZT&9r+re+q@crO_h4{=v9NO963jQ|ukKXEF$8QJ!QRrW- z;dg<5WLVGd0smsmAwOyC%NdNlRs_F$(daJ%|J7(Jb(4ng0)G_drad)$Kll@4sZ_g$ z-wOVhD6jKRJNR2M*Xj6O;GY%O`@aYL*TFwm*M21PaS46-BJeM9;Jd*80Q@l;{eJMj z1Yb9Qw1WSg1HT=7BdIUn1^(_1{2uW0!PnWBvpd#64&{r$KOFpHH0^VNUkrY^hVKWz z3jEhJ{8sQ&;QKZFcJQY+rBaJE{4Vg%0smzUzX$wdmZeg+X!to;1Kkb2&i*3sUvc2O z!2jHV?+1UcX1)Ga@P7%u&cE&8PjujSfj=F5-Tcx6{sM>cIatGa9r#7yH#+Edfq$+8 z-w*!p9Q3z>f2{+*9sJuI_+8-N>%i{;{|N_v4%VPAIq-|Xe-nINe7L~>2K+)ze)AK* z1^HDIf34szUY<(1H2ik(S2*yyz`p@}oqavvKkmTK!5Vri_}6IaF9Lt@S^Dwk0)IXD zy7={jztMr;3jXa5{C4mkaNu`=-vz$5{oub3{sc|?a)w~<;-J3>{G7A(F6{`0e0d1pYA^{axVy7x>!o4}QBt`5f$#=ox2S`6BS21YhT07x>%2 z*ZJ2E{?`uWTfyJ&9KCflmNm+kWupgRgBr_)8t? z_k-W$P=71QpE4d8n; z`KuND_Z-T%gP#IlH-5UnKk7Vv{XO7Ug0Cx|vk%rc4&{r$U*k~T1^(UO>-_5n|1t2( zbnOTK6^HuU!T;Pre;4>afInWNzX$xG=j-ju!9AdZ!7tO4F9LrI_`3Pa1^&t4>(=Lf z@YjGpPouvT{71pp`L7-P=fT&-R~Psnfv?L?J>dW3P(BCuunxXJU%m+ZQt);4yTG68 zP~H!Iz@dCA_$wXCw}XGRL-{W7?{_HQ1O7`6<#TWk?w=0ji@+bSQa^rN;Ex7h=N~`# zGr`yOPb>Jp245Fn?cks9!0!V8CI@~G_|H4=bA}nlXW;AXF9JWW)uH|1j{{$4zaRWl z9Qdu^pXI=B2cPa?>-2Yl{}lK-`+LBD4}5L@!#&VFF4T{|BJlTj;Jd)5AB~=<8Q*^J zPXb?Oe=GPA@ar|@+rhsNd|iI&0>96J-vj>97wOCA;2y5ufnNkZy@B9tjeRcgzXxC2 ze(;Nan@Y{sly3!p5%}9R`^R?hkHj+s-)YKsfuC~V_kh3U;#6v;Mt=_OL8sQFQnzXJ z7lFU(l2mG=hVKGDcWo;5poZ@U|9bE*)9_ot-*26s-wyt7!KXi^Yl|Q z{2uV{X-lP=HTCBlgnRvXR^e(5zX<#b!T&c zQm< z1%6^r<((H2hZZ_qidJI@o-FqjDu(iTjJ~;M21Thnnp(@w>p!yG37r z5BP6@ud6=?&tTkktKR=b;GcGzzW-d{AMi(gc|Z8{$EDuUwIBQo|Aco#YxwQpe+>Qt z4ZjQgLvK%|PSx;xz&{22xf*`Xp*UXw|4a?P2>e$Z_%85&afiOVAN+dob@sJ_zY+Y1 zrv7&DKL=lDe;4?NZqn=T0sj;SehzL-w}HP!Q-2Zov+hi#-q!G4;1B9Zr9RN`{op?b zzD|ED_~-puufHAqb^gyO#IteWzoD_e2>dbk=Z`WzIOf}iT(lKF21PB|NH!(2mZG_km8T3&w8!s1Nh4lacG6}3BC?nuFtVt|JHK- zJHEydx%k}A*F*Ta?|S(Kw-Cf<*0Hjt9KM!MiQ$>;9dh~}wU1;BX8tO%=*0OgUk}Gx zj6QoxF#gT;;TDznV5=rRV)2J>y^#^(dY~j5xd+NG`|&kyZHo`KxZ=~hN}{3ROv#xUaw#&wJv7&kF?GHzzv%DA0z2V?$?vfe`(iy6xqs~MLth8b5du4CN5 zxQVfoaWmsq#_fzd81vh?e#Ti=LC5&Ol6^!c`H!yBu>}1@`xRr4`;||9Bo49_) zV#adDYQ`muVa64V>limMZer|Y+|0O@aXaG<#{8SPe#Ti=LC5&Ol6^!c`H!yBu z>}1@`xRr4`;||7r@o)_G5sbx*<&4#gOBln9D;U=?ZeZNR*vYt=aVz6?#vP3Lw{rU# ziy6xqs~MLth8b5du4CN5xQVfoaWmsq#_fzd81u#97uwHQ%vjD?&A5ay%(#Ma9peVZ zO^lt4n;Ews&3dVJe8yGh+b~0{e+{(C}aR+1mpSXU; zV#adDYQ`muVa64V>limMZer|Y+|0O@aXaG<#{Ap4e#Ti=LC5&Ol6^!c`H!yBu z>}1@`xRr4`;||9BJGg$vV#adDYQ`muVa64V>limMZer|Y+|0O@aXaG<#{5lOKVvat zIb${B62>s&3dVJe8yGh+b~0{e+{(C}aR+1mom@X-F=IJnHRBS-Fyjiwb&MMrH!*fH zZf4xdxSeqaV}1wM&sfY@&REU3gfYyxf^i+=2F6W{os63qw=!;L+`*XtXRe>In6aF( znsEtZm~jQ;I>rr*n;1J8H#2T!+|IazG5;>EpRt&+oUxj531gUX1>-u#4UC%@I~f-> zTh<#hr%#_!IBJ0}8BQb%#}|()E*n#t6jzf*%WK@U)5?^V{;vvUOsayL1`1c@ihsMg zeQN!y*6VvncN*69I+N3IJiZMyXcCnA2Jw1mFiV`w>wR^dF34XmOSm3i@itlod}}QC3nispQy_VuvN;7(a$Y#@5D@V{2oHU~!G{b2PAi zr5jp|nbivlr_~ge6_-vbo?L1SI8R!+4{XgHK;PZ?|L4@v-^%d+fRzLGHVSrIu-l;A zgL99_-IqMxpRxhefyN@@4fr8{FZ?@z{Eq(z{P!DV80>e^g?kKCK{aU40VgGYHMZoW zfdf#HvBy9aU4w=XIBDQuNmCIvsA#~z9FSW7$1EhDvxO>54@#S+0(H<(m?q4H9k{P& z*-xvceZ=ENwdlL+g?M_rRB_x(YUW?7K4nNQg%v)^jD?!=Msd8QG2!(A6ETSm>RWv{ zS=``_HyFkKmN3L5CSpc0ahl{yG_o!{;Kc$VFBRZ#(NMxDruY09#fd;O{;k6WcoDxh z;Wdf_4W2r@aw6bq@T07{GKy;xkysoRN?2M8CUko78U$1rfg1c%EObjfzBr_7BaMv# zyb_^Uybr^JcUj<_2&9ExkAasZ;B_C0<@3b?P3kHX3AC*fhs9cl~dH;SjwxcsxV&( zGOGF&c^Q{i{kMqokHVR1LBIu+|5SOpcR=k|w}Ef|sPYOQ0Mp!lb#B_r<)ccFm8eUF zPgu&U_41--S--MV*`Ug)>u2$WXsZ1Uyxwl$@*PT$(OUjR&}B{8f~x%e+2nq*bZ^V9 zd|`{Ewpq$s+tZ^d-@)apEXpmHMxUnqkISWGk)?iX`5l__g=b00qb&t2mj?az&`P5! z-DgYc&f32>WL4i$IrZ7b<>`Gl=8xr4)U9%dS#HurQnGNOq!t3ko>9beH{er)Ox_o9E5DA=J#y+AVbaD+4LMk&BxjF!G@Y=v+27TYW~co z@1C9?v+22pn(wmdd!*;HZ2F#tnxC@id4`&Ivgt$8>)UMlUWS?{vg!GT%KzE)q3OJy zO~6(s zZ8bajqd*@(s}zg>X}vhWreCHDdjEcLgHHAK@xBR{;!}rz2N)TDs&ScQdX(n@HQrZ( zPI{s=;h8=<`!9tI*`I5%{~AFbYP2m?HA-bP4-YW<+kYSERBwT0U#9aj%|~|re2erC z9A=zhY1h|+{zXd7ySNmeA*g`lt#Npupzm!Ax3ud>LH{CUjsLNr)A@zz>(U((Ru)X+cG&hJK)iez=BS z3_AJq)nCE@e2!*+Rtfn$qkXd^9K-ZRroXR^jsoD* z8u`~X^sTJtt`CJ8yy%xdm~^RKUyqae#XAPTnh3g`KV5>JhxZ-G@{3uGUn5U{Pr^>m zIiOR$SFt~*u%6qQehkygnEsB?lV`MkDGB0PE_~g=^p75vbmgA|u|XmI<9Xqv`fDoa z`+z>38~O?BUn=N)VS=+Y^ov-}ijmT9;@K;dyOrsu93|-=v#yskdfw8|-)B9a@W2(% z_Ci}j*ub2Q60 zTgKxYra!?OiP5ZQsi5VHQTGrnQ^S>jj^C1@YihlGc@uc4ZVf+41Y=LQTG3V=}#Y=9siFo{Q!#}-UYpoZ8O8C8oIHEeShU? z=!b$%@w3VjKch7Ar5bvL_XddZzzc z(D}jyjV%8<%d7EniAMf1mVbAfRHFQ_Nh9CM@_X(k?Kv3p7JYh|{!7a^+5?Blpjr_TwQ$KFA^y9^>=kd>^o(I{e zPNr{uSrTS3{XM2vbGuZ2*nNooxEQ9PkJQkMHS`G@`U!%bXB_x~H1HU<^9-hM=+35} z&-8_yH)tP1pX)&<|6FD9&z(YE%9#IsSVMn-^~c|r(kiY#V)_S`ILX~h)@!tk5CxES z#OFZJ?dFA%8u}R4(`&K6LdfSCV-AyXtH!C1>6g7L>r?a8N~Zsr=P#94Hwro%XM#U! z==ZW7_eWA#{5B9@UuF7`&m~=r(|>F948p;=ogap1=m!XTp7Et+ewoDd#T*Z+Uru3q z(9$n)rssbp?fgQ5aT(LE{<|coad9`(@7z!N`BavFMbP=e1lvHT_3ih^NcmCB+o6%q z8*1-|eKqt$H1x58o@d-{$xHK@z6UR47PCEZjh>Y(?|xMZDu2?uF6{b?-dj!i@Uo|* z{86m`C8pPMz4MsJ>>) z<6^l+&nnQVAD0))dJktkH?y8iye?AX=vk(}$qRW!|A^@iv44(XJ-Im8rFJdYCJD;V zqnQ4|o06{dR0=v5Ho+ndy-q_L*S&N9|@1=EKOmhI)?VLZ(A=YApS;pqu)T+CP?=v>$Y0S&!TLvPX0R|$Ha zG45@td_322t497o&}kld&XR|p*2r(s(BIe4ztYeL>`Q*@{~0RidBz>jNuKh5sYd<; z4ZR9rjzHMln1v-t3Ep+gOk9apE@J@~X$5_u{+ekXIZ`!7j|5!u+ zT0XZf+Le=f^k&Gg-Q zzEJdsnSQ@z{qUwn|Hmxf#{1$@)}Oz>97jRR`PCSvU&;H#GM29vbiOdbX)M3+2-%O9 zGVdIX{3;E7J?klYQYvU+Jr8T-pV!d;s-b_Xq3;m%JmZjm$qK*VdJh{W{Ud)=jQ5i; z{RBbh3lq#``47L9#K)KyVft13O8-Qdz7BL6FWr{$vVr9ve^m-9|965;C9VX~`#zM=wYaHn0|2~WV zXK3^+Vm%KJll`dn%gb2LMvI=+pi_Sp^ZHHo<3k$#PqO|uEqVBTrVqEQiv}Gi`|+BW zr5BX`qnLi@-qKE$H)b)tme-{d*m?DWZuX@79%1?V9(i5QB5O7BH?aH_FG@j`4_{#V zGnW0uCrn@eS1GUT&pSx=OMzv-b1>*M?+NwwuWA#p`WIqH)!ZdLC1Z% z&9YK8Z(hmt1-x%kqf0&NHJ}{!W&EIbYVR^uMmr|GtL)xrY7& z>wo%fS)q!bVMqwn-kZOX^o?xKc+kntNxZJEV0uW%^MwhTSb%LOQxS-8K?UkBJCe(8P{W(KI)Zhd*(9zIX=fz^J!AhO%39&7qI*Z zJinaE^c$G|x4a>ht9~DN z7}?+dgFm?`;?4Ir$(zI?B}_l;T}e>=UZc_DWBGe|-sCiGT%?h|g5^iPCH2qZdhcQS z-H%H`3)8nU{dtxzXFB~62D^6cS!ho`Ktn%L(DRJvxxGriOCw*+@?Y@!O~px6BY(Dr zzK->L`H~?%svrN%^mbk+jF4>O5vF?zWjt(U`n!V87bf^z(DRJlSy1)kUQlS~w*v(o z=MtQkRQycV$j@N;;PbLl75{#X{BJb$3s}zpp2yYthu#%I`S1yg{^vob@pT5TH;(2u zf3DI01M9izJ1O`M%O8Zrm7O0(Y3LI)^h!a`Gp;;nfY7Y+k{5KcbN(1fSN^<8qvv+k z^U3|vz$&)$WsUqlH1y9{PwCfE!PTs1&yn`+-B&|DT+s834>`}PaWS3gZ#*CstMhgr z)2DC(Q1P~s>3jZF%BwiJf$5)H;`1> z4_MZ{qcrjpL8pH2;dx{%x8YQcypQ#7vFMKq`8;DY&zs8sSFrvkIsR4NenX@GebzI9 z`|C)yXW$X`?cE!6vj0V1Z>V`^jz)f=hF&k|dB%_3vO?AGzh(M}_axoL_T0ks^Z$`8 z|1{_Ycz&#b{lntMD=fc!i==p%@fFiQv*e9oXgKAQvF}SkRqsTm|DNYTW#_4au4>C* zt%e?DJuf^dW!1c}p6TTuOFE|^<6e!PE)D$^4gE6>{To3?{_Kf{Q=M^j}7PjzG}&% zLO#!^vh1(7X!P`G=wE zn#c97(8yn+pe2lW<8Hv z&OZmiA^VuhtFJ>e^kIUYXIwv2j#IVnourX>Y3K`C&(OzYjpA=V;cJZPFYx@X?7vK- z=l2@=Z5sN0tpEJ)WxcO*gSRmKY|Ht^PZ~XY7R&zKw!id)%7@2*PW|;Yug@!3zemXP zg$Wv1&s#4_qRLCZV?96e^K8lwkFxwE-WRC#$(u}nk2^%^`H|@#@co7LT=&5UB)fh; zN<%Nz&?_|b69qlbxO$tcP_2s^K&SEbxMh4bvHURZcO`#0(>-ry`{ypu?bdG(3VCj% z30~CDKhw~^5%fHxj>n_&=fNeie=oMIldC|d@xIuyu8s)0$q@c}Hp`z=kUigB$MhY% zZ#|RcAJ^!433Q6LPL4OVZr`I+(hs-n6Q_V~*Y7hl^hFwagP`Xb$MZT_`R8Jd{N)<@ zM%Gi$`x>=R@6^cuh2`s>l8(Xf6rV3N^51FbxfoD(emF=&KT^=~oULWQS;h2R&I9ZY zqfw(L!SV~ae@|umFV)CzVEOm>+(!J3LzHjO4Zg1D<>D17lVf}Z$AS>l# zEIh9-$K#oX9AD)FnLl3A4`F(>vXx#5K(7KQt~F}Cp^&G(F%tH~6W&;YUj7hIBydjTxX@JL@Y&P&hfM_U?2>6R9OrA8+ zAciOCZ>FoshJ5dUKiSyWqUx!vc8O|c%$qi+(xa}Z8udL>i+DqUs3jDQM?y`3W0w}! zMx%!76ubhVuGr(LZ*KNP@sfl{*c%EaT0Bi9hG%Bg+=^*cp1Ct-)Kt#*%%4_KRY}eA z$0MEwZ`dCSs5Wwau2ZY0&6z#jh$a)B#&~^QGF)o}l+e*m{7Sa5<4>(uBYNKDA*LBLf&v9=(}mOLlh4f^H-S11 z`rw$IbsgLk_LBQ5X1MKZLA$3%Le=OqVO}UI`cJei*5DCux5%n|;>t$@hmPa z<#0{}BVqRhbYCn`>uw5WRW{xgpwU|uL57$Ys53>heI01KI}vlof{oq~q994SWhePO zb)iTkRu_!L6VexvWe8l`enzBE^ZVgM1h>6}m)JCZyumPDY9gvgI~PWH8odeolG4KL zFoFWSWyQ0oYPNluSfD-_$2gk9x;w^vt&L(#QEg#pplJUstd$OoxLWQF~_0p(rXL7p=7|md@w!@Il(1T0$CE$Sd4n+ zM-tvpb;OU{jql0{uZ?y%G@-a8! z{XkSjV=(He_eRC{^!#RPH>73$rHRQ_LJkoK&Cuio*jDAOm%hQ=pI*(-dg8<;&paN) z(1AbwdW5|g-FLS&<avUtsFe8&5>Cd*+86!6IfW_txs6qX;KJvSX9iDQnPqE!I-ffH-EsKq%OVS7~{~OSEV>MC5V|6Y4~t z&*Q`VUfVz}v`(wk0vQfiqr^lv`h3FIp2cMo6Af7QcmmC}fhZO9EDI(YI6N~cRZY^m z6&K8L?__#_h-#N?2$>~^fp|F>U1Exf(+ZBAE@okxA1SfK0$#sF{0;#( zWe2Psb-g_!fc)aa%9@6tm+fzR_T zb!wxxIoK#hd?Oa+jVx3lI=70}0%3Hat!k83t3MqdQ;kfKwgNC50zQ>@uy__ecgVWL z*9J1|nVU>t_fi*xPiYsE@u^Te$6aIa>cnZXM_|dIur)duN4L&F^00RbqDN~W8R5o@ z;u z7kO5@sKioGR!pu5dF#nNvgMAQiB=(v(&|d33Q22h!rmtra>f6NvLKl3uPkD%puN`1LZo5 zR&&UYqoW6`aCUa?faR~pJdAa2OD9V*SFBs9QoQ05`+j74UYKEQ$N4)H+XoG5liM=n zL)+Rgiw5e&GRmG03*>TL*)Ep`_QGQAtl#iM*MhJZL|6jbT7wRe^8huRHj&E$bowRs zrZnx@?oHLXhrLQ@s*pQx+Zw@ktF0OWTtvD)ufqw`{C?ymY!M8!7UM)Tm(0c3j74-C zAGJE4MrQ(IEhIY;?}`ltyh$2c@CIU2~N zSntx-M%ZNQq55PX9+&dAd~&cjsT2z=3~J}$196&0Xv#JZq0*U{==f~4-_aS3Qyjr% zvatxF%+aW=T__~&n$HKQwo+t0<(_GY8RAsSRwx)>5D(BMN3*=4Hle=)ynLaM(2X}5 z$h5D+akFP`ctJQ6@oL5blp@Lyaq^_oQ`_vN4GUbiJiz-wPg!wU@v)o(FhlW~ux%Tl zPOPP6nv<*G%;6MvdN?hLQTS_@^>C=nC7IK$bXS|YvaEC-&Kte)K#e+Hp5EY%#l^8B zS_AcT+6;3juIPFQX;$%r7p?s>|*h z+rEG&aU_7egA-P?ReMB6sw2z9?%Gxl`01k>no*_4F;1|#wJpHwQjy?f>Vh!s7^pkM zPG5Xe6R(fvOr&A4B-rVuP#h)BrhTz(-Dou2>9A>P^q#3bTSZ~ZkpNk|lSLT{Ngt<| zz&gXQRF-3nj-utU67r&dCz}G8Ac9n`flNc7baG`lo{Y&O_vzlKw-(29*swTMk9Y{u zT);Ps($ge0GaRUwcO1|l=V=B4^E5{=V960>va_tD2CLG{o{EmwBH>DR={V0)e})_k zx=-?pz<^W44KrOs&0*xv^k90?{$VIX^p`cZ-2Xt7}a7Uuj+cwj3}of37}?t(wBVII9UUEAe+Xoh)T9#hzwhCY*b(oB6ec?PCI zasH{lYZr_oE#SmMr_^o&o=9uhibw>hJG|3%EZUDdHBGqDK_QurPqUfWtz+Sc8Ob!8 zXWu~8S+}#4m$h4`uAnqfr=4*j;k@yI041hCERl@KBO9bVJ_NLPVMyK`UC8h5CmVKp zBmg0~-L!4CS|3*Un=O>H9PS~&q)aB%X|E)E=O^1j&?)9Z8aQN@X%A#Q@z<5du365>wgT{Xg>N1`T4Kva z{TO?=8zoNYZAC}}t-j>if}9}7Xl*3gq84mEail?gYuPP|1v>68rI+Uj_gb-+kS98( zJUvNt2a>fZO=EdZN&|E^m9`7m)A3Hh)>Jy&&DuSf)R&dkh(N+TAWv;&(8!oU-d6OW z=~lBm{NeePy2o-~#T+$aRYF5T-O|ZCWKmW|Gn#xTL(W8MT1!8ekv$*5NpcBHji2O5_s=Y1Tm4!=~p4+gf06 z<_MEqkO?ojRnTo|#n6);*53G~ZLfN4g@PHer6yduOs7*1`JwhqPi@1Qo;q(Zl-W#; zr}Gv(#zMhwYd=*XhK!g9@MxFt7HLmsZ@Spo+>Vx0YLaIS2ni8fCRLi9m2}bUFjA4N zbx=!dU4)ca>yjnuGiUic4I+Iqq)gi!@@aD>+D#9lWv|a`#(U&{+Nzzi6^wCSFJ`U4 zO{2SXV*0FqZf$Kc77O@s+)r(DoTVUuI7K+2$)$W7JUj2YHIJjAr1MD(9Ei-SIZ+XT zDi&e-``J){%^=LP_oZ5=RXIH`LOB|7Kz=}+(*c5QNTknZMYctddK?ZTIDTe}8xpqa zAfZ+_wtP8!U>5{wU*??Jm+*lj-LtO{W~tTG5ighMCR{v{?aC)sgV>KrEukix4p1rAXgT zwDlo`O=oh{V7cyq)uPQ#-7O^3ClQpb)E<%=r5?PL)3klSpmtT>;Z`NALgEldpZ01X zu!{$yVtt`=1Xj52SP=6ho;(sc0nd*voZ~5-JS~9~-Y}igK{$cs1zK9^b~n|O$OWF` z83NfR7f$9hQ!+Dv<5}@oWY#i;9;>8IfZOHy1g(QKYc4ns7Mspk)Kjst2c_TT@ek6{ zxbzM7?8Kz?s9QY|LH6J=7*ywx0|!G*9_qkKhtn?97N_T0$%*J8`+g0^ z`PLDwf-zA!uYwT*`Xzrb&JVQ(#9!K@T?%aFRXK$n9$D}IsQc8Zc$RHi#cWS0e!;+z zu6q(2#$u?YZ)BKzf*zfaeIys*!OXMC=|zRT2jHHX%<7tx9T7Cy6gFa%ox*qRY`X{| z>HG5J{jf^UCX34^@I8cG+Hd-^pLd>&;Kq)`yx*WrDjwd4n*|j+RC1u zx(AV=UvuLr+svw5c4qo!pj-~x`&33_W`W=^>kEg=8AqljGK_+S5KmFzh(tURM1DkG zH9wtAckP^Ri=&7-7IV0p2q~F9Fwu(CQy`R%pQ-kbPS47tLftJ7SccG_p*9OjSg-GhA(pefm6=&Jt* DmNpEZ literal 0 HcmV?d00001 diff --git a/third-party/lpsolve/src/main/resources/libs/win/x64/lpsolve55j.dll b/third-party/lpsolve/src/main/resources/libs/win/x64/lpsolve55j.dll new file mode 100644 index 0000000000000000000000000000000000000000..754e3b6880535e5ba9af2d7974a4f35af26b3596 GIT binary patch literal 130048 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 literal 0 HcmV?d00001 diff --git a/third-party/lpsolve/src/main/resources/libs/win/x86/lpsolve55j.dll b/third-party/lpsolve/src/main/resources/libs/win/x86/lpsolve55j.dll new file mode 100644 index 0000000000000000000000000000000000000000..c80dab85e67a52c755a35a54cd8248780a552f80 GIT binary patch literal 102400 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 Q2mBoHbHLAm{}~Sa53K~(+W-In literal 0 HcmV?d00001 diff --git a/third-party/plexus-component-annotations/pom.xml b/third-party/plexus-component-annotations/pom.xml index 0becbd10..db6d105d 100644 --- a/third-party/plexus-component-annotations/pom.xml +++ b/third-party/plexus-component-annotations/pom.xml @@ -8,7 +8,7 @@ cz.zcu.kiv.crce wrapper-bundle-settings - 2.1.0-SNAPSHOT + 2.1.2-SNAPSHOT cz.zcu.kiv.crce.wrapper diff --git a/third-party/plexus-interpolation/pom.xml b/third-party/plexus-interpolation/pom.xml index b5b5b9bb..0af5351a 100644 --- a/third-party/plexus-interpolation/pom.xml +++ b/third-party/plexus-interpolation/pom.xml @@ -8,7 +8,7 @@ cz.zcu.kiv.crce wrapper-bundle-settings - 2.1.0-SNAPSHOT + 2.1.2-SNAPSHOT cz.zcu.kiv.crce.wrapper diff --git a/third-party/plexus-utils/pom.xml b/third-party/plexus-utils/pom.xml index 2186aad8..5d768752 100644 --- a/third-party/plexus-utils/pom.xml +++ b/third-party/plexus-utils/pom.xml @@ -8,7 +8,7 @@ cz.zcu.kiv.crce wrapper-bundle-settings - 2.1.0-SNAPSHOT + 2.1.2-SNAPSHOT cz.zcu.kiv.crce.wrapper From 688401be24f5f5ef4ae96db928f8226dadd93567 Mon Sep 17 00:00:00 2001 From: rpesek Date: Tue, 7 Aug 2018 14:21:44 +0200 Subject: [PATCH 13/85] Small modifications to the new webui module - modify module name (crce-webui-v2) - change text context web url (crce-webui) - disable switches (radio button) form CentralMaven if not created index --- build/pom.xml | 3 +- core/crce-metadata-api/.classpath | 1 + core/crce-metadata-api/.project | 10 +- core/crce-metadata-dao-api/.classpath | 1 + core/crce-metadata-dao-api/.project | 10 +- core/crce-metadata-impl/.classpath | 1 + core/crce-metadata-impl/.project | 10 +- core/crce-metadata-service-api/.classpath | 1 + core/crce-metadata-service-api/.project | 10 +- core/crce-metadata-service-impl/.classpath | 1 + core/crce-metadata-service-impl/.project | 10 +- core/crce-plugin-api/.classpath | 1 + core/crce-plugin-api/.project | 10 +- core/crce-repository-api/.classpath | 1 + core/crce-repository-api/.project | 10 +- core/crce-repository-impl/.classpath | 1 + core/crce-repository-impl/.project | 10 +- core/crce-resolver-api/.classpath | 1 + core/crce-resolver-api/.project | 10 +- core/crce-resolver-impl/.classpath | 1 + core/crce-resolver-impl/.project | 10 +- modules/crce-compatibility-api/.classpath | 1 + .../crce-compatibility-dao-mongodb/.classpath | 1 + modules/crce-concurrency/.classpath | 1 + modules/crce-concurrency/.project | 4 +- .../META-INF/MANIFEST.MF | 85 +++++----- modules/crce-handler-metrics/.classpath | 1 + modules/crce-integration-tests/.classpath | 2 + modules/crce-integration-tests/.project | 4 +- modules/crce-metadata-osgi-bundle/.classpath | 1 + modules/crce-optimizer-functions/.classpath | 1 + modules/crce-rest-v2/.classpath | 1 + modules/crce-vo/.classpath | 1 + modules/crce-vo/.project | 10 +- modules/crce-webservices-indexer/.classpath | 1 + .../.classpath | 1 + .../.project | 2 +- .../README.md | 0 .../pom.xml | 14 +- .../crce_webui_v2}/internal/Activator.java | 2 +- .../crce/crce_webui_v2}/other/KeyWord.java | 2 +- .../crce_webui_v2}/other/TypePackaging.java | 2 +- .../crce_webui_v2}/other/VersionInfo.java | 2 +- .../outer/CentralMavenForm.java | 145 +++++++++--------- .../outer/CheckMavenIndexForm.java | 4 +- .../outer/DefinedMavenForm.java | 8 +- .../crce_webui_v2}/outer/LoadFileForm.java | 4 +- .../crce_webui_v2}/outer/LocalMavenForm.java | 8 +- .../outer/classes/LocalMaven.java | 2 +- .../repository/ArtefactDetailForm.java | 10 +- .../crce_webui_v2}/repository/BufferForm.java | 10 +- .../repository/NewCapabilityForm.java | 6 +- .../repository/PluginEditForm.java | 4 +- .../repository/PluginsForm.java | 6 +- .../crce_webui_v2}/repository/StoreForm.java | 10 +- .../classes/CapabilityAttributeBean.java | 2 +- .../classes/RequirementAttributeBean.java | 2 +- .../repository/classes/ResourceBean.java | 2 +- .../repository/services/ResourceService.java | 7 +- .../crce/crce_webui_v2}/webui/AboutForm.java | 5 +- .../crce/crce_webui_v2}/webui/LoginForm.java | 2 +- .../crce_webui_v2}/webui/LogoBackground.java | 2 +- .../crce/crce_webui_v2}/webui/MenuForm.java | 2 +- .../kiv/crce/crce_webui_v2}/webui/MyUI.java | 24 +-- .../crce_webui_v2}/webui/SettingsForm.java | 2 +- .../src/main/resources/README | 0 .../webapp/VAADIN/themes/mytheme/addons.scss | 0 .../webapp/VAADIN/themes/mytheme/favicon.ico | Bin .../webapp/VAADIN/themes/mytheme/mytheme.scss | 0 .../webapp/VAADIN/themes/mytheme/styles.scss | 0 .../src/main/webapp/WEB-INF/web.xml | 4 +- modules/pom.xml | 2 +- 72 files changed, 277 insertions(+), 248 deletions(-) rename modules/{crce-webui-vaadin => crce-webui-v2}/.classpath (97%) rename modules/{crce-webui-vaadin => crce-webui-v2}/.project (98%) rename modules/{crce-webui-vaadin => crce-webui-v2}/README.md (100%) rename modules/{crce-webui-vaadin => crce-webui-v2}/pom.xml (97%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/internal/Activator.java (99%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/other/KeyWord.java (77%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/other/TypePackaging.java (57%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/other/VersionInfo.java (96%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/outer/CentralMavenForm.java (76%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/outer/CheckMavenIndexForm.java (95%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/outer/DefinedMavenForm.java (98%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/outer/LoadFileForm.java (97%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/outer/LocalMavenForm.java (95%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/outer/classes/LocalMaven.java (97%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/repository/ArtefactDetailForm.java (95%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/repository/BufferForm.java (95%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/repository/NewCapabilityForm.java (87%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/repository/PluginEditForm.java (96%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/repository/PluginsForm.java (93%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/repository/StoreForm.java (93%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/repository/classes/CapabilityAttributeBean.java (93%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/repository/classes/RequirementAttributeBean.java (93%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/repository/classes/ResourceBean.java (95%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/repository/services/ResourceService.java (96%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/webui/AboutForm.java (87%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/webui/LoginForm.java (98%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/webui/LogoBackground.java (90%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/webui/MenuForm.java (98%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/webui/MyUI.java (85%) rename modules/{crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin => crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2}/webui/SettingsForm.java (98%) rename modules/{crce-webui-vaadin => crce-webui-v2}/src/main/resources/README (100%) rename modules/{crce-webui-vaadin => crce-webui-v2}/src/main/webapp/VAADIN/themes/mytheme/addons.scss (100%) rename modules/{crce-webui-vaadin => crce-webui-v2}/src/main/webapp/VAADIN/themes/mytheme/favicon.ico (100%) rename modules/{crce-webui-vaadin => crce-webui-v2}/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss (100%) rename modules/{crce-webui-vaadin => crce-webui-v2}/src/main/webapp/VAADIN/themes/mytheme/styles.scss (100%) rename modules/{crce-webui-vaadin => crce-webui-v2}/src/main/webapp/WEB-INF/web.xml (84%) diff --git a/build/pom.xml b/build/pom.xml index c0f11ba2..7d6a13d1 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -77,7 +77,8 @@ org.apache.servicemix.tooling depends-maven-plugin - 1.2 + + 1.4.0 org.apache.felix diff --git a/core/crce-metadata-api/.classpath b/core/crce-metadata-api/.classpath index ff36ca09..83fc9ed7 100644 --- a/core/crce-metadata-api/.classpath +++ b/core/crce-metadata-api/.classpath @@ -15,6 +15,7 @@ + diff --git a/core/crce-metadata-api/.project b/core/crce-metadata-api/.project index dcddf63f..12b7d3a4 100644 --- a/core/crce-metadata-api/.project +++ b/core/crce-metadata-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-metadata-dao-api/.classpath b/core/crce-metadata-dao-api/.classpath index a086d4a1..dfdb3d58 100644 --- a/core/crce-metadata-dao-api/.classpath +++ b/core/crce-metadata-dao-api/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-metadata-dao-api/.project b/core/crce-metadata-dao-api/.project index 0d413bc0..7b6f96fd 100644 --- a/core/crce-metadata-dao-api/.project +++ b/core/crce-metadata-dao-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-metadata-impl/.classpath b/core/crce-metadata-impl/.classpath index a086d4a1..dfdb3d58 100644 --- a/core/crce-metadata-impl/.classpath +++ b/core/crce-metadata-impl/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-metadata-impl/.project b/core/crce-metadata-impl/.project index 98a8b9f1..851b7d39 100644 --- a/core/crce-metadata-impl/.project +++ b/core/crce-metadata-impl/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-metadata-service-api/.classpath b/core/crce-metadata-service-api/.classpath index a086d4a1..dfdb3d58 100644 --- a/core/crce-metadata-service-api/.classpath +++ b/core/crce-metadata-service-api/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-metadata-service-api/.project b/core/crce-metadata-service-api/.project index b10ca1c7..70e77ad8 100644 --- a/core/crce-metadata-service-api/.project +++ b/core/crce-metadata-service-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-metadata-service-impl/.classpath b/core/crce-metadata-service-impl/.classpath index a086d4a1..dfdb3d58 100644 --- a/core/crce-metadata-service-impl/.classpath +++ b/core/crce-metadata-service-impl/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-metadata-service-impl/.project b/core/crce-metadata-service-impl/.project index 16872220..a50b870e 100644 --- a/core/crce-metadata-service-impl/.project +++ b/core/crce-metadata-service-impl/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-plugin-api/.classpath b/core/crce-plugin-api/.classpath index a086d4a1..dfdb3d58 100644 --- a/core/crce-plugin-api/.classpath +++ b/core/crce-plugin-api/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-plugin-api/.project b/core/crce-plugin-api/.project index ec21180e..b8fae5ac 100644 --- a/core/crce-plugin-api/.project +++ b/core/crce-plugin-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-repository-api/.classpath b/core/crce-repository-api/.classpath index a086d4a1..dfdb3d58 100644 --- a/core/crce-repository-api/.classpath +++ b/core/crce-repository-api/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-repository-api/.project b/core/crce-repository-api/.project index b42166de..dbe9c738 100644 --- a/core/crce-repository-api/.project +++ b/core/crce-repository-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-repository-impl/.classpath b/core/crce-repository-impl/.classpath index a086d4a1..dfdb3d58 100644 --- a/core/crce-repository-impl/.classpath +++ b/core/crce-repository-impl/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-repository-impl/.project b/core/crce-repository-impl/.project index 9bb71646..823a8880 100644 --- a/core/crce-repository-impl/.project +++ b/core/crce-repository-impl/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-resolver-api/.classpath b/core/crce-resolver-api/.classpath index a086d4a1..dfdb3d58 100644 --- a/core/crce-resolver-api/.classpath +++ b/core/crce-resolver-api/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-resolver-api/.project b/core/crce-resolver-api/.project index 33c424b1..11cff5eb 100644 --- a/core/crce-resolver-api/.project +++ b/core/crce-resolver-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-resolver-impl/.classpath b/core/crce-resolver-impl/.classpath index a086d4a1..dfdb3d58 100644 --- a/core/crce-resolver-impl/.classpath +++ b/core/crce-resolver-impl/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-resolver-impl/.project b/core/crce-resolver-impl/.project index 16bc7094..4dec77e2 100644 --- a/core/crce-resolver-impl/.project +++ b/core/crce-resolver-impl/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/modules/crce-compatibility-api/.classpath b/modules/crce-compatibility-api/.classpath index ff36ca09..83fc9ed7 100644 --- a/modules/crce-compatibility-api/.classpath +++ b/modules/crce-compatibility-api/.classpath @@ -15,6 +15,7 @@ + diff --git a/modules/crce-compatibility-dao-mongodb/.classpath b/modules/crce-compatibility-dao-mongodb/.classpath index 0556be39..b8b4abe0 100644 --- a/modules/crce-compatibility-dao-mongodb/.classpath +++ b/modules/crce-compatibility-dao-mongodb/.classpath @@ -10,6 +10,7 @@ + diff --git a/modules/crce-concurrency/.classpath b/modules/crce-concurrency/.classpath index d2ddf387..03fa6514 100644 --- a/modules/crce-concurrency/.classpath +++ b/modules/crce-concurrency/.classpath @@ -15,6 +15,7 @@ + diff --git a/modules/crce-concurrency/.project b/modules/crce-concurrency/.project index bbee7626..dd8ac919 100644 --- a/modules/crce-concurrency/.project +++ b/modules/crce-concurrency/.project @@ -11,12 +11,12 @@ - org.eclipse.m2e.core.maven2Builder + org.fusesource.ide.project.RiderProjectBuilder - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder diff --git a/modules/crce-external-repository/META-INF/MANIFEST.MF b/modules/crce-external-repository/META-INF/MANIFEST.MF index 10f3fde5..c1a82452 100644 --- a/modules/crce-external-repository/META-INF/MANIFEST.MF +++ b/modules/crce-external-repository/META-INF/MANIFEST.MF @@ -1,6 +1,6 @@ Manifest-Version: 1.0 -Bnd-LastModified: 1529921920131 -Build-Jdk: 1.8.0_172 +Bnd-LastModified: 1533635192624 +Build-Jdk: 1.8.0_181 Built-By: rpesek Bundle-Activator: cz.zcu.kiv.crce.crce_external_repository.internal.Acti vator @@ -76,44 +76,45 @@ Embedded-Artifacts: lib/aether-api-1.13.1.jar;g="org.sonatype.aether";a= memory";v="3.6.2",lib/lucene-highlighter-3.6.2.jar;g="org.apache.lucene ";a="lucene-highlighter";v="3.6.2",lib/javax.annotation-api-1.2.jar;g=" javax.annotation";a="javax.annotation-api";v="1.2" -Export-Package: org.apache.maven.index;uses:="org.apache.maven.index.art - ifact,org.apache.maven.index.context,org.apache.maven.index.expr";versi - on="1.0.0",org.apache.maven.index.archetype;uses:="org.apache.maven.ind - ex.context";version="1.0.0",org.apache.maven.index.artifact;version="1. - 0.0",org.apache.maven.index.context;uses:="org.apache.maven.index,org.a - pache.maven.index.artifact";version="1.0.0",org.apache.maven.index.crea - tor;uses:="org.apache.maven.index,org.apache.maven.index.context";versi - on="1.0.0",org.apache.maven.index.expr;uses:="org.apache.maven.index";v - ersion="1.0.0",org.apache.maven.index.fs;version="1.0.0",org.apache.mav - en.index.incremental;uses:="org.apache.maven.index.packer,org.apache.ma - ven.index.updater";version="1.0.0",org.apache.maven.index.locator;uses: - ="org.apache.maven.index.artifact";version="1.0.0",org.apache.maven.ind - ex.packer;uses:="org.apache.maven.index.context";version="1.0.0",org.ap - ache.maven.index.search.grouping;uses:="org.apache.maven.index";version - ="1.0.0",org.apache.maven.index.treeview;uses:="org.apache.maven.index, - org.apache.maven.index.context";version="1.0.0",org.apache.maven.index. - updater;uses:="org.apache.maven.index.context,org.apache.maven.index.fs - ,org.apache.maven.index.incremental,org.apache.maven.wagon,org.apache.m - aven.wagon.authentication,org.apache.maven.wagon.events,org.apache.mave - n.wagon.proxy";version="1.0.0",org.apache.maven.index.util;uses:="org.a - pache.maven.index.context";version="1.0.0",org.apache.maven.index.util. - zip;version="1.0.0",org.apache.maven.wagon;uses:="org.apache.maven.wago - n.authentication,org.apache.maven.wagon.authorization,org.apache.maven. - wagon.events,org.apache.maven.wagon.proxy,org.apache.maven.wagon.reposi - tory,org.apache.maven.wagon.resource";version="1.0.0",org.apache.maven. - wagon.authentication;uses:="org.apache.maven.wagon";version="1.0.0",org - .apache.maven.wagon.authorization;uses:="org.apache.maven.wagon";versio - n="1.0.0",org.apache.maven.wagon.events;uses:="org.apache.maven.wagon,o - rg.apache.maven.wagon.resource";version="1.0.0",org.apache.maven.wagon. - observers;uses:="org.apache.maven.wagon.events";version="1.0.0",org.apa - che.maven.wagon.providers.http;uses:="org.apache.maven.wagon,org.apache - .maven.wagon.authentication,org.apache.maven.wagon.authorization,org.ap - ache.maven.wagon.proxy,org.apache.maven.wagon.resource";version="1.0.0" - ,org.apache.maven.wagon.proxy;version="1.0.0",org.apache.maven.wagon.re - pository;version="1.0.0",org.apache.maven.wagon.resource;version="1.0.0 - ",org.apache.maven.wagon.shared.http4;uses:="org.apache.maven.wagon,org - .apache.maven.wagon.authorization,org.apache.maven.wagon.repository,org - .apache.maven.wagon.resource";version="1.0.0",javax.inject;version="1.0 - .0",cz.zcu.kiv.crce.crce_external_repository.api;version="1.0.0" -Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))" +Export-Package: cz.zcu.kiv.crce.crce_external_repository.api;uses:="org. + apache.maven.index";version="1.0.0",org.apache.maven.index;uses:="org.a + pache.maven.index.artifact,org.apache.maven.index.context,org.apache.ma + ven.index.expr";version="1.0.0",org.apache.maven.index.archetype;uses:= + "org.apache.maven.index.context";version="1.0.0",org.apache.maven.index + .artifact;version="1.0.0",org.apache.maven.index.context;uses:="org.apa + che.maven.index,org.apache.maven.index.artifact";version="1.0.0",org.ap + ache.maven.index.creator;uses:="org.apache.maven.index,org.apache.maven + .index.context";version="1.0.0",org.apache.maven.index.expr;uses:="org. + apache.maven.index";version="1.0.0",org.apache.maven.index.fs;version=" + 1.0.0",org.apache.maven.index.incremental;uses:="org.apache.maven.index + .packer,org.apache.maven.index.updater";version="1.0.0",org.apache.mave + n.index.locator;uses:="org.apache.maven.index.artifact";version="1.0.0" + ,org.apache.maven.index.packer;uses:="org.apache.maven.index.context";v + ersion="1.0.0",org.apache.maven.index.search.grouping;uses:="org.apache + .maven.index";version="1.0.0",org.apache.maven.index.treeview;uses:="or + g.apache.maven.index,org.apache.maven.index.context";version="1.0.0",or + g.apache.maven.index.updater;uses:="org.apache.maven.index.context,org. + apache.maven.index.fs,org.apache.maven.index.incremental,org.apache.mav + en.wagon,org.apache.maven.wagon.authentication,org.apache.maven.wagon.e + vents,org.apache.maven.wagon.proxy";version="1.0.0",org.apache.maven.in + dex.util;uses:="org.apache.maven.index.context";version="1.0.0",org.apa + che.maven.index.util.zip;version="1.0.0",org.apache.maven.wagon;uses:=" + org.apache.maven.wagon.authentication,org.apache.maven.wagon.authorizat + ion,org.apache.maven.wagon.events,org.apache.maven.wagon.proxy,org.apac + he.maven.wagon.repository,org.apache.maven.wagon.resource";version="1.0 + .0",org.apache.maven.wagon.authentication;uses:="org.apache.maven.wagon + ";version="1.0.0",org.apache.maven.wagon.authorization;uses:="org.apach + e.maven.wagon";version="1.0.0",org.apache.maven.wagon.events;uses:="org + .apache.maven.wagon,org.apache.maven.wagon.resource";version="1.0.0",or + g.apache.maven.wagon.observers;uses:="org.apache.maven.wagon.events";ve + rsion="1.0.0",org.apache.maven.wagon.providers.http;uses:="org.apache.m + aven.wagon,org.apache.maven.wagon.authentication,org.apache.maven.wagon + .authorization,org.apache.maven.wagon.proxy,org.apache.maven.wagon.reso + urce";version="1.0.0",org.apache.maven.wagon.proxy;version="1.0.0",org. + apache.maven.wagon.repository;version="1.0.0",org.apache.maven.wagon.re + source;version="1.0.0",org.apache.maven.wagon.shared.http4;uses:="org.a + pache.maven.wagon,org.apache.maven.wagon.authorization,org.apache.maven + .wagon.repository,org.apache.maven.wagon.resource";version="1.0.0",java + x.inject;version="1.0.0" +Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))" Tool: Bnd-3.3.0.201609221906 diff --git a/modules/crce-handler-metrics/.classpath b/modules/crce-handler-metrics/.classpath index 0556be39..b8b4abe0 100644 --- a/modules/crce-handler-metrics/.classpath +++ b/modules/crce-handler-metrics/.classpath @@ -10,6 +10,7 @@ + diff --git a/modules/crce-integration-tests/.classpath b/modules/crce-integration-tests/.classpath index b2acffc9..db82fad3 100644 --- a/modules/crce-integration-tests/.classpath +++ b/modules/crce-integration-tests/.classpath @@ -10,11 +10,13 @@ + + diff --git a/modules/crce-integration-tests/.project b/modules/crce-integration-tests/.project index eda13523..da2260e0 100644 --- a/modules/crce-integration-tests/.project +++ b/modules/crce-integration-tests/.project @@ -11,12 +11,12 @@ - org.eclipse.m2e.core.maven2Builder + org.fusesource.ide.project.RiderProjectBuilder - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder diff --git a/modules/crce-metadata-osgi-bundle/.classpath b/modules/crce-metadata-osgi-bundle/.classpath index a086d4a1..dfdb3d58 100644 --- a/modules/crce-metadata-osgi-bundle/.classpath +++ b/modules/crce-metadata-osgi-bundle/.classpath @@ -10,6 +10,7 @@ + diff --git a/modules/crce-optimizer-functions/.classpath b/modules/crce-optimizer-functions/.classpath index 0556be39..b8b4abe0 100644 --- a/modules/crce-optimizer-functions/.classpath +++ b/modules/crce-optimizer-functions/.classpath @@ -10,6 +10,7 @@ + diff --git a/modules/crce-rest-v2/.classpath b/modules/crce-rest-v2/.classpath index f3932ed9..f3b0f012 100644 --- a/modules/crce-rest-v2/.classpath +++ b/modules/crce-rest-v2/.classpath @@ -10,6 +10,7 @@ + diff --git a/modules/crce-vo/.classpath b/modules/crce-vo/.classpath index ff36ca09..83fc9ed7 100644 --- a/modules/crce-vo/.classpath +++ b/modules/crce-vo/.classpath @@ -15,6 +15,7 @@ + diff --git a/modules/crce-vo/.project b/modules/crce-vo/.project index d54bba6a..f1c272fb 100644 --- a/modules/crce-vo/.project +++ b/modules/crce-vo/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/modules/crce-webservices-indexer/.classpath b/modules/crce-webservices-indexer/.classpath index 0556be39..b8b4abe0 100644 --- a/modules/crce-webservices-indexer/.classpath +++ b/modules/crce-webservices-indexer/.classpath @@ -10,6 +10,7 @@ + diff --git a/modules/crce-webui-vaadin/.classpath b/modules/crce-webui-v2/.classpath similarity index 97% rename from modules/crce-webui-vaadin/.classpath rename to modules/crce-webui-v2/.classpath index 54b64112..9b7de225 100644 --- a/modules/crce-webui-vaadin/.classpath +++ b/modules/crce-webui-v2/.classpath @@ -15,6 +15,7 @@ + diff --git a/modules/crce-webui-vaadin/.project b/modules/crce-webui-v2/.project similarity index 98% rename from modules/crce-webui-vaadin/.project rename to modules/crce-webui-v2/.project index f693cc9b..eac49f46 100644 --- a/modules/crce-webui-vaadin/.project +++ b/modules/crce-webui-v2/.project @@ -1,6 +1,6 @@ - crce-webui-vaadin + crce-webui-v2 diff --git a/modules/crce-webui-vaadin/README.md b/modules/crce-webui-v2/README.md similarity index 100% rename from modules/crce-webui-vaadin/README.md rename to modules/crce-webui-v2/README.md diff --git a/modules/crce-webui-vaadin/pom.xml b/modules/crce-webui-v2/pom.xml similarity index 97% rename from modules/crce-webui-vaadin/pom.xml rename to modules/crce-webui-v2/pom.xml index 6331c5ab..8b8e7c7d 100644 --- a/modules/crce-webui-vaadin/pom.xml +++ b/modules/crce-webui-v2/pom.xml @@ -10,16 +10,16 @@ 2.1.1-SNAPSHOT - crce-webui-vaadin + crce-webui-v2 war - 1.1 - CRCE - Web UI (Vaadin) + 1.2 + CRCE - Web UI - CRCE - Web UI (Vaadin) - ${namespace}.crce_webui_vaadin + CRCE - Web UI + ${namespace}.crce_webui_v2 7.7.10 7.7.10 9.3.9.v20160517 @@ -338,8 +338,8 @@ WEB-INF/lib/lucene-memory-3.6.2.jar, WEB-INF/lib/lucene-highlighter-3.6.2.jar --> - crce-vaadin - crce-vaadin + crce-webui + crce-webui <_wab>src/main/webapp diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/internal/Activator.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/internal/Activator.java similarity index 99% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/internal/Activator.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/internal/Activator.java index 9be82d29..7c8dc49d 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/internal/Activator.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/internal/Activator.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.internal; +package cz.zcu.kiv.crce.crce_webui_v2.internal; import java.util.Collection; import java.util.HashMap; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/KeyWord.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/KeyWord.java similarity index 77% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/KeyWord.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/KeyWord.java index c5efeaa1..5550eb74 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/KeyWord.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/KeyWord.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.other; +package cz.zcu.kiv.crce.crce_webui_v2.other; public class KeyWord { private String keyWord; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/TypePackaging.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/TypePackaging.java similarity index 57% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/TypePackaging.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/TypePackaging.java index af77ae48..f5cdadf4 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/TypePackaging.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/TypePackaging.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.other; +package cz.zcu.kiv.crce.crce_webui_v2.other; public enum TypePackaging { jar,war,ejb,ear,pom,maven_plugin diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/VersionInfo.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/VersionInfo.java similarity index 96% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/VersionInfo.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/VersionInfo.java index 4721a6f7..c45f7222 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/other/VersionInfo.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/VersionInfo.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.other; +package cz.zcu.kiv.crce.crce_webui_v2.other; import java.io.IOException; import java.io.InputStream; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java similarity index 76% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java index 609774f0..93ac372f 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CentralMavenForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.outer; +package cz.zcu.kiv.crce.crce_webui_v2.outer; import java.io.File; import java.io.IOException; @@ -28,9 +28,9 @@ import cz.zcu.kiv.crce.crce_external_repository.api.CentralMaven; import cz.zcu.kiv.crce.crce_external_repository.api.ResultSearchArtifactTree; import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; -import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; -import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; -import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_v2.other.TypePackaging; +import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; import cz.zcu.kiv.crce.repository.RefusedArtifactException; @SuppressWarnings("serial") @@ -71,6 +71,12 @@ public CentralMavenForm(MyUI myUI) { directIndexOption.addItems("Direct", "Index"); directIndexOption.setValue("Direct"); + if (myUI.getSession().getAttribute("mavenIndex") == null) { + directIndexOption.setItemEnabled("Index", false); + directIndexOption.setDescription( + "The central maven repository index is not created. Check its creation in the settings menu"); + } + rangeOption.addItem("<="); rangeOption.addItem("="); rangeOption.addItem(">="); @@ -116,10 +122,10 @@ public CentralMavenForm(MyUI myUI) { tree.addItem(pom[i]); tree.setParent(pom[i], pom[i - 1]); } - //addArtifactToTree(artifactTree, pom[pom.length - 1]); - addArtifactToTree(artifactTree.getUrl(), artifactTree.getGroupId(), artifactTree.getArtefactId(), + // addArtifactToTree(artifactTree, pom[pom.length - 1]); + addArtifactToTree(artifactTree.getUrl(), artifactTree.getGroupId(), artifactTree.getArtefactId(), artifactTree.getVersions().get(0), artifactTree.getPackaging(), pom[pom.length - 1]); - + // for margin HorizontalLayout treePanelLayout = new HorizontalLayout(); treePanelLayout.addComponent(tree); @@ -135,11 +141,13 @@ public CentralMavenForm(MyUI myUI) { String[] pom = artifactTree.getGroupId().split("/"); String uniqueItemChildren, uniqueItemParent = "/"; - /*for central maven2 url - the correct is the listing over all items, - but in this case the first is empty and the second is maven2*/ - for(int i = 2; i < pom.length; i++) { + /* + * for central maven2 url - the correct is the listing over all items, but in + * this case the first is empty and the second is maven2 + */ + for (int i = 2; i < pom.length; i++) { uniqueItemChildren = uniqueItemParent + pom[i] + "/"; - if(tree.getItem(uniqueItemChildren) == null) { + if (tree.getItem(uniqueItemChildren) == null) { tree.addItem(uniqueItemChildren); tree.setItemCaption(uniqueItemChildren, pom[i]); tree.setParent(uniqueItemChildren, uniqueItemParent); @@ -147,17 +155,13 @@ public CentralMavenForm(MyUI myUI) { uniqueItemParent = uniqueItemChildren; } addArtefactToTreeGroup(artifactTree, uniqueItemParent); - /*for (int i = 1; i < pom.length; i++) { - uniqueItem = uniqueItem + pom[i]; - - if (tree.getItem(pom[i]) == null) { - tree.addItem(pom[i]); - tree.setParent(pom[i], pom[i - 1]); - } else { - tree.setParent(pom[i], pom[i - 1]); - } - } - addArtefactToTreeGroup(artifactTree, pom[pom.length - 1]);*/ + /* + * for (int i = 1; i < pom.length; i++) { uniqueItem = uniqueItem + pom[i]; + * + * if (tree.getItem(pom[i]) == null) { tree.addItem(pom[i]); + * tree.setParent(pom[i], pom[i - 1]); } else { tree.setParent(pom[i], pom[i - + * 1]); } } addArtefactToTreeGroup(artifactTree, pom[pom.length - 1]); + */ } // for margin HorizontalLayout treePanelLayout = new HorizontalLayout(); @@ -192,51 +196,50 @@ public CentralMavenForm(MyUI myUI) { notif.setDelayMsec(5000); notif.show(Page.getCurrent()); } else { - if(myUI.getSession().getAttribute("mavenIndex") == null) { - Notification notif = new Notification( - "The central maven repository index is not created. Check its creation in the settings menu", - Notification.Type.WARNING_MESSAGE); - notif.setDelayMsec(5000); - notif.show(Page.getCurrent()); - } - else { - ResultSearchArtifactTree artifactList = new CentralMaven( - (SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).getArtifactTree(group.getValue(), - artifact.getValue(), version.getValue(), packaging.getValue(), - directIndexOption.getValue(), rangeOption.getValue().toString()); - if(artifactList.getStatus().equals("found")) { - for (ArtifactTree artifactTree : artifactList.getArtifactTreeList()) { - String[] pom = artifactTree.getGroupId().split("\\."); - tree.addItem(pom[0]); - for (int i = 1; i < pom.length; i++) { - tree.addItem(pom[i]); - tree.setParent(pom[i], pom[i - 1]); - } - for (String s : artifactTree.getVersions()) { - addArtifactToTree(artifactTree.getUrl(), artifactTree.getGroupId(), artifactTree.getArtefactId(), s, - artifactTree.getPackaging(),pom[pom.length - 1]); - } + /* + * if(myUI.getSession().getAttribute("mavenIndex") == null) { Notification notif + * = new Notification( + * "The central maven repository index is not created. Check its creation in the settings menu" + * , Notification.Type.WARNING_MESSAGE); notif.setDelayMsec(5000); + * notif.show(Page.getCurrent()); } else { + */ + ResultSearchArtifactTree artifactList = new CentralMaven( + (SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).getArtifactTree( + group.getValue(), artifact.getValue(), version.getValue(), packaging.getValue(), + directIndexOption.getValue(), rangeOption.getValue().toString()); + if (artifactList.getStatus().equals("found")) { + for (ArtifactTree artifactTree : artifactList.getArtifactTreeList()) { + String[] pom = artifactTree.getGroupId().split("\\."); + tree.addItem(pom[0]); + for (int i = 1; i < pom.length; i++) { + tree.addItem(pom[i]); + tree.setParent(pom[i], pom[i - 1]); + } + for (String s : artifactTree.getVersions()) { + addArtifactToTree(artifactTree.getUrl(), artifactTree.getGroupId(), + artifactTree.getArtefactId(), s, artifactTree.getPackaging(), + pom[pom.length - 1]); } - // for margin - HorizontalLayout treePanelLayout = new HorizontalLayout(); - treePanelLayout.addComponent(tree); - treePanelLayout.setMargin(true); - treePanel.setContent(treePanelLayout); - formPanelButtonLayout.addComponents(treePanel, uploadButton); - formPanelButtonLayout.setMargin(true); - formPanelButtonLayout.setSpacing(true); - formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); - uploadButton.setVisible(false); - } - else if(artifactList.getStatus().equals("notfound")){ - HorizontalLayout treePanelLayout = new HorizontalLayout(); - treePanelLayout.addComponent(notFound); - treePanelLayout.setMargin(true); - treePanel.setContent(treePanelLayout); - formPanelButtonLayout.addComponents(treePanel); - formPanelButtonLayout.setMargin(true); } + // for margin + HorizontalLayout treePanelLayout = new HorizontalLayout(); + treePanelLayout.addComponent(tree); + treePanelLayout.setMargin(true); + treePanel.setContent(treePanelLayout); + formPanelButtonLayout.addComponents(treePanel, uploadButton); + formPanelButtonLayout.setMargin(true); + formPanelButtonLayout.setSpacing(true); + formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); + uploadButton.setVisible(false); + } else if (artifactList.getStatus().equals("notfound")) { + HorizontalLayout treePanelLayout = new HorizontalLayout(); + treePanelLayout.addComponent(notFound); + treePanelLayout.setMargin(true); + treePanel.setContent(treePanelLayout); + formPanelButtonLayout.addComponents(treePanel); + formPanelButtonLayout.setMargin(true); } + /* } */ } } content.addComponent(formPanelButtonLayout); @@ -301,9 +304,10 @@ else if(artifactList.getStatus().equals("notfound")){ addComponent(content); } - private void addArtifactToTree(String url, String group, String artifact, String version, String packaging, String parent) { + private void addArtifactToTree(String url, String group, String artifact, String version, String packaging, + String parent) { String uniqueVersion = artifact + version; - + tree.addItem(artifact); tree.setParent(artifact, parent); tree.addItem(uniqueVersion); @@ -312,13 +316,12 @@ private void addArtifactToTree(String url, String group, String artifact, String // konečný artefact je komplet url link např. pro wget - UPRAVIT DLE // POTŘEBY - String artifactText = url + group.replace('.', '/') + "/" + artifact + "/" + version + "/" + - artifact + "-" + version + "." + packaging; + String artifactText = url + group.replace('.', '/') + "/" + artifact + "/" + version + "/" + artifact + "-" + + version + "." + packaging; tree.addItem(artifactText); tree.setParent(artifactText, uniqueVersion); - tree.setItemCaption(artifactText, - artifact + "-" + version + "." + packaging); + tree.setItemCaption(artifactText, artifact + "-" + version + "." + packaging); tree.setChildrenAllowed(artifactText, false); if (packaging.equals("jar") || packaging.equals("war")) { tree.setItemIcon(artifactText, FontAwesome.GIFT); @@ -328,7 +331,7 @@ private void addArtifactToTree(String url, String group, String artifact, String tree.setItemIcon(artifactText, FontAwesome.FILE); } } - + private void addArtefactToTreeGroup(ArtifactTree artifactTree, String parent) { // konečný artefact je komplet url link např. pro wget - UPRAVIT DLE // POTŘEBY diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CheckMavenIndexForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CheckMavenIndexForm.java similarity index 95% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CheckMavenIndexForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CheckMavenIndexForm.java index 8f3fffbf..0831e4fd 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/CheckMavenIndexForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CheckMavenIndexForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.outer; +package cz.zcu.kiv.crce.crce_webui_v2.outer; import com.vaadin.server.VaadinSession; import com.vaadin.ui.Button; @@ -10,7 +10,7 @@ import cz.zcu.kiv.crce.crce_external_repository.api.MavenIndex; import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; -import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; @SuppressWarnings("serial") public class CheckMavenIndexForm extends FormLayout { diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/DefinedMavenForm.java similarity index 98% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/DefinedMavenForm.java index c4494fd8..9cf0debc 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/DefinedMavenForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/DefinedMavenForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.outer; +package cz.zcu.kiv.crce.crce_webui_v2.outer; import java.io.File; import java.io.IOException; @@ -28,9 +28,9 @@ import cz.zcu.kiv.crce.crce_external_repository.api.ArtifactTree; import cz.zcu.kiv.crce.crce_external_repository.api.DefinedMaven; import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; -import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; -import cz.zcu.kiv.crce.crce_webui_vaadin.other.TypePackaging; -import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_v2.other.TypePackaging; +import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; import cz.zcu.kiv.crce.repository.RefusedArtifactException; public class DefinedMavenForm extends FormLayout{ diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LoadFileForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LoadFileForm.java similarity index 97% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LoadFileForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LoadFileForm.java index f82b51e9..dc357130 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LoadFileForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LoadFileForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.outer; +package cz.zcu.kiv.crce.crce_webui_v2.outer; import java.io.File; import java.io.FileNotFoundException; @@ -26,7 +26,7 @@ import com.vaadin.ui.Upload.SucceededListener; import com.vaadin.ui.VerticalLayout; -import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; import cz.zcu.kiv.crce.repository.RefusedArtifactException; @SuppressWarnings("serial") diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LocalMavenForm.java similarity index 95% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LocalMavenForm.java index baa26d59..24cd7f2f 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/LocalMavenForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LocalMavenForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.outer; +package cz.zcu.kiv.crce.crce_webui_v2.outer; import java.io.File; import java.io.IOException; @@ -24,9 +24,9 @@ import com.vaadin.ui.themes.ValoTheme; import com.vaadin.ui.VerticalLayout; -import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; -import cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes.LocalMaven; -import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_v2.outer.classes.LocalMaven; +import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; import cz.zcu.kiv.crce.repository.RefusedArtifactException; @SuppressWarnings("serial") diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/LocalMaven.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/classes/LocalMaven.java similarity index 97% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/LocalMaven.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/classes/LocalMaven.java index 90ab17e5..f917d581 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/outer/classes/LocalMaven.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/classes/LocalMaven.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.outer.classes; +package cz.zcu.kiv.crce.crce_webui_v2.outer.classes; import java.io.File; import java.io.Serializable; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/ArtefactDetailForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/ArtefactDetailForm.java similarity index 95% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/ArtefactDetailForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/ArtefactDetailForm.java index 8e4aeaa8..2eecdf6d 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/ArtefactDetailForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/ArtefactDetailForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.repository; +package cz.zcu.kiv.crce.crce_webui_v2.repository; import java.util.ArrayList; import java.util.List; @@ -16,10 +16,10 @@ import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.CapabilityAttributeBean; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.RequirementAttributeBean; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; -import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.CapabilityAttributeBean; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.RequirementAttributeBean; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; import cz.zcu.kiv.crce.metadata.Attribute; import cz.zcu.kiv.crce.metadata.Capability; import cz.zcu.kiv.crce.metadata.Requirement; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/BufferForm.java similarity index 95% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/BufferForm.java index 2db16fca..2c62df45 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/BufferForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/BufferForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.repository; +package cz.zcu.kiv.crce.crce_webui_v2.repository; import java.util.List; @@ -22,10 +22,10 @@ import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; -import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.services.ResourceService; -import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_v2.repository.services.ResourceService; +import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; public class BufferForm extends FormLayout{ private static final long serialVersionUID = 6675695008606881678L; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/NewCapabilityForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/NewCapabilityForm.java similarity index 87% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/NewCapabilityForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/NewCapabilityForm.java index af771fb7..43b4d82d 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/NewCapabilityForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/NewCapabilityForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.repository; +package cz.zcu.kiv.crce.crce_webui_v2.repository; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.shared.ui.MarginInfo; @@ -9,8 +9,8 @@ import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; -import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; @SuppressWarnings("serial") public class NewCapabilityForm extends FormLayout{ diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginEditForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/PluginEditForm.java similarity index 96% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginEditForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/PluginEditForm.java index c737156c..0ec98eac 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginEditForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/PluginEditForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.repository; +package cz.zcu.kiv.crce.crce_webui_v2.repository; import java.util.ArrayList; @@ -14,7 +14,7 @@ import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; -import cz.zcu.kiv.crce.crce_webui_vaadin.other.KeyWord; +import cz.zcu.kiv.crce.crce_webui_v2.other.KeyWord; import cz.zcu.kiv.crce.plugin.Plugin; @SuppressWarnings("serial") diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/PluginsForm.java similarity index 93% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/PluginsForm.java index 30d5c978..a7a93abd 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/PluginsForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/PluginsForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.repository; +package cz.zcu.kiv.crce.crce_webui_v2.repository; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.shared.ui.MarginInfo; @@ -9,8 +9,8 @@ import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; -import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; -import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; import cz.zcu.kiv.crce.plugin.Plugin; @SuppressWarnings("serial") diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/StoreForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/StoreForm.java similarity index 93% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/StoreForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/StoreForm.java index 36f5169b..411b970b 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/StoreForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/StoreForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.repository; +package cz.zcu.kiv.crce.crce_webui_v2.repository; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.event.ShortcutAction.KeyCode; @@ -20,10 +20,10 @@ import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; -import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.services.ResourceService; -import cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI; +import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_v2.repository.services.ResourceService; +import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; public class StoreForm extends FormLayout{ private static final long serialVersionUID = 7439970261502810719L; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/CapabilityAttributeBean.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/classes/CapabilityAttributeBean.java similarity index 93% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/CapabilityAttributeBean.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/classes/CapabilityAttributeBean.java index fa6c19c8..fbd03afc 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/CapabilityAttributeBean.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/classes/CapabilityAttributeBean.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes; +package cz.zcu.kiv.crce.crce_webui_v2.repository.classes; public class CapabilityAttributeBean { private String designation; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/RequirementAttributeBean.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/classes/RequirementAttributeBean.java similarity index 93% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/RequirementAttributeBean.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/classes/RequirementAttributeBean.java index 4a77f0a2..f50e6c6b 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/RequirementAttributeBean.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/classes/RequirementAttributeBean.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes; +package cz.zcu.kiv.crce.crce_webui_v2.repository.classes; public class RequirementAttributeBean { private String designation; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/ResourceBean.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/classes/ResourceBean.java similarity index 95% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/ResourceBean.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/classes/ResourceBean.java index 297c1788..729f6a23 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/classes/ResourceBean.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/classes/ResourceBean.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes; +package cz.zcu.kiv.crce.crce_webui_v2.repository.classes; import cz.zcu.kiv.crce.metadata.Resource; import cz.zcu.kiv.crce.metadata.type.Version; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/services/ResourceService.java similarity index 96% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/services/ResourceService.java index 549426ef..7ef61394 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/repository/services/ResourceService.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/services/ResourceService.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.repository.services; +package cz.zcu.kiv.crce.crce_webui_v2.repository.services; import java.io.IOException; import java.io.Serializable; @@ -10,8 +10,9 @@ import com.vaadin.server.VaadinSession; import com.vaadin.server.WrappedSession; -import cz.zcu.kiv.crce.crce_webui_vaadin.internal.Activator; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; + +import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; import cz.zcu.kiv.crce.metadata.Capability; import cz.zcu.kiv.crce.metadata.Resource; import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiBundle; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/AboutForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/AboutForm.java similarity index 87% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/AboutForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/AboutForm.java index 08d6fd71..9a140a6b 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/AboutForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/AboutForm.java @@ -1,10 +1,11 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.webui; +package cz.zcu.kiv.crce.crce_webui_v2.webui; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; -import cz.zcu.kiv.crce.crce_webui_vaadin.other.VersionInfo; + +import cz.zcu.kiv.crce.crce_webui_v2.other.VersionInfo; @SuppressWarnings("serial") public class AboutForm extends FormLayout{ diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LoginForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/LoginForm.java similarity index 98% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LoginForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/LoginForm.java index a1ca1586..a7366121 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LoginForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/LoginForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.webui; +package cz.zcu.kiv.crce.crce_webui_v2.webui; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.shared.ui.MarginInfo; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LogoBackground.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/LogoBackground.java similarity index 90% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LogoBackground.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/LogoBackground.java index fc4b0243..25f09ad6 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/LogoBackground.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/LogoBackground.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.webui; +package cz.zcu.kiv.crce.crce_webui_v2.webui; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.FormLayout; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MenuForm.java similarity index 98% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MenuForm.java index 284299f4..4e548b90 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MenuForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MenuForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.webui; +package cz.zcu.kiv.crce.crce_webui_v2.webui; import com.vaadin.annotations.StyleSheet; import com.vaadin.shared.ui.MarginInfo; diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MyUI.java similarity index 85% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MyUI.java index e43384dd..4676eda7 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/MyUI.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MyUI.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.webui; +package cz.zcu.kiv.crce.crce_webui_v2.webui; import javax.servlet.annotation.WebServlet; @@ -12,17 +12,17 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import cz.zcu.kiv.crce.crce_webui_vaadin.outer.CentralMavenForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.outer.CheckMavenIndexForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.outer.DefinedMavenForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.outer.LoadFileForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.outer.LocalMavenForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.ArtefactDetailForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.BufferForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.NewCapabilityForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.PluginsForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.StoreForm; -import cz.zcu.kiv.crce.crce_webui_vaadin.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_v2.outer.CentralMavenForm; +import cz.zcu.kiv.crce.crce_webui_v2.outer.CheckMavenIndexForm; +import cz.zcu.kiv.crce.crce_webui_v2.outer.DefinedMavenForm; +import cz.zcu.kiv.crce.crce_webui_v2.outer.LoadFileForm; +import cz.zcu.kiv.crce.crce_webui_v2.outer.LocalMavenForm; +import cz.zcu.kiv.crce.crce_webui_v2.repository.ArtefactDetailForm; +import cz.zcu.kiv.crce.crce_webui_v2.repository.BufferForm; +import cz.zcu.kiv.crce.crce_webui_v2.repository.NewCapabilityForm; +import cz.zcu.kiv.crce.crce_webui_v2.repository.PluginsForm; +import cz.zcu.kiv.crce.crce_webui_v2.repository.StoreForm; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; /** diff --git a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java similarity index 98% rename from modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java rename to modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java index 1764bb61..949a3107 100644 --- a/modules/crce-webui-vaadin/src/main/java/cz/zcu/kiv/crce/crce_webui_vaadin/webui/SettingsForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java @@ -1,4 +1,4 @@ -package cz.zcu.kiv.crce.crce_webui_vaadin.webui; +package cz.zcu.kiv.crce.crce_webui_v2.webui; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.server.Page; diff --git a/modules/crce-webui-vaadin/src/main/resources/README b/modules/crce-webui-v2/src/main/resources/README similarity index 100% rename from modules/crce-webui-vaadin/src/main/resources/README rename to modules/crce-webui-v2/src/main/resources/README diff --git a/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss b/modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/addons.scss similarity index 100% rename from modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss rename to modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/addons.scss diff --git a/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico b/modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/favicon.ico similarity index 100% rename from modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico rename to modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/favicon.ico diff --git a/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss b/modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss similarity index 100% rename from modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss rename to modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss diff --git a/modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss b/modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/styles.scss similarity index 100% rename from modules/crce-webui-vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss rename to modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/styles.scss diff --git a/modules/crce-webui-vaadin/src/main/webapp/WEB-INF/web.xml b/modules/crce-webui-v2/src/main/webapp/WEB-INF/web.xml similarity index 84% rename from modules/crce-webui-vaadin/src/main/webapp/WEB-INF/web.xml rename to modules/crce-webui-v2/src/main/webapp/WEB-INF/web.xml index 3116477f..a4999902 100644 --- a/modules/crce-webui-vaadin/src/main/webapp/WEB-INF/web.xml +++ b/modules/crce-webui-v2/src/main/webapp/WEB-INF/web.xml @@ -1,7 +1,7 @@ - crce-webui-vaadin + crce-webui_2 org.atmosphere.cpr.SessionSupport true @@ -12,7 +12,7 @@ MyUIServlet - cz.zcu.kiv.crce.crce_webui_vaadin.webui.MyUI$MyUIServlet + cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI$MyUIServlet MyUIServlet diff --git a/modules/pom.xml b/modules/pom.xml index 927021b4..95f437d6 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -69,7 +69,7 @@ - crce-webui-vaadin + crce-webui-v2 From e1255d4dd1634d1538ea775bd3d9fd3935e919c7 Mon Sep 17 00:00:00 2001 From: rpesek Date: Tue, 7 Aug 2018 14:32:37 +0200 Subject: [PATCH 14/85] Module crce-webui-v2 - edit in the README file --- modules/crce-webui-v2/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/crce-webui-v2/README.md b/modules/crce-webui-v2/README.md index 6b54f414..ce4dfaa3 100644 --- a/modules/crce-webui-v2/README.md +++ b/modules/crce-webui-v2/README.md @@ -1,4 +1,4 @@ -crce-webui-vaadin +crce-webui-v2 ============== Template for a simple Vaadin application that only requires a Servlet 3.0 container to run. @@ -9,7 +9,7 @@ Workflow To compile the entire project, run "mvn install". -To run the application, run "mvn jetty:run" and open http://localhost:8080/ . +To run the application, run "mvn jetty:run" and open http://localhost:8080/crce-webui . To produce a deployable production mode WAR: - change productionMode to true in the servlet class configuration (nested in the UI class) From b306444177bea021dd95169e6fb8f13d6ada68f2 Mon Sep 17 00:00:00 2001 From: Premek Brada Date: Tue, 7 Aug 2018 16:01:44 +0200 Subject: [PATCH 15/85] added Eclipse project files to ignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7ff327c6..4f35f1f4 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,8 @@ tmp/ local.properties .settings/ .loadpath +.classpath +.project # Locally stored "Eclipse launch configurations" *.launch From 445b294691350ac26899adb527f0fb05b325baae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emek=20Brada?= Date: Thu, 9 Aug 2018 11:46:57 +0200 Subject: [PATCH 16/85] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f2719d8..c47a0b0e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ CRCE is an experimental repository, designed to support research into component- ## Prerequisities -- **JDK 7** set in `JAVA_HOME` environment variable before starting CRCE (there is a problem with running web UI on JDK 8, need to update dependencies), tested on 1.7.0_80 +- **JDK 8** set in `JAVA_HOME` environment variable before starting CRCE, tested on 1.8.0_171 - **MongoDB**, tested on v2.6.10, v3.4.10 - **Maven 3**, tested on 3.5.2 From 837f19642331b257ce2072ca9c1d03a4e526aa30 Mon Sep 17 00:00:00 2001 From: rpesek Date: Tue, 14 Aug 2018 13:03:07 +0200 Subject: [PATCH 17/85] Editing the Web UI Module - By default, delete artifacts in the Local Maven repositories (change in the settings form) - Changing the packaging item from the popup to the text (+ with this related edits), choosing the types of packages is not limited to listing them --- .../META-INF/MANIFEST.MF | 2 +- .../api/SettingsUrl.java | 9 + modules/crce-webui-v2/pom.xml | 2 +- .../crce_webui_v2/other/TypePackaging.java | 5 - .../crce_webui_v2/outer/CentralMavenForm.java | 183 +- .../crce_webui_v2/outer/DefinedMavenForm.java | 169 +- .../crce_webui_v2/outer/LocalMavenForm.java | 29 +- .../crce_webui_v2/webui/SettingsForm.java | 7 +- .../webapp/VAADIN/themes/mytheme/styles.css | 12990 ++++++++++++++++ 9 files changed, 13200 insertions(+), 196 deletions(-) delete mode 100644 modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/TypePackaging.java create mode 100644 modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/styles.css diff --git a/modules/crce-external-repository/META-INF/MANIFEST.MF b/modules/crce-external-repository/META-INF/MANIFEST.MF index c1a82452..9ec75bac 100644 --- a/modules/crce-external-repository/META-INF/MANIFEST.MF +++ b/modules/crce-external-repository/META-INF/MANIFEST.MF @@ -1,5 +1,5 @@ Manifest-Version: 1.0 -Bnd-LastModified: 1533635192624 +Bnd-LastModified: 1534242675630 Build-Jdk: 1.8.0_181 Built-By: rpesek Bundle-Activator: cz.zcu.kiv.crce.crce_external_repository.internal.Acti diff --git a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/SettingsUrl.java b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/SettingsUrl.java index 177aa6e9..05f7aea9 100644 --- a/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/SettingsUrl.java +++ b/modules/crce-external-repository/src/main/java/cz/zcu/kiv/crce/crce_external_repository/api/SettingsUrl.java @@ -4,6 +4,7 @@ public class SettingsUrl{ private String centralMavenUrl = "http://repo.maven.apache.org/maven2/"; private String localAetherUrl = "aether-local-repo"; private String externalAetherUrl = "http://repo.maven.apache.org/maven2/"; + private boolean enableDeleteLocalMaven = false; private boolean enableGroupSearch = false; public String getCentralMavenUrl() { @@ -29,6 +30,14 @@ public void setLocalAetherUrl(String url) { public void setExternalAetherUrl(String url) { this.externalAetherUrl = url; } + + public boolean isEnableDeleteLocalMaven() { + return enableDeleteLocalMaven; + } + + public void setEnableDeleteLocalMaven(boolean enableDeleteLocalMaven) { + this.enableDeleteLocalMaven = enableDeleteLocalMaven; + } public boolean isEnableGroupSearch() { return enableGroupSearch; diff --git a/modules/crce-webui-v2/pom.xml b/modules/crce-webui-v2/pom.xml index 8b8e7c7d..4b9fe496 100644 --- a/modules/crce-webui-v2/pom.xml +++ b/modules/crce-webui-v2/pom.xml @@ -12,7 +12,7 @@ crce-webui-v2 war - 1.2 + 1.3 CRCE - Web UI diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/TypePackaging.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/TypePackaging.java deleted file mode 100644 index f5cdadf4..00000000 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/other/TypePackaging.java +++ /dev/null @@ -1,5 +0,0 @@ -package cz.zcu.kiv.crce.crce_webui_v2.other; - -public enum TypePackaging { - jar,war,ejb,ear,pom,maven_plugin -} diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java index 93ac372f..b77daeec 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java @@ -4,7 +4,6 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; -import java.util.EnumSet; import com.vaadin.server.FontAwesome; import com.vaadin.server.Page; @@ -29,7 +28,6 @@ import cz.zcu.kiv.crce.crce_external_repository.api.ResultSearchArtifactTree; import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; -import cz.zcu.kiv.crce.crce_webui_v2.other.TypePackaging; import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; import cz.zcu.kiv.crce.repository.RefusedArtifactException; @@ -39,7 +37,7 @@ public class CentralMavenForm extends FormLayout { private TextField group = new TextField("Group Id"); private TextField artifact = new TextField("Artifact Id"); private TextField version = new TextField("Version"); - private NativeSelect packaging = new NativeSelect("Packaging"); + private TextField packaging = new TextField("Packaging"); private OptionGroup directIndexOption = new OptionGroup("Direct or search index"); private NativeSelect rangeOption = new NativeSelect("Range"); private Button searchButton = new Button("Search"); @@ -59,9 +57,6 @@ public CentralMavenForm(MyUI myUI) { HorizontalLayout content = new HorizontalLayout(); HorizontalLayout versionLayout = new HorizontalLayout(); VerticalLayout formPanelButtonLayout = new VerticalLayout(); - packaging.addItems(EnumSet.allOf(TypePackaging.class)); - packaging.select(TypePackaging.jar); - packaging.setNullSelectionAllowed(false); caption.addStyleName(ValoTheme.LABEL_BOLD); @@ -77,6 +72,15 @@ public CentralMavenForm(MyUI myUI) { "The central maven repository index is not created. Check its creation in the settings menu"); } + group.setRequired(true); + group.setRequiredError("The item can not be empty!"); + artifact.setRequired(true); + artifact.setRequiredError("The item can not be empty!"); + version.setRequired(true); + version.setRequiredError("The item can not be empty!"); + packaging.setRequired(true); + packaging.setRequiredError("The item can not be empty!"); + rangeOption.addItem("<="); rangeOption.addItem("="); rangeOption.addItem(">="); @@ -108,101 +112,89 @@ public CentralMavenForm(MyUI myUI) { if (content.getComponentIndex(formPanelButtonLayout) != -1) { content.removeComponent(formPanelButtonLayout); } - // check exist component from central Maven repository - if (directIndexOption.getValue().equals("Direct")) { - ResultSearchArtifactTree artifactList = new CentralMaven( - (SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).getArtifactTree(group.getValue(), - artifact.getValue(), version.getValue(), packaging.getValue(), - directIndexOption.getValue(), null); - if (artifactList.getArtifactTreeList() != null && artifactList.getStatus().equals("direct")) { - ArtifactTree artifactTree = artifactList.getArtifactTreeList().get(0); - String[] pom = artifactTree.getGroupId().split("\\."); - tree.addItem(pom[0]); - for (int i = 1; i < pom.length; i++) { - tree.addItem(pom[i]); - tree.setParent(pom[i], pom[i - 1]); - } - // addArtifactToTree(artifactTree, pom[pom.length - 1]); - addArtifactToTree(artifactTree.getUrl(), artifactTree.getGroupId(), artifactTree.getArtefactId(), - artifactTree.getVersions().get(0), artifactTree.getPackaging(), pom[pom.length - 1]); - - // for margin - HorizontalLayout treePanelLayout = new HorizontalLayout(); - treePanelLayout.addComponent(tree); - treePanelLayout.setMargin(true); - treePanel.setContent(treePanelLayout); - formPanelButtonLayout.addComponents(treePanel, uploadButton); - formPanelButtonLayout.setMargin(true); - formPanelButtonLayout.setSpacing(true); - formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); - uploadButton.setVisible(false); - } else if (artifactList.getArtifactTreeList() != null && artifactList.getStatus().equals("group")) { - for (ArtifactTree artifactTree : artifactList.getArtifactTreeList()) { - String[] pom = artifactTree.getGroupId().split("/"); - String uniqueItemChildren, uniqueItemParent = "/"; - - /* - * for central maven2 url - the correct is the listing over all items, but in - * this case the first is empty and the second is maven2 - */ - for (int i = 2; i < pom.length; i++) { - uniqueItemChildren = uniqueItemParent + pom[i] + "/"; - if (tree.getItem(uniqueItemChildren) == null) { - tree.addItem(uniqueItemChildren); - tree.setItemCaption(uniqueItemChildren, pom[i]); - tree.setParent(uniqueItemChildren, uniqueItemParent); + if (group.getValue().trim().isEmpty() || artifact.getValue().trim().isEmpty() + || version.getValue().trim().isEmpty() || packaging.getValue().trim().isEmpty()) { + Notification notif = new Notification("Incomplete assignment!", Notification.Type.WARNING_MESSAGE); + notif.setDelayMsec(5000); + notif.show(Page.getCurrent()); + } else { + // check exist component from central Maven repository + if (directIndexOption.getValue().equals("Direct")) { + ResultSearchArtifactTree artifactList = new CentralMaven( + (SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).getArtifactTree( + group.getValue(), artifact.getValue(), version.getValue(), packaging.getValue(), + directIndexOption.getValue(), null); + if (artifactList.getArtifactTreeList() != null && artifactList.getStatus().equals("direct")) { + ArtifactTree artifactTree = artifactList.getArtifactTreeList().get(0); + String[] pom = artifactTree.getGroupId().split("\\."); + tree.addItem(pom[0]); + for (int i = 1; i < pom.length; i++) { + tree.addItem(pom[i]); + tree.setParent(pom[i], pom[i - 1]); + } + // addArtifactToTree(artifactTree, pom[pom.length - 1]); + addArtifactToTree(artifactTree.getUrl(), artifactTree.getGroupId(), + artifactTree.getArtefactId(), artifactTree.getVersions().get(0), + artifactTree.getPackaging(), pom[pom.length - 1]); + + // for margin + HorizontalLayout treePanelLayout = new HorizontalLayout(); + treePanelLayout.addComponent(tree); + treePanelLayout.setMargin(true); + treePanel.setContent(treePanelLayout); + formPanelButtonLayout.addComponents(treePanel, uploadButton); + formPanelButtonLayout.setMargin(true); + formPanelButtonLayout.setSpacing(true); + formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); + uploadButton.setVisible(false); + } else if (artifactList.getArtifactTreeList() != null && artifactList.getStatus().equals("group")) { + for (ArtifactTree artifactTree : artifactList.getArtifactTreeList()) { + String[] pom = artifactTree.getGroupId().split("/"); + String uniqueItemChildren, uniqueItemParent = "/"; + + /* + * for central maven2 url - the correct is the listing over all items, but in + * this case the first is empty and the second is maven2 + */ + for (int i = 2; i < pom.length; i++) { + uniqueItemChildren = uniqueItemParent + pom[i] + "/"; + if (tree.getItem(uniqueItemChildren) == null) { + tree.addItem(uniqueItemChildren); + tree.setItemCaption(uniqueItemChildren, pom[i]); + tree.setParent(uniqueItemChildren, uniqueItemParent); + } + uniqueItemParent = uniqueItemChildren; } - uniqueItemParent = uniqueItemChildren; + addArtefactToTreeGroup(artifactTree, uniqueItemParent); } - addArtefactToTreeGroup(artifactTree, uniqueItemParent); - /* - * for (int i = 1; i < pom.length; i++) { uniqueItem = uniqueItem + pom[i]; - * - * if (tree.getItem(pom[i]) == null) { tree.addItem(pom[i]); - * tree.setParent(pom[i], pom[i - 1]); } else { tree.setParent(pom[i], pom[i - - * 1]); } } addArtefactToTreeGroup(artifactTree, pom[pom.length - 1]); - */ + // for margin + HorizontalLayout treePanelLayout = new HorizontalLayout(); + treePanelLayout.addComponent(tree); + treePanelLayout.setMargin(true); + treePanel.setContent(treePanelLayout); + formPanelButtonLayout.addComponents(treePanel, uploadButton); + formPanelButtonLayout.setMargin(true); + formPanelButtonLayout.setSpacing(true); + formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); + uploadButton.setVisible(false); + } else { + // for margin + HorizontalLayout treePanelLayout = new HorizontalLayout(); + treePanelLayout.addComponent(notFound); + treePanelLayout.setMargin(true); + treePanel.setContent(treePanelLayout); + formPanelButtonLayout.addComponents(treePanel); + formPanelButtonLayout.setMargin(true); } - // for margin - HorizontalLayout treePanelLayout = new HorizontalLayout(); - treePanelLayout.addComponent(tree); - treePanelLayout.setMargin(true); - treePanel.setContent(treePanelLayout); - formPanelButtonLayout.addComponents(treePanel, uploadButton); - formPanelButtonLayout.setMargin(true); - formPanelButtonLayout.setSpacing(true); - formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); - uploadButton.setVisible(false); - } else { - // for margin - HorizontalLayout treePanelLayout = new HorizontalLayout(); - treePanelLayout.addComponent(notFound); - treePanelLayout.setMargin(true); - treePanel.setContent(treePanelLayout); - formPanelButtonLayout.addComponents(treePanel); - formPanelButtonLayout.setMargin(true); } - } - // index search - else { - if (group.getValue().trim().isEmpty() || artifact.getValue().trim().isEmpty()) { - Notification notif = new Notification("Incomplete assignment!", Notification.Type.WARNING_MESSAGE); - notif.setDelayMsec(5000); - notif.show(Page.getCurrent()); - } else if (group.getValue().charAt(0) == '*' || group.getValue().charAt(0) == '?' + // index search + else if (group.getValue().charAt(0) == '*' || group.getValue().charAt(0) == '?' || artifact.getValue().charAt(0) == '*' || artifact.getValue().charAt(0) == '?') { Notification notif = new Notification("Can not start a search term with '*' or '?'", Notification.Type.WARNING_MESSAGE); notif.setDelayMsec(5000); notif.show(Page.getCurrent()); } else { - /* - * if(myUI.getSession().getAttribute("mavenIndex") == null) { Notification notif - * = new Notification( - * "The central maven repository index is not created. Check its creation in the settings menu" - * , Notification.Type.WARNING_MESSAGE); notif.setDelayMsec(5000); - * notif.show(Page.getCurrent()); } else { - */ ResultSearchArtifactTree artifactList = new CentralMaven( (SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).getArtifactTree( group.getValue(), artifact.getValue(), version.getValue(), packaging.getValue(), @@ -239,7 +231,6 @@ public CentralMavenForm(MyUI myUI) { formPanelButtonLayout.addComponents(treePanel); formPanelButtonLayout.setMargin(true); } - /* } */ } } content.addComponent(formPanelButtonLayout); @@ -277,14 +268,8 @@ public CentralMavenForm(MyUI myUI) { directIndexOption.addValueChangeListener(e -> { if (directIndexOption.getValue().equals("Direct")) { rangeOption.setEnabled(false); - group.setRequired(false); - artifact.setRequired(false); } else { rangeOption.setEnabled(true); - group.setRequired(true); - group.setRequiredError("The item can not be empty!"); - artifact.setRequired(true); - artifact.setRequiredError("The item can not be empty!"); } }); @@ -295,7 +280,7 @@ public CentralMavenForm(MyUI myUI) { group.clear(); artifact.clear(); version.clear(); - packaging.select(TypePackaging.jar); + packaging.clear(); tree.removeAllItems(); content.addComponent(userForm); }); diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/DefinedMavenForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/DefinedMavenForm.java index 9cf0debc..a1e58bdd 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/DefinedMavenForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/DefinedMavenForm.java @@ -5,7 +5,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.StandardOpenOption; -import java.util.EnumSet; +//import java.util.EnumSet; import com.vaadin.server.FontAwesome; import com.vaadin.server.Page; @@ -17,7 +17,7 @@ import com.vaadin.ui.FormLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; -import com.vaadin.ui.NativeSelect; +//import com.vaadin.ui.NativeSelect; import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; import com.vaadin.ui.TextField; @@ -29,11 +29,11 @@ import cz.zcu.kiv.crce.crce_external_repository.api.DefinedMaven; import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; -import cz.zcu.kiv.crce.crce_webui_v2.other.TypePackaging; +//import cz.zcu.kiv.crce.crce_webui_v2.other.TypePackaging; import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; import cz.zcu.kiv.crce.repository.RefusedArtifactException; -public class DefinedMavenForm extends FormLayout{ +public class DefinedMavenForm extends FormLayout { private static final long serialVersionUID = 4172878715304331198L; private transient DefinedMaven definedMaven; private TextField definedUrl = new TextField(); @@ -41,7 +41,8 @@ public class DefinedMavenForm extends FormLayout{ private TextField group = new TextField("Group Id"); private TextField artifact = new TextField("Artifact Id"); private TextField version = new TextField("Version"); - private NativeSelect packaging = new NativeSelect("Packaging"); + // private NativeSelect packaging = new NativeSelect("Packaging"); + private TextField packaging = new TextField("Packaging"); private Button searchButton = new Button("Search"); private Button clearButton = new Button("Clear"); private Button uploadButton = new Button("Upload"); @@ -70,14 +71,21 @@ public DefinedMavenForm(MyUI myUI) { HorizontalLayout treeLayout = new HorizontalLayout(); VerticalLayout formLayout = new VerticalLayout(); HorizontalLayout content = new HorizontalLayout(); - + caption.addStyleName(ValoTheme.LABEL_BOLD); definedUrl.setWidth("450px"); - packaging.addItems(EnumSet.allOf(TypePackaging.class)); - packaging.select(TypePackaging.jar); - packaging.setNullSelectionAllowed(false); + // packaging.addItems(EnumSet.allOf(TypePackaging.class)); + // packaging.select(TypePackaging.jar); + // packaging.setNullSelectionAllowed(false); + + group.setRequired(true); + group.setRequiredError("The item can not be empty!"); + artifact.setRequired(true); + artifact.setRequiredError("The item can not be empty!"); + packaging.setRequired(true); + packaging.setRequiredError("The item can not be empty!"); searchButton.setStyleName(ValoTheme.BUTTON_PRIMARY); @@ -92,17 +100,17 @@ public DefinedMavenForm(MyUI myUI) { fieldLayout.addComponents(group, artifact, version, packaging, buttonsSearchClearLayout); fieldLayout.setSpacing(true); fieldLayout.setMargin(new MarginInfo(false, true, false, false)); - + treeLayout.setMargin(true); treePanel.setContent(treeLayout); treePanel.setWidth("600px"); treePanel.setHeight("283px"); treePanel.setVisible(false); buttonUploadResolveLayout.setVisible(false); - + buttonUploadResolveLayout.addComponents(resolveButton, uploadButton); buttonUploadResolveLayout.setSpacing(true); - + treePanelButtonLayout.addComponents(treePanel, buttonUploadResolveLayout); treePanelButtonLayout.setSpacing(true); treePanelButtonLayout.setComponentAlignment(buttonUploadResolveLayout, Alignment.BOTTOM_CENTER); @@ -135,7 +143,8 @@ public DefinedMavenForm(MyUI myUI) { group.clear(); artifact.clear(); version.clear(); - packaging.select(TypePackaging.jar); + packaging.clear(); + // packaging.select(TypePackaging.jar); // erasing any previous components shown if (treeLayout.getComponentIndex(notFound) != -1) { treeLayout.removeComponent(notFound); @@ -149,59 +158,66 @@ public DefinedMavenForm(MyUI myUI) { // search artefact from defined repository searchButton.addClickListener(e1 -> { - SettingsUrl settings; - if (myUI.getSession().getAttribute("settingsUrl") == null) { - settings = new SettingsUrl(); + if (group.getValue().trim().isEmpty() || artifact.getValue().trim().isEmpty() + || packaging.getValue().trim().isEmpty()) { + Notification notif = new Notification("Incomplete assignment!", Notification.Type.WARNING_MESSAGE); + notif.setDelayMsec(5000); + notif.show(Page.getCurrent()); } else { - settings = (SettingsUrl) myUI.getSession().getAttribute("settingsUrl"); - } - // erasing any previous components shown - if (treeLayout.getComponentIndex(notFound) != -1) { - treeLayout.removeComponent(notFound); - } - if (treeLayout.getComponentIndex(tree) != -1) { - treeLayout.removeComponent(tree); - } - - // předání hodnot - definedMaven = new DefinedMaven(settings); - ArtifactTree definedArtefact = definedMaven.getArtifact(group.getValue(), artifact.getValue(), version.getValue(), - packaging.getValue()); - if(definedArtefact == null){ - treeLayout.addComponent(notFound); - } - else { - tree = new Tree(); - String[] pom = definedArtefact.getGroupId().split("\\."); - tree.addItem(pom[0]); - for (int i = 1; i < pom.length; i++) { - tree.addItem(pom[i]); - tree.setParent(pom[i], pom[i - 1]); + SettingsUrl settings; + if (myUI.getSession().getAttribute("settingsUrl") == null) { + settings = new SettingsUrl(); + } else { + settings = (SettingsUrl) myUI.getSession().getAttribute("settingsUrl"); + } + // erasing any previous components shown + if (treeLayout.getComponentIndex(notFound) != -1) { + treeLayout.removeComponent(notFound); + } + if (treeLayout.getComponentIndex(tree) != -1) { + treeLayout.removeComponent(tree); } - if (definedArtefact.getVersions().size() > 1) { - for (String s : definedArtefact.getVersions()) { - addArtefactToTree(definedArtefact.getGroupId(), definedArtefact.getArtefactId(), s, - definedArtefact.getPackaging(),pom[pom.length - 1]); - } + // předání hodnot + definedMaven = new DefinedMaven(settings); + ArtifactTree definedArtefact = definedMaven.getArtifact(group.getValue(), artifact.getValue(), + version.getValue(), packaging.getValue()); + if (definedArtefact == null) { + treeLayout.addComponent(notFound); } else { - addArtefactToTree(definedArtefact.getGroupId(), definedArtefact.getArtefactId(), definedArtefact.getVersions().get(0), - definedArtefact.getPackaging(),pom[pom.length - 1]); + tree = new Tree(); + String[] pom = definedArtefact.getGroupId().split("\\."); + tree.addItem(pom[0]); + for (int i = 1; i < pom.length; i++) { + tree.addItem(pom[i]); + tree.setParent(pom[i], pom[i - 1]); + } + + if (definedArtefact.getVersions().size() > 1) { + for (String s : definedArtefact.getVersions()) { + addArtefactToTree(definedArtefact.getGroupId(), definedArtefact.getArtefactId(), s, + definedArtefact.getPackaging(), pom[pom.length - 1]); + } + } else { + addArtefactToTree(definedArtefact.getGroupId(), definedArtefact.getArtefactId(), + definedArtefact.getVersions().get(0), definedArtefact.getPackaging(), + pom[pom.length - 1]); + } + + tree.addExpandListener(e2 -> { + buttonUploadResolveLayout.setVisible(true); + }); + + tree.addCollapseListener(e3 -> { + buttonUploadResolveLayout.setVisible(false); + }); + + treeLayout.addComponent(tree); } - - tree.addExpandListener(e2 ->{ - buttonUploadResolveLayout.setVisible(true); - }); - - tree.addCollapseListener(e3 -> { - buttonUploadResolveLayout.setVisible(false); - }); - - treeLayout.addComponent(tree); + treePanel.setVisible(true); } - treePanel.setVisible(true); }); - + uploadButton.addClickListener(e -> { SettingsUrl settings; if (myUI.getSession().getAttribute("settingsUrl") == null) { @@ -210,7 +226,7 @@ public DefinedMavenForm(MyUI myUI) { settings = (SettingsUrl) myUI.getSession().getAttribute("settingsUrl"); } // First check the artifact storage in the local repository - if(tree.getValue() != null && tree.getValue().toString().contains(":")) { + if (tree.getValue() != null && tree.getValue().toString().contains(":")) { String artifactText = tree.getValue().toString(); if (DefinedMaven.resolveArtifact(artifactText, settings)) { File file = new File(settings.getLocalAetherUrl() + "/" @@ -236,14 +252,12 @@ public DefinedMavenForm(MyUI myUI) { new Notification("Problem with resolving artifact", Notification.Type.WARNING_MESSAGE) .show(Page.getCurrent()); } - } - else { - new Notification("No artefact selected", Notification.Type.WARNING_MESSAGE) - .show(Page.getCurrent()); + } else { + new Notification("No artefact selected", Notification.Type.WARNING_MESSAGE).show(Page.getCurrent()); } }); - - resolveButton.addClickListener(e ->{ + + resolveButton.addClickListener(e -> { SettingsUrl settings; if (myUI.getSession().getAttribute("settingsUrl") == null) { settings = new SettingsUrl(); @@ -251,7 +265,7 @@ public DefinedMavenForm(MyUI myUI) { settings = (SettingsUrl) myUI.getSession().getAttribute("settingsUrl"); } // First check the artifact storage in the local repository - if(tree.getValue() != null && tree.getValue().toString().contains(":")) { + if (tree.getValue() != null && tree.getValue().toString().contains(":")) { String artifactText = tree.getValue().toString(); if (DefinedMaven.resolveArtifact(artifactText, settings)) { Notification notif = new Notification("Info", "Artefact sucess resolved to Maven local repository.", @@ -262,17 +276,15 @@ public DefinedMavenForm(MyUI myUI) { new Notification("Problem with resolving artifact", Notification.Type.WARNING_MESSAGE) .show(Page.getCurrent()); } - } - else { - new Notification("No artefact selected", Notification.Type.WARNING_MESSAGE) - .show(Page.getCurrent()); + } else { + new Notification("No artefact selected", Notification.Type.WARNING_MESSAGE).show(Page.getCurrent()); } }); - + content.setSpacing(true); addComponent(content); } - + private void addArtefactToTree(String group, String artifact, String version, String packaging, String parent) { tree.addItem(artifact); tree.setParent(artifact, parent); @@ -281,15 +293,16 @@ private void addArtefactToTree(String group, String artifact, String version, St // konečný artefact je komplet url link např. pro wget - UPRAVIT DLE // POTŘEBY - /*String artifactText = settings.getExternalAetherUrl() + "/" + - groupText + "/" + idText + "/" + version + "." + packagingText;*/ - + /* + * String artifactText = settings.getExternalAetherUrl() + "/" + groupText + "/" + * + idText + "/" + version + "." + packagingText; + */ + String artifactText = group + ":" + artifact + ":" + version + ":" + packaging; tree.addItem(artifactText); tree.setParent(artifactText, version.toString()); - tree.setItemCaption(artifactText, - artifact + "-" + version + "." + packaging); + tree.setItemCaption(artifactText, artifact + "-" + version + "." + packaging); tree.setChildrenAllowed(artifactText, false); if (packaging.equals("jar") || packaging.equals("war")) { tree.setItemIcon(artifactText, FontAwesome.GIFT); diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LocalMavenForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LocalMavenForm.java index 24cd7f2f..88689adc 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LocalMavenForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LocalMavenForm.java @@ -24,6 +24,7 @@ import com.vaadin.ui.themes.ValoTheme; import com.vaadin.ui.VerticalLayout; +import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; import cz.zcu.kiv.crce.crce_webui_v2.outer.classes.LocalMaven; import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; @@ -36,7 +37,7 @@ public class LocalMavenForm extends FormLayout { private Panel formPanel = new Panel("Content"); private Button uploadButton = new Button("Upload"); private Button removeButton = new Button("Remove"); - + public LocalMavenForm() { HorizontalLayout content = new HorizontalLayout(); addComponent(content); @@ -45,16 +46,22 @@ public LocalMavenForm() { public LocalMavenForm(MyUI myUI) { VerticalLayout content = new VerticalLayout(); caption.addStyleName(ValoTheme.LABEL_BOLD); - + VerticalLayout formLayout = new VerticalLayout(); HorizontalLayout buttons = new HorizontalLayout(); - + removeButton.setStyleName(ValoTheme.BUTTON_DANGER); - - buttons.addComponents(uploadButton, removeButton); + + if (myUI.getSession().getAttribute("settingsUrl") == null + || !((SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).isEnableDeleteLocalMaven()) { + buttons.addComponent(uploadButton); + } else { + buttons.addComponents(uploadButton, removeButton); + } + buttons.setSpacing(true); buttons.setVisible(false); - + // Tree of Maven local repository Tree localMavenTree = localMaven.getTree(myUI.getSession()); content.setMargin(new MarginInfo(false, true)); @@ -71,11 +78,11 @@ public LocalMavenForm(MyUI myUI) { formLayout.setComponentAlignment(buttons, Alignment.BOTTOM_CENTER); content.addComponents(formLayout); content.setSpacing(true); - + localMavenTree.addItemClickListener(e -> { buttons.setVisible(true); }); - + removeButton.addClickListener(e -> { if (localMavenTree.getValue() != null) { File file = new File(localMavenTree.getValue().toString()); @@ -102,7 +109,7 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx } } }); - + uploadButton.addClickListener(e -> { if (localMavenTree.getValue() != null) { if (!localMavenTree.areChildrenAllowed((Object) localMavenTree.getValue())) { @@ -122,10 +129,10 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx new Notification("Could not open file", ex.getMessage(), Notification.Type.ERROR_MESSAGE) .show(Page.getCurrent()); } - + } else { new Notification("No artifact is selected for upload!", Notification.Type.WARNING_MESSAGE) - .show(Page.getCurrent()); + .show(Page.getCurrent()); } } }); diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java index 949a3107..5db64ec6 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java @@ -29,6 +29,7 @@ public SettingsForm() { public SettingsForm(VaadinSession session) { TextField centralMavenUrl = new TextField("Central Maven url"); TextField localAetherRepo = new TextField("Local Aether repository"); + CheckBox enableDeleteLocalMaven = new CheckBox("Enable delete local Maven repo"); CheckBox enableGroupSearch = new CheckBox("Enable only group search"); centralMavenUrl.setWidth("400px"); @@ -40,10 +41,12 @@ public SettingsForm(VaadinSession session) { SettingsUrl settingsUrl = new SettingsUrl(); centralMavenUrl.setValue(settingsUrl.getCentralMavenUrl()); localAetherRepo.setValue(settingsUrl.getLocalAetherUrl()); + enableDeleteLocalMaven.setValue(false); enableGroupSearch.setValue(false); } else { centralMavenUrl.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getCentralMavenUrl()); localAetherRepo.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).getLocalAetherUrl()); + enableDeleteLocalMaven.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).isEnableDeleteLocalMaven()); enableGroupSearch.setValue(((SettingsUrl) session.getAttribute("settingsUrl")).isEnableGroupSearch()); } @@ -57,7 +60,7 @@ public SettingsForm(VaadinSession session) { saveButton.setClickShortcut(KeyCode.ENTER); VerticalLayout content = new VerticalLayout(); - content.addComponents(centralMavenUrl, localAetherRepo, enableGroupSearch, buttonsLayout); + content.addComponents(centralMavenUrl, localAetherRepo, enableDeleteLocalMaven, enableGroupSearch, buttonsLayout); content.setSpacing(true); HorizontalLayout formLayout = new HorizontalLayout(); @@ -74,6 +77,7 @@ public SettingsForm(VaadinSession session) { } settingsUrl.setCentralMavenUrl(centralMavenUrl.getValue()); settingsUrl.setLocalAetherUrl(localAetherRepo.getValue()); + settingsUrl.setEnableDeleteLocalMaven(enableDeleteLocalMaven.getValue()); settingsUrl.setEnableGroupSearch(enableGroupSearch.getValue()); getSession().setAttribute("settingsUrl", settingsUrl); Notification notif = new Notification("Info", "Settings saved successfully" , @@ -87,6 +91,7 @@ public SettingsForm(VaadinSession session) { getSession().setAttribute("settingsUrl", settingsUrl); centralMavenUrl.setValue(settingsUrl.getCentralMavenUrl()); localAetherRepo.setValue(settingsUrl.getLocalAetherUrl()); + enableDeleteLocalMaven.setValue(settingsUrl.isEnableDeleteLocalMaven()); enableGroupSearch.setValue(settingsUrl.isEnableGroupSearch()); }); diff --git a/modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/styles.css b/modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/styles.css new file mode 100644 index 00000000..07d8f544 --- /dev/null +++ b/modules/crce-webui-v2/src/main/webapp/VAADIN/themes/mytheme/styles.css @@ -0,0 +1,12990 @@ +/** + * Checks if a list contains a certain value. + * + * @param {list} $list - the list to check + * @param {value} $var - the value to search for + * @param {bool} $recursive (false) - should any contained lists be checked for the value + * + * @return {bool} true if the value is found from the list, false otherwise + * + * @group lists + */ + +/** + * Cross-browser opacity. + * + * @param {number} $value - opacity value from 0 to 1 + * @param {bool} $important (false) - should the property value be declared with !important + * + * @group util + */ + +@-webkit-keyframes valo-animate-in-fade { + 0% { + opacity: 0; + } + } + +@-moz-keyframes valo-animate-in-fade { + 0% { + opacity: 0; + } + } + +@keyframes valo-animate-in-fade { + 0% { + opacity: 0; + } + } + +@-webkit-keyframes valo-animate-out-fade { + 100% { + opacity: 0; + } + } + +@-moz-keyframes valo-animate-out-fade { + 100% { + opacity: 0; + } + } + +@keyframes valo-animate-out-fade { + 100% { + opacity: 0; + } + } + +@-webkit-keyframes valo-animate-in-slide-down { + 0% { + -webkit-transform: translateY(-100%); + } + } + +@-moz-keyframes valo-animate-in-slide-down { + 0% { + -moz-transform: translateY(-100%); + } + } + +@keyframes valo-animate-in-slide-down { + 0% { + -webkit-transform: translateY(-100%); + -moz-transform: translateY(-100%); + -ms-transform: translateY(-100%); + -o-transform: translateY(-100%); + transform: translateY(-100%); + } + } + +@-webkit-keyframes valo-animate-in-slide-up { + 0% { + -webkit-transform: translateY(100%); + } + } + +@-moz-keyframes valo-animate-in-slide-up { + 0% { + -moz-transform: translateY(100%); + } + } + +@keyframes valo-animate-in-slide-up { + 0% { + -webkit-transform: translateY(100%); + -moz-transform: translateY(100%); + -ms-transform: translateY(100%); + -o-transform: translateY(100%); + transform: translateY(100%); + } + } + +@-webkit-keyframes valo-animate-in-slide-left { + 0% { + -webkit-transform: translateX(100%); + } + } + +@-moz-keyframes valo-animate-in-slide-left { + 0% { + -moz-transform: translateX(100%); + } + } + +@keyframes valo-animate-in-slide-left { + 0% { + -webkit-transform: translateX(100%); + -moz-transform: translateX(100%); + -ms-transform: translateX(100%); + -o-transform: translateX(100%); + transform: translateX(100%); + } + } + +@-webkit-keyframes valo-animate-in-slide-right { + 0% { + -webkit-transform: translateX(-100%); + } + } + +@-moz-keyframes valo-animate-in-slide-right { + 0% { + -moz-transform: translateX(-100%); + } + } + +@keyframes valo-animate-in-slide-right { + 0% { + -webkit-transform: translateX(-100%); + -moz-transform: translateX(-100%); + -ms-transform: translateX(-100%); + -o-transform: translateX(-100%); + transform: translateX(-100%); + } + } + +@-webkit-keyframes valo-animate-out-slide-down { + 100% { + -webkit-transform: translateY(100%); + } + } + +@-moz-keyframes valo-animate-out-slide-down { + 100% { + -moz-transform: translateY(100%); + } + } + +@keyframes valo-animate-out-slide-down { + 100% { + -webkit-transform: translateY(100%); + -moz-transform: translateY(100%); + -ms-transform: translateY(100%); + -o-transform: translateY(100%); + transform: translateY(100%); + } + } + +@-webkit-keyframes valo-animate-out-slide-up { + 100% { + -webkit-transform: translateY(-100%); + } + } + +@-moz-keyframes valo-animate-out-slide-up { + 100% { + -moz-transform: translateY(-100%); + } + } + +@keyframes valo-animate-out-slide-up { + 100% { + -webkit-transform: translateY(-100%); + -moz-transform: translateY(-100%); + -ms-transform: translateY(-100%); + -o-transform: translateY(-100%); + transform: translateY(-100%); + } + } + +@-webkit-keyframes valo-animate-out-slide-left { + 100% { + -webkit-transform: translateX(-100%); + } + } + +@-moz-keyframes valo-animate-out-slide-left { + 100% { + -moz-transform: translateX(-100%); + } + } + +@keyframes valo-animate-out-slide-left { + 100% { + -webkit-transform: translateX(-100%); + -moz-transform: translateX(-100%); + -ms-transform: translateX(-100%); + -o-transform: translateX(-100%); + transform: translateX(-100%); + } + } + +@-webkit-keyframes valo-animate-out-slide-right { + 100% { + -webkit-transform: translateX(100%); + } + } + +@-moz-keyframes valo-animate-out-slide-right { + 100% { + -moz-transform: translateX(100%); + } + } + +@keyframes valo-animate-out-slide-right { + 100% { + -webkit-transform: translateX(100%); + -moz-transform: translateX(100%); + -ms-transform: translateX(100%); + -o-transform: translateX(100%); + transform: translateX(100%); + } + } + +@-webkit-keyframes valo-overlay-animate-in { + 0% { + -webkit-transform: translatey(-4px); + opacity: 0; + } + } + +@-moz-keyframes valo-overlay-animate-in { + 0% { + -moz-transform: translatey(-4px); + opacity: 0; + } + } + +@keyframes valo-overlay-animate-in { + 0% { + -webkit-transform: translatey(-4px); + -moz-transform: translatey(-4px); + -ms-transform: translatey(-4px); + -o-transform: translatey(-4px); + transform: translatey(-4px); + opacity: 0; + } + } + +@-webkit-keyframes valo-animate-out-slide-down-fade { + 100% { + opacity: 0; + -webkit-transform: translatey(30%); + } + } + +@-moz-keyframes valo-animate-out-slide-down-fade { + 100% { + opacity: 0; + -moz-transform: translatey(30%); + } + } + +@keyframes valo-animate-out-slide-down-fade { + 100% { + opacity: 0; + -webkit-transform: translatey(30%); + -moz-transform: translatey(30%); + -ms-transform: translatey(30%); + -o-transform: translatey(30%); + transform: translatey(30%); + } + } + +/** + * Outputs cross-browser Valo-specific linear gradient background-image declarations. + * + * @group style + * + * @param {color} $color ($v-background-color) - The base color for the gradient color stops + * @param {list} $gradient ($v-gradient) - Valo-specific gradient value. See the documentation for $v-gradient. + * @param {color} $fallback (null) - A fallback color for browser which do not support linear gradients (IE8 and IE9 in particular). If null, the base $color is used instead. + * @param {string} $direction (to bottom) - the direction of the linear gradient. The color stops are by default so that a lighter shade is at the start and a darker shade is at the end. + */ + +/** + * Computes a CSS border property value for the given base color. + * + * @group style + * + * @param {list} $border ($v-border) - CSS border value which can contain any of the color keywords + * @param {color} $color ($v-background-color) - the base color to which the color keywords are applied to + * @param {color} $context (null) - context/surrounding color where the border is expected to appear. The color of the final border is the darker of the two parameters passed to this function. + * @param {number} $strength (1) - adjustment for the border contrast + * + * @return {list} The input $border value with any color keyword replaced with the corresponding actual color + */ + +/** + * Ouput selectors and properties to vertically center elements inside their parent. + * + * @param {string} $to-align (()) - The selector to match the elements which you wish to align vertically. The targeted elements should be inline or inline-block elements. + * @param {string} $align (middle) - The vertical-align value, e.g. top, middle, bottom + * @param {string} $pseudo-element (after) - Which pseudo element to use for the vertical align guide + * + * @group util + */ + +@font-face { + font-family: ThemeIcons; + font-weight: normal; + font-style: normal; + src: url(../valo/util/bourbon/css3/../../../../base/fonts/themeicons-webfont.eot); + src: url(../valo/util/bourbon/css3/../../../../base/fonts/themeicons-webfont.eot?#iefix) format("embedded-opentype"), url(../valo/util/bourbon/css3/../../../../base/fonts/themeicons-webfont.woff) format("woff"), url(../valo/util/bourbon/css3/../../../../base/fonts/themeicons-webfont.ttf) format("truetype"), url(../valo/util/bourbon/css3/../../../../base/fonts/themeicons-webfont.svg#ThemeIcons) format("svg"); +} + +.ThemeIcons { + font-family: ThemeIcons; + font-style: normal; + font-weight: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + display: inline-block; + text-align: center; +} + +@font-face { + font-family: FontAwesome; + font-weight: normal; + font-style: normal; + src: url(../valo/util/bourbon/css3/../../../../base/fonts/fontawesome-webfont.eot); + src: url(../valo/util/bourbon/css3/../../../../base/fonts/fontawesome-webfont.eot?#iefix) format("embedded-opentype"), url(../valo/util/bourbon/css3/../../../../base/fonts/fontawesome-webfont.woff) format("woff"), url(../valo/util/bourbon/css3/../../../../base/fonts/fontawesome-webfont.ttf) format("truetype"), url(../valo/util/bourbon/css3/../../../../base/fonts/fontawesome-webfont.svg#FontAwesome) format("svg"); +} + +.FontAwesome { + font-family: FontAwesome; + font-style: normal; + font-weight: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + display: inline-block; + text-align: center; +} + +@font-face { + font-family: "Open Sans"; + src: url(../valo/fonts/open-sans/OpenSans-Light-webfont.eot); + src: url(../valo/fonts/open-sans/OpenSans-Light-webfont.eot?#iefix) format("embedded-opentype"), url(../valo/fonts/open-sans/OpenSans-Light-webfont.woff) format("woff"), url(../valo/fonts/open-sans/OpenSans-Light-webfont.ttf) format("truetype"); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: "Open Sans"; + src: url(../valo/fonts/open-sans/OpenSans-Regular-webfont.eot); + src: url(../valo/fonts/open-sans/OpenSans-Regular-webfont.eot?#iefix) format("embedded-opentype"), url(../valo/fonts/open-sans/OpenSans-Regular-webfont.woff) format("woff"), url(../valo/fonts/open-sans/OpenSans-Regular-webfont.ttf) format("truetype"); + font-weight: 400; + font-style: normal; +} + +@font-face { + font-family: "Open Sans"; + src: url(../valo/fonts/open-sans/OpenSans-Semibold-webfont.eot); + src: url(../valo/fonts/open-sans/OpenSans-Semibold-webfont.eot?#iefix) format("embedded-opentype"), url(../valo/fonts/open-sans/OpenSans-Semibold-webfont.woff) format("woff"), url(../valo/fonts/open-sans/OpenSans-Semibold-webfont.ttf) format("truetype"); + font-weight: 600; + font-style: normal; +} + +@-webkit-keyframes v-rotate-360 { + to { + -webkit-transform: rotate(360deg); + } + } + +@-moz-keyframes v-rotate-360 { + to { + -moz-transform: rotate(360deg); + } + } + +@-o-keyframes v-rotate-360 { + to { + -o-transform: rotate(360deg); + } + } + +@keyframes v-rotate-360 { + to { + transform: rotate(360deg); + } + } + +@-webkit-keyframes v-progress-start { + 0% { + width: 0%; + } + 100% { + width: 50%; + } + } + +@-moz-keyframes v-progress-start { + 0% { + width: 0%; + } + 100% { + width: 50%; + } + } + +@keyframes v-progress-start { + 0% { + width: 0%; + } + 100% { + width: 50%; + } + } + +@-webkit-keyframes v-progress-delay { + 0% { + width: 50%; + } + 100% { + width: 90%; + } + } + +@-moz-keyframes v-progress-delay { + 0% { + width: 50%; + } + 100% { + width: 90%; + } + } + +@keyframes v-progress-delay { + 0% { + width: 50%; + } + 100% { + width: 90%; + } + } + +@-webkit-keyframes v-progress-wait { + 0% { + width: 90%; + height: 4px; + } + 3% { + width: 91%; + height: 7px; + } + 100% { + width: 96%; + height: 7px; + } + } + +@-moz-keyframes v-progress-wait { + 0% { + width: 90%; + height: 4px; + } + 3% { + width: 91%; + height: 7px; + } + 100% { + width: 96%; + height: 7px; + } + } + +@keyframes v-progress-wait { + 0% { + width: 90%; + height: 4px; + } + 3% { + width: 91%; + height: 7px; + } + 100% { + width: 96%; + height: 7px; + } + } + +@-webkit-keyframes v-progress-wait-pulse { + 0% { + opacity: 1; + } + 50% { + opacity: 0.1; + } + 100% { + opacity: 1; + } + } + +@-moz-keyframes v-progress-wait-pulse { + 0% { + opacity: 1; + } + 50% { + opacity: 0.1; + } + 100% { + opacity: 1; + } + } + +@keyframes v-progress-wait-pulse { + 0% { + opacity: 1; + } + 50% { + opacity: 0.1; + } + 100% { + opacity: 1; + } + } + +/** + * Outputs the context menu selectors and styles, which is used by Table and Tree for instance. + * + * @requires {mixin} valo-selection-item-style + * @requires {mixin} valo-selection-item-selected-style + */ + +/** + * The background color for overlay elements. + * + * @type color + * @group overlay + */ + +.v-shadow, .v-shadow-window { + display: none; +} + +.v-ie8 .v-shadow, .v-ie8 .v-shadow-window { + display: block; +} + +.v-ie8 .v-shadow .top, .v-ie8 .v-shadow-window .top { + position: absolute; + top: -6px; + right: 10px; + bottom: 6px; + left: -10px; + background: black; + filter: alpha(opacity=5) progid:DXImageTransform.Microsoft.blur(pixelradius=10, makeShadow=false); +} + +.v-ie8 .v-shadow .top-left, .v-ie8 .v-shadow-window .top-left { + position: absolute; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; + background: black; + filter: alpha(opacity=9) progid:DXImageTransform.Microsoft.blur(pixelradius=0, makeShadow=false); +} + +/** + * The backgound color for tooltips. + * + * @type color + * @group tooltip + */ + +/** + * + * + * @param {string} $primary-stylename (v-absolutelayout) - + * + * @group absolutelayout + */ + +/** + * Outputs the selectors and properties for the Accordion component. + * + * @param {string} $primary-stylename (v-accordion) - the primary style name for the selectors + * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component + * @group accordion + */ + +/** + * Outputs the selectors and properties for the Button component. + * + * @param {string} $primary-stylename (v-button) - the primary style name for the selectors + * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component + * + * @group button + */ + +/** + * A list of colors for custom event colors. Can be an empty list of you don't + * need any custom event colors. + * + * @example javascript + * // Java code + * // 'event' is an instance of EditableCalendarEvent + * event.setStyleName("color1"); // 1st color in the list + * event.setStyleName("color2"); // 2nd color in the list + * // etc. + * + * @group calendar + */ + +/** + * Outputs the selectors and properties for the CheckBox component. + * + * @param {string} $primary-stylename (v-checkbox) - the primary style name for the selectors + * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component + * + * @group checkbox + */ + +/** + * Outputs the global selectors and properties for the ColorPicker component - styles which are + * considered mandatory for the component to work properly. + * + * @param {string} $primary-stylename (v-colorpicker) - the primary style name for the selectors + * + * @group colorpicker + */ + +/** + * Outputs the selectors and properties for the ComboBox component. + * + * @param {string} $primary-stylename (v-filterselect) - the primary style name for the selectors + * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component + * + * @group combobox + */ + +/** + * The amount of spacing between different widgets in a component group. + * If null, a computed value is used ($v-border size * -1, or 1px if $v-border size is 0) + * + * @group csslayout + */ + +/** + * + * + * @param {string} $primary-stylename (v-customcomponent) - + * + * @group customcomponent + */ + +/** + * + * + * @param {string} $primary-stylename (v-customlayout) - + * + * @group customlayout + */ + +/** + * Outputs the selectors and properties for the DateField component. + * + * @param {string} $primary-stylename (v-datefield) - the primary style name for the selectors + * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component + * + * @group datefield + */ + +/** + * Outputs the styles and selectors for the DragAndDropWrapper component. + * + * @param {string} $primary-stylename (v-ddwrapper) - the primary style name for the selectors + * + * @group drag-n-drop + */ + +/** + * + * + * @param {string} $primary-stylename (v-form) - + * + * @group form + */ + +/** + * Outputs the selectors and properties for the FormLayout component. + * + * @param {string} $primary-stylename (v-formlayout) - the primary style name for the selectors + * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component + * + * @group formlayout + */ + +/** + * + * @group table + */ + +@-webkit-keyframes valo-grid-editor-footer-animate-in { + 0% { + margin-top: -37px; + } + } + +@-moz-keyframes valo-grid-editor-footer-animate-in { + 0% { + margin-top: -37px; + } + } + +@keyframes valo-grid-editor-footer-animate-in { + 0% { + margin-top: -37px; + } + } + +@-webkit-keyframes valo-grid-editor-footer-animate-in-alt { + 0% { + margin-bottom: -38px; + } + 100% { + margin-bottom: -1px; + } + } + +@-moz-keyframes valo-grid-editor-footer-animate-in-alt { + 0% { + margin-bottom: -38px; + } + 100% { + margin-bottom: -1px; + } + } + +@keyframes valo-grid-editor-footer-animate-in-alt { + 0% { + margin-bottom: -38px; + } + 100% { + margin-bottom: -1px; + } + } + +/** + * + * + * @param {string} $primary-stylename (v-gridlayout) - + * + * @group gridlayout + */ + +/** + * The font weight for headers. + * + * @group label + */ + +/** + * + * @group link + */ + +/** + * + * + * @param {string} $primary-stylename (v-loginform) - + * + * @group loginform + */ + +/** + * + * + * @param {string} $primary-stylename (v-menubar) - + * @param {bool} $include-additional-styles - + * + * @group menubar + */ + +/** + * + * + * @param {string} $primary-stylename (v-nativebutton) - + * + * @group nativebutton + */ + +/** + * + * + * @param {string} $primary-stylename (v-select) - + * + * @group nativeselect + */ + +/** + * + * @group notification + */ + +/** + * + * + * @param {string} $primary-stylename (v-select-optiongroup) - + * @param {bool} $include-additional-styles - + * + * @group optiongroup + */ + +/** + * + * + * + * @group orderedlayout + */ + +/** + * + * @group panel + */ + +@-webkit-keyframes v-popupview-animate-in { + 0% { + -webkit-transform: scale(0); + } + } + +@-moz-keyframes v-popupview-animate-in { + 0% { + -moz-transform: scale(0); + } + } + +@keyframes v-popupview-animate-in { + 0% { + -webkit-transform: scale(0); + -moz-transform: scale(0); + -ms-transform: scale(0); + -o-transform: scale(0); + transform: scale(0); + } + } + +/** + * + * @group progressbar + */ + +/** + * + * @group richtextarea + */ + +/** + * + * @group slider + */ + +/** + * + * + * @param {string} $primary-stylename (v-splitpanel) - + * @param {bool} $include-additional-styles - + * + * @group splitpanel + */ + +/** + * + * @group table + */ + +/** + * Should the tabsheet content changes be animated. + * + * @group tabsheet + */ + +/** + * The background color for text fields. + * @group textfield + */ + +/** + * Outputs the selectors and properties for the TextArea component. + * + * @param {string} $primary-stylename (v-textarea) - the primary style name for the selectors + * @param {bool} $include-additional-styles - should the mixin output all the different style variations of the component + * + * @group textarea + */ + +/** + * + * @group tree + */ + +/** + * + * + * @param {string} $primary-stylename (v-treetable) - + * + * @group treetable + */ + +/** + * + * + * @param {string} $primary-stylename (v-select-twincol) - + * + * @group twin-column-select + */ + +/** + * + * + * @param {string} $primary-stylename (v-upload) - + * + * @group upload + */ + +/** + * + */ + +/** + * @group window + */ + +@-webkit-keyframes valo-modal-window-indication { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + +@-moz-keyframes valo-modal-window-indication { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + +@keyframes valo-modal-window-indication { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + +@-webkit-keyframes valo-animate-out-scale-down-fade { + 100% { + -webkit-transform: scale(0.8); + opacity: 0; + } + } + +@-moz-keyframes valo-animate-out-scale-down-fade { + 100% { + -moz-transform: scale(0.8); + opacity: 0; + } + } + +@keyframes valo-animate-out-scale-down-fade { + 100% { + -webkit-transform: scale(0.8); + -moz-transform: scale(0.8); + -ms-transform: scale(0.8); + -o-transform: scale(0.8); + transform: scale(0.8); + opacity: 0; + } + } + +/** + * @group valo-menu + */ + +.v-vaadin-version:after { + content: "7.7.10"; +} + +.v-widget { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + display: inline-block; + vertical-align: top; + text-align: left; + white-space: normal; +} + +.v-generated-body { + overflow: hidden; + margin: 0; + padding: 0; + border: 0; +} + +.v-app { + height: 100%; + -webkit-tap-highlight-color: transparent; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.v-app input[type="text"], .v-app .v-slot > .v-caption, .v-app .v-gridlayout-slot > .v-caption, .v-app .v-has-caption > .v-caption, .v-app .v-formlayout-captioncell > .v-caption, .v-app .v-csslayout > .v-caption { + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +.v-app input::-ms-clear { + display: none; +} + +.v-ui { + position: relative; +} + +.v-ui.v-ui-embedded { + margin-top: -1px; + border-top: 1px solid transparent; +} + +.v-ui:focus { + outline: none; +} + +.v-overlay-container { + width: 0; + height: 0; +} + +.v-drag-element { + z-index: 60000; + position: absolute !important; + cursor: default; +} + +.v-clip { + overflow: hidden; +} + +.v-scrollable { + overflow: auto; +} + +.v-scrollable > .v-widget { + vertical-align: middle; + overflow: hidden; +} + +.v-ios.v-webkit .v-scrollable { + -webkit-overflow-scrolling: touch; +} + +.v-ios5.v-webkit .v-scrollable { + -webkit-overflow-scrolling: none; +} + +.v-webkit.v-ios .v-browserframe { + -webkit-overflow-scrolling: touch; + overflow: auto; +} + +.v-assistive-device-only { + position: absolute; + top: -2000px; + left: -2000px; + width: 10px; + overflow: hidden; +} + +.v-icon { + cursor: inherit; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.v-icon, .v-errorindicator, .v-required-field-indicator { + display: inline-block; + line-height: inherit; +} + +.v-caption { + display: inline-block; + white-space: nowrap; + line-height: 1.55; +} + +.v-captiontext { + display: inline-block; + line-height: inherit; +} + +div.v-layout.v-horizontal.v-widget { + white-space: nowrap; +} + +.v-layout.v-vertical > .v-expand, .v-layout.v-horizontal > .v-expand { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 100%; + height: 100%; +} + +.v-slot, .v-spacing { + display: inline-block; + white-space: nowrap; + vertical-align: top; +} + +.v-vertical > .v-slot:after { + display: inline-block; + clear: both; + width: 0; + height: 0; + overflow: hidden; +} + +.v-vertical > .v-slot, .v-vertical > .v-expand > .v-slot { + display: block; + clear: both; +} + +.v-horizontal > .v-slot, .v-horizontal > .v-expand > .v-slot { + height: 100%; +} + +.v-horizontal > .v-expand > .v-slot { + position: relative; +} + +.v-vertical > .v-spacing, .v-vertical > .v-expand > .v-spacing { + width: 0 !important; + display: block; + clear: both; +} + +.v-horizontal > .v-spacing, .v-horizontal > .v-expand > .v-spacing { + height: 0 !important; +} + +.v-align-middle:before, .v-align-bottom:before, .v-expand > .v-align-middle:before, .v-expand > .v-align-bottom:before { + content: ""; + display: inline-block; + height: 100%; + vertical-align: middle; + width: 0; +} + +.v-align-middle, .v-align-bottom { + white-space: nowrap; +} + +.v-align-middle > .v-widget, .v-align-bottom > .v-widget { + display: inline-block; +} + +.v-align-middle, .v-align-middle > .v-widget { + vertical-align: middle; +} + +.v-align-bottom, .v-align-bottom > .v-widget { + vertical-align: bottom; +} + +.v-align-center { + text-align: center; +} + +.v-align-center > .v-widget { + margin-left: auto; + margin-right: auto; +} + +.v-align-right { + text-align: right; +} + +.v-align-right > .v-widget { + margin-left: auto; +} + +.v-has-caption, .v-has-caption > .v-caption { + display: inline-block; +} + +.v-caption-on-left, .v-caption-on-right { + white-space: nowrap; +} + +.v-caption-on-top > .v-caption, .v-caption-on-bottom > .v-caption { + display: block; +} + +.v-caption-on-left > .v-caption { + padding-right: 0.5em; +} + +.v-caption-on-left > .v-widget, .v-caption-on-right > .v-widget { + display: inline-block; +} + +.v-has-caption.v-has-width > .v-widget { + width: 100% !important; +} + +.v-has-caption.v-has-height > .v-widget { + height: 100% !important; +} + +.v-gridlayout { + position: relative; +} + +.v-gridlayout-slot { + position: absolute; + line-height: 1.55; +} + +.v-gridlayout-spacing-on { + overflow: hidden; +} + +.v-gridlayout-spacing, .v-gridlayout-spacing-off { + padding-left: 0; + padding-top: 0; +} + +.v-gridlayout-spacing-off { + overflow: hidden; +} + +.v-calendar-month-day-scrollable { + overflow-y: scroll; +} + +.v-calendar-week-wrapper { + position: relative; + overflow: hidden; +} + +.v-calendar-current-time { + position: absolute; + left: 0; + width: 100%; + height: 1px; + background: red; + z-index: 2; +} + +.v-calendar-event-resizetop, .v-calendar-event-resizebottom { + position: absolute; + height: 5%; + min-height: 3px; + width: 100%; + z-index: 1; +} + +.v-calendar-event-resizetop { + cursor: row-resize; + top: 0; +} + +.v-calendar-event-resizebottom { + cursor: row-resize; + bottom: 0; +} + +.v-calendar-header-month td:first-child { + padding-left: 20px; +} + +.v-calendar-month-sizedheight .v-calendar-month-day { + height: 100px; +} + +.v-calendar-month-sizedwidth .v-calendar-month-day { + width: 100px; +} + +.v-calendar-header-month-Hsized .v-calendar-header-day { + width: 101px; +} + +.v-calendar-header-month-Hsized td:first-child { + padding-left: 21px; +} + +.v-calendar-header-day-Hsized { + width: 200px; +} + +.v-calendar-week-numbers-Vsized .v-calendar-week-number { + height: 100px; + line-height: 100px; +} + +.v-calendar-week-wrapper-Vsized { + height: 400px; + overflow-x: hidden !important; +} + +.v-calendar-times-Vsized .v-calendar-time { + height: 38px; +} + +.v-calendar-times-Hsized .v-calendar-time { + width: 42px; +} + +.v-calendar-day-times-Vsized .v-datecellslot, .v-calendar-day-times-Vsized .v-datecellslot-even { + height: 18px; +} + +.v-calendar-day-times-Hsized, .v-calendar-day-times-Hsized .v-datecellslot, .v-calendar-day-times-Hsized .v-datecellslot-even { + width: 200px; +} + +.v-colorpicker-popup.v-window { + min-width: 220px !important; +} + +.v-colorpicker-gradient-container { + overflow: visible !important; +} + +.v-colorpicker-gradient-clicklayer { + opacity: 0; + filter: alpha(opacity=0) ; +} + +.rgb-gradient .v-colorpicker-gradient-background { + background: url(../valo/components/img/colorpicker/gradient2.png); +} + +.hsv-gradient .v-colorpicker-gradient-foreground { + background: url(../valo/components/img/colorpicker/gradient.png); +} + +.v-colorpicker-gradient-higherbox:before { + content: ""; + width: 11px; + height: 11px; + border-radius: 7px; + border: 1px solid #fff; + -webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(0, 0, 0, 0.3); + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(0, 0, 0, 0.3); + position: absolute; + bottom: -6px; + left: -6px; +} + +.v-colorpicker-popup .v-slider.v-slider-red:before { + background-color: red; +} + +.v-colorpicker-popup .v-slider.v-slider-green:before { + background-color: green; +} + +.v-colorpicker-popup .v-slider.v-slider-blue:before { + background-color: blue; +} + +.v-colorpicker-popup .v-slider.hue-slider:before { + background: url(../valo/components/img/colorpicker/slider_hue_bg.png); +} + +.v-colorpicker-popup input.v-textfield-dark { + color: #fff; +} + +.v-colorpicker-popup input.v-textfield-light { + color: #000; +} + +.v-colorpicker-grid { + height: 319px; +} + +.v-colorpicker-popup .colorselect td { + line-height: 15px; +} + +.v-table-header table, .v-table-footer table, .v-table-table { + border-spacing: 0; + border-collapse: separate; + margin: 0; + padding: 0; + border: 0; + line-height: 1.55; +} + +.v-table-resizer, .v-table-sort-indicator { + float: right; +} + +.v-table-caption-container-align-center { + text-align: center; +} + +.v-table-caption-container-align-right { + text-align: right; +} + +.v-table-header td, .v-table-footer td, .v-table-cell-content { + padding: 0; +} + +.v-table-sort-indicator { + width: 0; +} + +.v-tabsheet-hidetabs > .v-tabsheet-tabcontainer, .v-tabsheet-spacertd, .v-disabled .v-tabsheet-scroller, .v-tabsheet .v-disabled .v-tabsheet-caption-close { + display: none; +} + +.v-tabsheet { + overflow: visible !important; + position: relative; +} + +.v-tabsheet-tabcontainer table, .v-tabsheet-tabcontainer tbody, .v-tabsheet-tabcontainer tr { + display: inline-block; + border-spacing: 0; + border-collapse: collapse; + vertical-align: top; +} + +.v-tabsheet-tabcontainer td { + display: inline-block; + padding: 0; +} + +.v-tabsheet-tabs { + white-space: nowrap; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.v-tabsheet-content { + position: relative; +} + +.v-tabsheet-content > div > .v-scrollable > .v-margin-top { + padding-top: 12px; +} + +.v-tabsheet-content > div > .v-scrollable > .v-margin-right { + padding-right: 12px; +} + +.v-tabsheet-content > div > .v-scrollable > .v-margin-bottom { + padding-bottom: 12px; +} + +.v-tabsheet-content > div > .v-scrollable > .v-margin-left { + padding-left: 12px; +} + +.v-splitpanel-vertical, .v-splitpanel-horizontal { + overflow: hidden; + white-space: nowrap; +} + +.v-splitpanel-hsplitter { + z-index: 100; + cursor: e-resize; + cursor: col-resize; +} + +.v-splitpanel-vsplitter { + z-index: 100; + cursor: s-resize; + cursor: row-resize; +} + +.v-splitpanel-hsplitter:after, .v-splitpanel-vsplitter:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +.v-splitpanel-hsplitter div, .v-splitpanel-vsplitter div { + width: inherit; + height: inherit; + overflow: hidden; + position: relative; +} + +.v-splitpanel-hsplitter div:before, .v-splitpanel-vsplitter div:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +.v-disabled [class$="splitter"] div { + cursor: default; +} + +.v-disabled [class$="splitter"] div:before { + display: none; +} + +.v-splitpanel-horizontal > div > .v-splitpanel-second-container { + position: static !important; + display: inline-block; + vertical-align: top; +} + +.v-splitpanel-horizontal > div > .v-splitpanel-first-container { + display: inline-block; + vertical-align: top; +} + +.mytheme.v-app, .mytheme.v-app-loading { + font: 300 16px/1.55 "Open Sans", sans-serif; + color: #464646; + background-color: #fafafa; + cursor: default; +} + +.mytheme .v-app-loading { + width: 100%; + height: 100%; + background: #fafafa; +} + +.mytheme .v-app-loading:before { + content: ""; + position: fixed; + z-index: 100; + top: 45%; + left: 50%; + width: 28px; + height: 28px; + padding: 9px; + margin-top: -24px; + margin-left: -24px; + background: #fff url(../valo/shared/img/spinner.gif) no-repeat 50%; + border-radius: 4px; +} + +.mytheme .v-loading-indicator { + position: fixed !important; + z-index: 99999; + left: 0; + right: auto; + top: 0; + width: 50%; + opacity: 1; + height: 4px; + background-color: #197de1; + pointer-events: none; + -webkit-transition: none; + -moz-transition: none; + transition: none; + -webkit-animation: v-progress-start 1000ms 200ms both; + -moz-animation: v-progress-start 1000ms 200ms both; + animation: v-progress-start 1000ms 200ms both; +} + +.mytheme .v-loading-indicator[style*="none"] { + display: block !important; + width: 100% !important; + opacity: 0; + -webkit-animation: none; + -moz-animation: none; + animation: none; + -webkit-transition: opacity 500ms 300ms, width 300ms; + -moz-transition: opacity 500ms 300ms, width 300ms; + transition: opacity 500ms 300ms, width 300ms; +} + +.mytheme .v-loading-indicator-delay { + width: 90%; + -webkit-animation: v-progress-delay 3.8s forwards; + -moz-animation: v-progress-delay 3.8s forwards; + animation: v-progress-delay 3.8s forwards; +} + +.v-ff .mytheme .v-loading-indicator-delay { + width: 50%; +} + +.mytheme .v-loading-indicator-wait { + width: 96%; + -webkit-animation: v-progress-wait 5s forwards, v-progress-wait-pulse 1s 4s infinite backwards; + -moz-animation: v-progress-wait 5s forwards, v-progress-wait-pulse 1s 4s infinite backwards; + animation: v-progress-wait 5s forwards, v-progress-wait-pulse 1s 4s infinite backwards; +} + +.v-ff .mytheme .v-loading-indicator-wait { + width: 90%; +} + +.v-ie8 .mytheme .v-loading-indicator, .v-ie8 .mytheme .v-loading-indicator-delay, .v-ie8 .mytheme .v-loading-indicator-wait, .v-ie9 .mytheme .v-loading-indicator, .v-ie9 .mytheme .v-loading-indicator-delay, .v-ie9 .mytheme .v-loading-indicator-wait { + width: 28px !important; + height: 28px; + padding: 9px; + background: #fff url(../valo/shared/img/spinner.gif) no-repeat 50%; + border-radius: 4px; + top: 9px; + right: 9px; + left: auto; + filter: alpha(opacity=50); +} + +.v-ie8 .mytheme .v-loading-indicator[style*="none"], .v-ie8 .mytheme .v-loading-indicator-delay[style*="none"], .v-ie8 .mytheme .v-loading-indicator-wait[style*="none"], .v-ie9 .mytheme .v-loading-indicator[style*="none"], .v-ie9 .mytheme .v-loading-indicator-delay[style*="none"], .v-ie9 .mytheme .v-loading-indicator-wait[style*="none"] { + display: none !important; +} + +.v-ie8 .mytheme .v-loading-indicator-wait, .v-ie9 .mytheme .v-loading-indicator-wait { + filter: alpha(opacity=100); +} + +.mytheme .v-scrollable:focus { + outline: none; +} + +.mytheme img.v-icon { + vertical-align: middle; +} + +.mytheme .v-caption { + font-size: 14px; + font-weight: 400; + padding-bottom: 0.3em; + padding-left: 1px; +} + +.mytheme .v-caption-on-left .v-caption, .mytheme .v-caption-on-right .v-caption { + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-icon + .v-captiontext, .mytheme .v-icon + span { + margin-left: 7px; +} + +.mytheme .v-icon + .v-captiontext:empty, .mytheme .v-icon + span:empty { + margin-left: 0; +} + +.mytheme .v-errorindicator { + color: #ed473b; + font-weight: 600; + width: 19px; + text-align: center; +} + +.mytheme .v-errorindicator:before { + content: "!"; +} + +.mytheme .v-required-field-indicator { + color: #ed473b; + padding: 0 0.2em; +} + +.mytheme select { + font: inherit; + font-weight: 400; + line-height: inherit; + padding: 5px; + margin: 0; + border-radius: 4px; + border: 1px solid #c5c5c5; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + color: #464646; +} + +.mytheme select:focus { + outline: none; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme button { + font: inherit; + font-weight: 400; + line-height: 1.55; +} + +.mytheme a { + cursor: pointer; + color: #197de1; + text-decoration: underline; + font-weight: inherit; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme a:hover { + color: #4396ea; +} + +.mytheme a.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-disabled { + cursor: default !important; +} + +.mytheme .v-drag-element { + background: #fafafa; + color: #464646; + -webkit-box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + border-radius: 4px; + overflow: hidden; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-tooltip { + background-color: #323232; + background-color: rgba(50, 50, 50, 0.9); + -webkit-box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2); + color: white; + padding: 5px 9px; + border-radius: 3px; + max-width: 35em; + overflow: hidden !important; + font-size: 14px; +} + +.mytheme .v-tooltip div[style*="width"] { + width: auto !important; +} + +.mytheme .v-tooltip .v-errormessage { + background-color: white; + background-color: #fff; + color: #ed473b; + margin: -5px -9px; + padding: 5px 9px; + max-height: 10em; + overflow: auto; + font-weight: 400; +} + +.mytheme .v-tooltip .v-errormessage h2:only-child { + font: inherit; + line-height: inherit; +} + +.mytheme .v-tooltip .v-tooltip-text { + max-height: 10em; + overflow: auto; + margin-top: 10px; +} + +.mytheme .v-tooltip .v-errormessage[aria-hidden="true"] + .v-tooltip-text { + margin-top: 0; +} + +.mytheme .v-tooltip h1, .mytheme .v-tooltip h2, .mytheme .v-tooltip h3, .mytheme .v-tooltip h4 { + color: inherit; +} + +.mytheme .v-contextmenu { + padding: 4px 4px; + border-radius: 4px; + background-color: white; + color: #474747; + -webkit-box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + backface-visibility: hidden; + padding: 4px 4px; +} + +.mytheme .v-contextmenu[class*="animate-in"] { + -webkit-animation: valo-overlay-animate-in 120ms; + -moz-animation: valo-overlay-animate-in 120ms; + animation: valo-overlay-animate-in 120ms; +} + +.mytheme .v-contextmenu[class*="animate-out"] { + -webkit-animation: valo-animate-out-fade 120ms; + -moz-animation: valo-animate-out-fade 120ms; + animation: valo-animate-out-fade 120ms; +} + +.mytheme .v-contextmenu table { + border-spacing: 0; +} + +.mytheme .v-contextmenu .gwt-MenuItem { + cursor: pointer; + line-height: 27px; + padding: 0 20px 0 10px; + border-radius: 3px; + font-weight: 400; + white-space: nowrap; + position: relative; + display: block; +} + +.mytheme .v-contextmenu .gwt-MenuItem:active:before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: #0957a6; + opacity: 0.15; + filter: alpha(opacity=15.0) ; + pointer-events: none; + border-radius: inherit; +} + +.mytheme .v-contextmenu .gwt-MenuItem .v-icon { + max-height: 27px; + margin-right: 5px; + min-width: 1em; +} + +.mytheme .v-contextmenu .gwt-MenuItem-selected { + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + color: #ecf2f8; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); +} + +.mytheme .v-reconnect-dialog { + color: white; + top: 12px; + right: 12px; + max-width: 100%; + border-radius: 0; + -webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.25); + padding: 12px 15px; + background-color: #444; + background-color: rgba(68, 68, 68, 0.9); + line-height: 22px; + text-align: center; +} + +.mytheme .v-reconnect-dialog .text { + display: inline-block; + padding-left: 10px; +} + +.mytheme .v-reconnect-dialog .spinner { + height: 24px !important; + width: 24px !important; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + border: 2px solid rgba(25, 125, 225, 0.2); + border-top-color: #197de1; + border-right-color: #197de1; + border-radius: 100%; + -webkit-animation: v-rotate-360 500ms infinite linear; + -moz-animation: v-rotate-360 500ms infinite linear; + animation: v-rotate-360 500ms infinite linear; + pointer-events: none; + display: none; + vertical-align: middle; +} + +.v-ie8 .mytheme .v-reconnect-dialog .spinner, .v-ie9 .mytheme .v-reconnect-dialog .spinner { + border: none; + border-radius: 4px; + background: #fff url(../valo/shared/img/spinner.gif) no-repeat 50% 50%; + background-size: 80%; +} + +.v-ie8 .mytheme .v-reconnect-dialog .spinner { + min-width: 30px; + min-height: 30px; +} + +.mytheme .v-reconnect-dialog.active .spinner { + display: inline-block; +} + +.mytheme .v-absolutelayout-wrapper { + position: absolute; +} + +.mytheme .v-absolutelayout-margin, .mytheme .v-absolutelayout-canvas { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.mytheme .v-absolutelayout.v-has-height > div, .mytheme .v-absolutelayout.v-has-height .v-absolutelayout-margin { + height: 100%; +} + +.mytheme .v-absolutelayout.v-has-height > div, .mytheme .v-absolutelayout.v-has-width .v-absolutelayout-margin { + width: 100%; +} + +.mytheme .v-margin-top { + padding-top: 37px; +} + +.mytheme .v-margin-right { + padding-right: 37px; +} + +.mytheme .v-margin-bottom { + padding-bottom: 37px; +} + +.mytheme .v-margin-left { + padding-left: 37px; +} + +.mytheme .v-spacing { + width: 12px; + height: 12px; +} + +.mytheme .v-verticallayout-well, .mytheme .v-horizontallayout-well { + background: #f5f5f5; + color: #454545; + -webkit-box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.05), inset 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.05), inset 0 2px 3px rgba(0, 0, 0, 0.05); + border-radius: 4px; + border: 1px solid #c5c5c5; +} + +.mytheme .v-verticallayout-well > div > [class*="-caption"], .mytheme .v-horizontallayout-well > div > [class*="-caption"] { + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-verticallayout-well > .v-margin-top, .mytheme .v-horizontallayout-well > .v-margin-top { + padding-top: 12px; +} + +.mytheme .v-verticallayout-well > .v-margin-right, .mytheme .v-horizontallayout-well > .v-margin-right { + padding-right: 12px; +} + +.mytheme .v-verticallayout-well > .v-margin-bottom, .mytheme .v-horizontallayout-well > .v-margin-bottom { + padding-bottom: 12px; +} + +.mytheme .v-verticallayout-well > .v-margin-left, .mytheme .v-horizontallayout-well > .v-margin-left { + padding-left: 12px; +} + +.mytheme .v-verticallayout-card, .mytheme .v-horizontallayout-card { + background: white; + color: #474747; + border-radius: 4px; + border: 1px solid #d5d5d5; + -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); +} + +.mytheme .v-verticallayout-card > .v-margin-top, .mytheme .v-horizontallayout-card > .v-margin-top { + padding-top: 12px; +} + +.mytheme .v-verticallayout-card > .v-margin-right, .mytheme .v-horizontallayout-card > .v-margin-right { + padding-right: 12px; +} + +.mytheme .v-verticallayout-card > .v-margin-bottom, .mytheme .v-horizontallayout-card > .v-margin-bottom { + padding-bottom: 12px; +} + +.mytheme .v-verticallayout-card > .v-margin-left, .mytheme .v-horizontallayout-card > .v-margin-left { + padding-left: 12px; +} + +.mytheme .v-horizontallayout-wrapping { + white-space: normal !important; +} + +.mytheme .v-horizontallayout-wrapping > .v-spacing + .v-slot, .mytheme .v-horizontallayout-wrapping > .v-slot:first-child { + margin-bottom: 12px; +} + +.mytheme .v-horizontallayout-wrapping > .v-slot:first-child:last-child { + margin-bottom: 0; +} + +.mytheme .v-button { + position: relative; + text-align: center; + white-space: nowrap; + outline: none; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + height: 37px; + padding: 0 16px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); +} + +.mytheme .v-button:before { + content: ""; + display: inline-block; + width: 0; + height: 100%; + vertical-align: middle; +} + +.mytheme .v-button > div { + vertical-align: middle; +} + +.v-sa .mytheme .v-button:before { + height: 110%; +} + +.v-ff .mytheme .v-button:before { + height: 107%; +} + +.v-ie .mytheme .v-button:before { + margin-top: 4px; +} + +.mytheme .v-button:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; +} + +.mytheme .v-button:focus:after { + -webkit-transition: none; + -moz-transition: none; + transition: none; +} + +.mytheme .v-button.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-button.v-disabled:after { + display: none; +} + +.mytheme .v-button:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-button:hover:after { + background-color: rgba(186, 186, 186, 0.1); +} + +.mytheme .v-button:focus:after { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-button:active:after { + background-color: rgba(125, 125, 125, 0.2); +} + +.mytheme .v-button-primary { + height: 37px; + padding: 0 16px; + color: #ecf2f8; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #1362b1; + border-top-color: #156ab3; + border-bottom-color: #1156a8; + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + -webkit-box-shadow: inset 0 1px 0 #4d98e6, inset 0 -1px 0 #166bca, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 #4d98e6, inset 0 -1px 0 #166bca, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); + padding: 0 19px; + font-weight: bold; + min-width: 81px; +} + +.mytheme .v-button-primary:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-button-primary:hover:after { + background-color: rgba(90, 163, 237, 0.1); +} + +.mytheme .v-button-primary:focus:after { + border: inherit; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-button-primary:active:after { + background-color: rgba(2, 62, 122, 0.2); +} + +.v-ie8 .mytheme .v-button-primary { + min-width: 43px; +} + +.mytheme .v-button-friendly { + height: 37px; + padding: 0 16px; + color: #eaf4e9; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #227719; + border-top-color: #257d1a; + border-bottom-color: #1e6b15; + background-color: #2c9720; + background-image: -webkit-linear-gradient(top, #2f9f22 2%, #26881b 98%); + background-image: linear-gradient(to bottom,#2f9f22 2%, #26881b 98%); + -webkit-box-shadow: inset 0 1px 0 #46b33a, inset 0 -1px 0 #26811b, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 #46b33a, inset 0 -1px 0 #26811b, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); +} + +.mytheme .v-button-friendly:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-button-friendly:hover:after { + background-color: rgba(65, 211, 48, 0.1); +} + +.mytheme .v-button-friendly:focus:after { + border: inherit; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-button-friendly:active:after { + background-color: rgba(14, 86, 6, 0.2); +} + +.mytheme .v-button-danger { + height: 37px; + padding: 0 16px; + color: #f9f0ef; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #bb382e; + border-top-color: #bc3c31; + border-bottom-color: #b13028; + background-color: #ed473b; + background-image: -webkit-linear-gradient(top, #ee4c3f 2%, #e13e33 98%); + background-image: linear-gradient(to bottom,#ee4c3f 2%, #e13e33 98%); + -webkit-box-shadow: inset 0 1px 0 #ef786f, inset 0 -1px 0 #da3c31, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 #ef786f, inset 0 -1px 0 #da3c31, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); +} + +.mytheme .v-button-danger:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-button-danger:hover:after { + background-color: rgba(243, 137, 129, 0.1); +} + +.mytheme .v-button-danger:focus:after { + border: inherit; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-button-danger:active:after { + background-color: rgba(146, 12, 2, 0.2); +} + +.mytheme .v-button-borderless { + border: none; + -webkit-box-shadow: none; + box-shadow: none; + background: transparent; + color: inherit; +} + +.mytheme .v-button-borderless:hover:after { + background: transparent; +} + +.mytheme .v-button-borderless:active { + opacity: 0.7; + filter: alpha(opacity=70) ; +} + +.mytheme .v-button-borderless:active:after { + background: transparent; +} + +.mytheme .v-button-borderless-colored { + border: none; + -webkit-box-shadow: none; + box-shadow: none; + background: transparent; + color: #197de1; +} + +.mytheme .v-button-borderless-colored:hover { + color: #4396ea; +} + +.mytheme .v-button-borderless-colored:hover:after { + background: transparent; +} + +.mytheme .v-button-borderless-colored:active { + opacity: 0.7; + filter: alpha(opacity=70) ; +} + +.mytheme .v-button-borderless-colored:active:after { + background: transparent; +} + +.mytheme .v-button-quiet { + visibility: hidden; +} + +.mytheme .v-button-quiet:focus, .mytheme .v-button-quiet:hover { + visibility: visible; +} + +.mytheme .v-button-quiet [class*="wrap"] { + visibility: visible; +} + +.mytheme .v-button-quiet [class*="caption"] { + display: inline-block; +} + +.mytheme .v-button-link { + border: none; + -webkit-box-shadow: none; + box-shadow: none; + background: transparent; + color: inherit; + cursor: pointer; + color: #197de1; + text-decoration: underline; + font-weight: inherit; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme .v-button-link:hover:after { + background: transparent; +} + +.mytheme .v-button-link:active { + opacity: 0.7; + filter: alpha(opacity=70) ; +} + +.mytheme .v-button-link:active:after { + background: transparent; +} + +.mytheme .v-button-link:hover { + color: #4396ea; +} + +.mytheme .v-button-link.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-button-tiny { + height: 28px; + padding: 0 13px; + + + font-size: 12px; + + border-radius: 4px; +} + +.mytheme .v-button-tiny:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-button-small { + height: 31px; + padding: 0 14px; + + + font-size: 14px; + + border-radius: 4px; +} + +.mytheme .v-button-small:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-button-large { + height: 44px; + padding: 0 19px; + + + font-size: 20px; + + border-radius: 4px; +} + +.mytheme .v-button-large:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-button-huge { + height: 59px; + padding: 0 26px; + + + font-size: 26px; + + border-radius: 4px; +} + +.mytheme .v-button-huge:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-button-icon-align-right [class*="wrap"] { + display: inline-block; +} + +.mytheme .v-button-icon-align-right .v-icon { + float: right; + margin-left: 13px; +} + +.mytheme .v-button-icon-align-right .v-icon + span:not(:empty) { + margin-left: 0; +} + +.mytheme .v-button-icon-align-top { + height: auto; + padding-top: 5px; + padding-bottom: 5px; +} + +.mytheme .v-button-icon-align-top [class*="wrap"] { + display: inline-block; +} + +.mytheme .v-button-icon-align-top .v-icon { + display: block; + margin-left: auto; + margin-right: auto; +} + +.mytheme .v-button-icon-align-top .v-icon + span:not(:empty) { + margin-top: 7px; + margin-left: 0; +} + +.mytheme .v-button-icon-only { + width: 37px; + padding: 0; +} + +.mytheme .v-button-icon-only.v-button-tiny { + width: 28px; +} + +.mytheme .v-button-icon-only.v-button-small { + width: 31px; +} + +.mytheme .v-button-icon-only.v-button-large { + width: 44px; +} + +.mytheme .v-button-icon-only.v-button-huge { + width: 59px; +} + +.mytheme .v-button-icon-only .v-button-caption { + display: none; +} + +.mytheme .v-checkbox { + position: relative; + line-height: 19px; + white-space: nowrap; +} + +.mytheme .v-checkbox.v-has-width label { + white-space: normal; +} + +:root .mytheme .v-checkbox { + padding-left: 25px; +} + +:root .mytheme .v-checkbox label { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + display: inline-block; +} + +:root .mytheme .v-checkbox > input { + position: absolute; + clip: rect(0, 0, 0, 0); + left: 0.2em; + top: 0.2em; + z-index: 0; + margin: 0; +} + +:root .mytheme .v-checkbox > input:focus ~ label:before { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); +} + +:root .mytheme .v-checkbox > input ~ label:before, :root .mytheme .v-checkbox > input ~ label:after { + content: ""; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 19px; + height: 19px; + position: absolute; + top: 0; + left: 0; + border-radius: 4px; + font-size: 13px; + text-align: center; +} + +:root .mytheme .v-checkbox > input ~ label:before { + height: 18.5px; + padding: 0 9px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + padding: 0; + height: 19px; +} + +:root .mytheme .v-checkbox > input ~ label:after { + content: "\f00c"; + font-family: ThemeIcons; + color: transparent; + -webkit-transition: color 100ms; + -moz-transition: color 100ms; + transition: color 100ms; +} + +:root .mytheme .v-checkbox > input:active ~ label:after { + background-color: rgba(125, 125, 125, 0.2); +} + +:root .mytheme .v-checkbox > input:checked ~ label:after { + color: #197de1; +} + +.mytheme .v-checkbox > .v-icon, .mytheme .v-checkbox > label .v-icon { + margin: 0 6px 0 3px; + min-width: 1em; + cursor: pointer; +} + +.mytheme .v-checkbox.v-disabled > label, .mytheme .v-checkbox.v-disabled > .v-icon { + cursor: default; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-checkbox.v-disabled > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-checkbox.v-disabled > input:active ~ label:after { + background: transparent; +} + +.mytheme .v-checkbox.v-readonly > label, .mytheme .v-checkbox.v-readonly > .v-icon { + cursor: default; +} + +.mytheme .v-checkbox.v-readonly > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-checkbox.v-readonly > input:active ~ label:after { + background: transparent; +} + +:root .mytheme .v-checkbox.v-readonly > input ~ label:after { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-checkbox-small { + position: relative; + line-height: 16px; + white-space: nowrap; + font-size: 14px; +} + +.mytheme .v-checkbox-small.v-has-width label { + white-space: normal; +} + +:root .mytheme .v-checkbox-small { + padding-left: 21px; +} + +:root .mytheme .v-checkbox-small label { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + display: inline-block; +} + +:root .mytheme .v-checkbox-small > input { + position: absolute; + clip: rect(0, 0, 0, 0); + left: 0.2em; + top: 0.2em; + z-index: 0; + margin: 0; +} + +:root .mytheme .v-checkbox-small > input:focus ~ label:before { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); +} + +:root .mytheme .v-checkbox-small > input ~ label:before, :root .mytheme .v-checkbox-small > input ~ label:after { + content: ""; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 16px; + height: 16px; + position: absolute; + top: 0; + left: 0; + border-radius: 4px; + font-size: 11px; + text-align: center; +} + +:root .mytheme .v-checkbox-small > input ~ label:before { + height: 15.5px; + padding: 0 7px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + padding: 0; + height: 16px; +} + +:root .mytheme .v-checkbox-small > input ~ label:after { + content: "\f00c"; + font-family: ThemeIcons; + color: transparent; + -webkit-transition: color 100ms; + -moz-transition: color 100ms; + transition: color 100ms; +} + +:root .mytheme .v-checkbox-small > input:active ~ label:after { + background-color: rgba(125, 125, 125, 0.2); +} + +:root .mytheme .v-checkbox-small > input:checked ~ label:after { + color: #197de1; +} + +.mytheme .v-checkbox-small > .v-icon, .mytheme .v-checkbox-small > label .v-icon { + margin: 0 5px 0 3px; + min-width: 1em; + cursor: pointer; +} + +.mytheme .v-checkbox-small.v-disabled > label, .mytheme .v-checkbox-small.v-disabled > .v-icon { + cursor: default; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-checkbox-small.v-disabled > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-checkbox-small.v-disabled > input:active ~ label:after { + background: transparent; +} + +.mytheme .v-checkbox-small.v-readonly > label, .mytheme .v-checkbox-small.v-readonly > .v-icon { + cursor: default; +} + +.mytheme .v-checkbox-small.v-readonly > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-checkbox-small.v-readonly > input:active ~ label:after { + background: transparent; +} + +:root .mytheme .v-checkbox-small.v-readonly > input ~ label:after { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-checkbox-large { + position: relative; + line-height: 22px; + white-space: nowrap; + font-size: 20px; +} + +.mytheme .v-checkbox-large.v-has-width label { + white-space: normal; +} + +:root .mytheme .v-checkbox-large { + padding-left: 29px; +} + +:root .mytheme .v-checkbox-large label { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + display: inline-block; +} + +:root .mytheme .v-checkbox-large > input { + position: absolute; + clip: rect(0, 0, 0, 0); + left: 0.2em; + top: 0.2em; + z-index: 0; + margin: 0; +} + +:root .mytheme .v-checkbox-large > input:focus ~ label:before { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); +} + +:root .mytheme .v-checkbox-large > input ~ label:before, :root .mytheme .v-checkbox-large > input ~ label:after { + content: ""; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 22px; + height: 22px; + position: absolute; + top: 0; + left: 0; + border-radius: 4px; + font-size: 15px; + text-align: center; +} + +:root .mytheme .v-checkbox-large > input ~ label:before { + height: 22px; + padding: 0 10px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + padding: 0; + height: 22px; +} + +:root .mytheme .v-checkbox-large > input ~ label:after { + content: "\f00c"; + font-family: ThemeIcons; + color: transparent; + -webkit-transition: color 100ms; + -moz-transition: color 100ms; + transition: color 100ms; +} + +:root .mytheme .v-checkbox-large > input:active ~ label:after { + background-color: rgba(125, 125, 125, 0.2); +} + +:root .mytheme .v-checkbox-large > input:checked ~ label:after { + color: #197de1; +} + +.mytheme .v-checkbox-large > .v-icon, .mytheme .v-checkbox-large > label .v-icon { + margin: 0 7px 0 4px; + min-width: 1em; + cursor: pointer; +} + +.mytheme .v-checkbox-large.v-disabled > label, .mytheme .v-checkbox-large.v-disabled > .v-icon { + cursor: default; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-checkbox-large.v-disabled > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-checkbox-large.v-disabled > input:active ~ label:after { + background: transparent; +} + +.mytheme .v-checkbox-large.v-readonly > label, .mytheme .v-checkbox-large.v-readonly > .v-icon { + cursor: default; +} + +.mytheme .v-checkbox-large.v-readonly > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-checkbox-large.v-readonly > input:active ~ label:after { + background: transparent; +} + +:root .mytheme .v-checkbox-large.v-readonly > input ~ label:after { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-filterselect { + position: relative; + width: 185px; + height: 37px; + border-radius: 4px; + white-space: nowrap; +} + +.mytheme .v-filterselect [class*="input"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 37px; + border-radius: 4px; + padding: 4px 9px; + border: 1px solid #c5c5c5; + background: white; + color: #474747; + -webkit-box-shadow: inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + width: 100% !important; + height: 100%; + padding-right: 38px; + border-radius: inherit; +} + +.v-ie8 .mytheme .v-filterselect [class*="input"], .v-ie9 .mytheme .v-filterselect [class*="input"] { + line-height: 37px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-filterselect [class*="input"].v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-filterselect [class*="input"]:focus { + outline: none; + -webkit-transition: none; + -moz-transition: none; + transition: none; + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-filterselect [class*="input"][class*="prompt"] { + color: #a3a3a3; +} + +.mytheme .v-filterselect .v-icon + [class*="input"] { + padding-left: 37px; +} + +.mytheme .v-filterselect img.v-icon { + max-height: 37px; + margin-left: 9px; +} + +.mytheme .v-filterselect span.v-icon { + color: #474747; + width: 37px; + line-height: 1; + padding-top: 0.12em; +} + +.mytheme .v-filterselect[class*="prompt"] > [class*="input"] { + color: #a3a3a3; +} + +.mytheme .v-filterselect [class$="button"] { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + position: absolute; + width: 37px; + top: 1px; + right: 1px; + bottom: 1px; + border-left: 1px solid #e4e4e4; + color: #a3a3a3; + border-radius: 0 3px 3px 0; +} + +.v-ie8 .mytheme .v-filterselect [class$="button"] { + background-color: white; +} + +.mytheme .v-filterselect [class$="button"]:before { + font-family: ThemeIcons; + content: "\f078"; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; + position: absolute; + width: 37px; + text-align: center; + top: 50%; + line-height: 1; + margin-top: -0.47em; +} + +.mytheme .v-filterselect [class$="button"]:hover:before { + color: #474747; +} + +.mytheme .v-filterselect [class$="button"]:active:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; + background-color: rgba(128, 128, 128, 0.2); +} + +.mytheme .v-filterselect.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-filterselect.v-disabled [class$="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-filterselect.v-disabled [class$="button"]:active:after { + display: none; +} + +.mytheme .v-filterselect.v-readonly [class*="input"] { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-filterselect.v-readonly [class*="input"]:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-filterselect.v-readonly [class$="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-filterselect.v-readonly [class$="button"]:active:after { + display: none; +} + +.mytheme .v-filterselect .v-icon { + position: absolute; + pointer-events: none; +} + +.mytheme .v-filterselect-error .v-filterselect-input { + border-color: #ed473b !important; + background: #fffbfb; + color: #6c2621; +} + +.mytheme .v-filterselect-error .v-filterselect-button { + color: #ed473b; + border-color: #ed473b; +} + +.mytheme .v-filterselect-suggestpopup { + margin-top: 5px !important; +} + +.mytheme .v-filterselect-suggestpopup[class*="animate-in"] { + -webkit-animation: valo-overlay-animate-in 120ms; + -moz-animation: valo-overlay-animate-in 120ms; + animation: valo-overlay-animate-in 120ms; +} + +.mytheme .v-filterselect-suggestpopup [class$="suggestmenu"] { + padding: 4px 4px; + border-radius: 4px; + background-color: white; + color: #474747; + -webkit-box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + backface-visibility: hidden; + padding: 4px 4px; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + position: relative; + z-index: 1; + display: block; +} + +.mytheme .v-filterselect-suggestpopup table, .mytheme .v-filterselect-suggestpopup tbody, .mytheme .v-filterselect-suggestpopup tr, .mytheme .v-filterselect-suggestpopup td { + display: block; + width: 100%; + overflow-y: hidden; + float: left; + clear: both; +} + +.mytheme .v-filterselect-suggestpopup .gwt-MenuItem { + cursor: pointer; + line-height: 27px; + padding: 0 20px 0 10px; + border-radius: 3px; + font-weight: 400; + white-space: nowrap; + position: relative; + height: 27px; + box-sizing: border-box; + text-overflow: ellipsis; + overflow-x: hidden; +} + +.mytheme .v-filterselect-suggestpopup .gwt-MenuItem:active:before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: #0957a6; + opacity: 0.15; + filter: alpha(opacity=15.0) ; + pointer-events: none; + border-radius: inherit; +} + +.mytheme .v-filterselect-suggestpopup .gwt-MenuItem .v-icon { + max-height: 27px; + margin-right: 5px; + min-width: 1em; +} + +.mytheme .v-filterselect-suggestpopup .gwt-MenuItem-selected { + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + color: #ecf2f8; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); +} + +.mytheme .v-filterselect-suggestpopup [class$="status"] { + position: absolute; + right: 4px; + background: rgba(212, 212, 212, 0.9); + color: #3b3b3b; + border-radius: 0 0 4px 4px; + height: 23px; + bottom: -23px; + font-size: 12px; + line-height: 23px; + padding: 0 6px; + cursor: default; + pointer-events: none; + -webkit-animation: valo-animate-in-slide-down 200ms 80ms backwards; + -moz-animation: valo-animate-in-slide-down 200ms 80ms backwards; + animation: valo-animate-in-slide-down 200ms 80ms backwards; +} + +.mytheme .v-filterselect-suggestpopup [class$="status"] > * { + color: #3b3b3b; + text-decoration: none; +} + +.mytheme .v-filterselect-suggestpopup div[class*="page"] { + position: absolute; + z-index: 3; + right: 0; + opacity: 0.2; + filter: alpha(opacity=20) ; + cursor: pointer; + -webkit-transition: all 200ms; + -moz-transition: all 200ms; + transition: all 200ms; + width: 25px; + height: 25px; + line-height: 25px; + text-align: center; + font-family: ThemeIcons; + -webkit-transform: scale(0.8); + -moz-transform: scale(0.8); + -ms-transform: scale(0.8); + -o-transform: scale(0.8); + transform: scale(0.8); + color: #464646; +} + +.mytheme .v-filterselect-suggestpopup div[class*="page"]:after { + content: ""; + position: absolute; + display: block; + border-radius: 50%; +} + +.mytheme .v-filterselect-suggestpopup div[class*="page"]:hover { + opacity: 1; + filter: none ; + background: rgba(250, 250, 250, 0.5); +} + +.mytheme .v-filterselect-suggestpopup div[class*="page"]:hover:after { + top: -10px; + bottom: -10px; + left: -20px; + right: -20px; +} + +.mytheme .v-filterselect-suggestpopup div[class*="page"] span { + display: none; +} + +.mytheme .v-filterselect-suggestpopup:hover div[class*="page"] { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -ms-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); +} + +.mytheme .v-filterselect-suggestpopup div[class*="prev"] { + top: 0; + -webkit-transform-origin: 100% 0%; + -moz-transform-origin: 100% 0%; + -ms-transform-origin: 100% 0%; + -o-transform-origin: 100% 0%; + transform-origin: 100% 0%; + border-radius: 0 4px 0 4px; +} + +.mytheme .v-filterselect-suggestpopup div[class*="prev"]:before { + content: "\f0d8"; +} + +.mytheme .v-filterselect-suggestpopup div[class*="next"] { + bottom: 0; + -webkit-transform-origin: 100% 100%; + -moz-transform-origin: 100% 100%; + -ms-transform-origin: 100% 100%; + -o-transform-origin: 100% 100%; + transform-origin: 100% 100%; + border-radius: 4px 0 4px 0; +} + +.mytheme .v-filterselect-suggestpopup div[class*="next"]:before { + content: "\f0d7"; +} + +.mytheme .v-filterselect-suggestpopup div[class*="-off"] { + display: none; +} + +.mytheme .v-filterselect-no-input { + cursor: pointer; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); +} + +.mytheme .v-filterselect-no-input [class*="input"] { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + cursor: inherit; + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + text-shadow: inherit; + text-overflow: ellipsis; + border-radius: inherit; +} + +.mytheme .v-filterselect-no-input [class*="input"]:focus { + outline: none; + -webkit-transition: none; + -moz-transition: none; + transition: none; + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-filterselect-no-input [class$="button"] { + border-left: none !important; +} + +.mytheme .v-filterselect-no-input:hover [class$="button"]:before { + color: inherit; +} + +.mytheme .v-filterselect-borderless .v-filterselect-input { + border: none; + border-radius: 0; + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; + color: inherit; +} + +.mytheme .v-filterselect-borderless .v-filterselect-input:focus { + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-filterselect-borderless .v-filterselect-input[class*="prompt"] { + color: inherit; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-filterselect-borderless .v-filterselect-button { + border: none; + color: inherit; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-filterselect-borderless.v-filterselect-prompt .v-filterselect-input { + color: inherit; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-filterselect-align-right input { + text-align: right; +} + +.mytheme .v-filterselect-align-center input { + text-align: center; +} + +.mytheme .v-filterselect-tiny { + height: 28px; + + font-size: 12px; +} + +.mytheme .v-filterselect-tiny [class*="input"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 28px; + + padding: 3px 5px; + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + width: 100% !important; + height: 100%; + padding-right: 29px; + border-radius: inherit; +} + +.v-ie8 .mytheme .v-filterselect-tiny [class*="input"], .v-ie9 .mytheme .v-filterselect-tiny [class*="input"] { + line-height: 28px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-filterselect-tiny .v-icon + [class*="input"] { + padding-left: 28px; +} + +.mytheme .v-filterselect-tiny img.v-icon { + max-height: 28px; + margin-left: 5px; +} + +.mytheme .v-filterselect-tiny span.v-icon { + + width: 28px; + line-height: 1; + padding-top: 0.12em; +} + +.mytheme .v-filterselect-tiny [class$="button"] { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + position: absolute; + width: 28px; + border-radius: 0 4px 4px 0; +} + +.mytheme .v-filterselect-tiny [class$="button"]:before { + font-family: ThemeIcons; + content: "\f078"; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; + position: absolute; + width: 28px; + text-align: center; + top: 50%; + line-height: 1; + margin-top: -0.47em; +} + +.mytheme .v-filterselect-tiny [class$="button"]:active:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; +} + +.mytheme .v-filterselect-tiny.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-filterselect-tiny.v-disabled [class$="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-filterselect-tiny.v-disabled [class$="button"]:active:after { + display: none; +} + +.mytheme .v-filterselect-tiny.v-readonly [class*="input"] { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-filterselect-tiny.v-readonly [class*="input"]:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-filterselect-tiny.v-readonly [class$="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-filterselect-tiny.v-readonly [class$="button"]:active:after { + display: none; +} + +.mytheme .v-filterselect-compact, .mytheme .v-filterselect-small { + height: 31px; + +} + +.mytheme .v-filterselect-compact [class*="input"], .mytheme .v-filterselect-small [class*="input"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 31px; + + padding: 3px 6px; + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + width: 100% !important; + height: 100%; + padding-right: 32px; + border-radius: inherit; +} + +.v-ie8 .mytheme .v-filterselect-compact [class*="input"], .v-ie9 .mytheme .v-filterselect-compact [class*="input"], .v-ie8 .mytheme .v-filterselect-small [class*="input"], .v-ie9 .mytheme .v-filterselect-small [class*="input"] { + line-height: 31px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-filterselect-compact .v-icon + [class*="input"], .mytheme .v-filterselect-small .v-icon + [class*="input"] { + padding-left: 31px; +} + +.mytheme .v-filterselect-compact img.v-icon, .mytheme .v-filterselect-small img.v-icon { + max-height: 31px; + margin-left: 6px; +} + +.mytheme .v-filterselect-compact span.v-icon, .mytheme .v-filterselect-small span.v-icon { + + width: 31px; + line-height: 1; + padding-top: 0.12em; +} + +.mytheme .v-filterselect-compact [class$="button"], .mytheme .v-filterselect-small [class$="button"] { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + position: absolute; + width: 31px; + border-radius: 0 4px 4px 0; +} + +.mytheme .v-filterselect-compact [class$="button"]:before, .mytheme .v-filterselect-small [class$="button"]:before { + font-family: ThemeIcons; + content: "\f078"; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; + position: absolute; + width: 31px; + text-align: center; + top: 50%; + line-height: 1; + margin-top: -0.47em; +} + +.mytheme .v-filterselect-compact [class$="button"]:active:after, .mytheme .v-filterselect-small [class$="button"]:active:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; +} + +.mytheme .v-filterselect-compact.v-disabled, .mytheme .v-filterselect-small.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-filterselect-compact.v-disabled [class$="button"], .mytheme .v-filterselect-small.v-disabled [class$="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-filterselect-compact.v-disabled [class$="button"]:active:after, .mytheme .v-filterselect-small.v-disabled [class$="button"]:active:after { + display: none; +} + +.mytheme .v-filterselect-compact.v-readonly [class*="input"], .mytheme .v-filterselect-small.v-readonly [class*="input"] { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-filterselect-compact.v-readonly [class*="input"]:focus, .mytheme .v-filterselect-small.v-readonly [class*="input"]:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-filterselect-compact.v-readonly [class$="button"], .mytheme .v-filterselect-small.v-readonly [class$="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-filterselect-compact.v-readonly [class$="button"]:active:after, .mytheme .v-filterselect-small.v-readonly [class$="button"]:active:after { + display: none; +} + +.mytheme .v-filterselect-small { + font-size: 14px; +} + +.mytheme .v-filterselect-large { + height: 44px; + + font-size: 20px; +} + +.mytheme .v-filterselect-large [class*="input"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 44px; + + padding: 5px 8px; + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + width: 100% !important; + height: 100%; + padding-right: 45px; + border-radius: inherit; +} + +.v-ie8 .mytheme .v-filterselect-large [class*="input"], .v-ie9 .mytheme .v-filterselect-large [class*="input"] { + line-height: 44px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-filterselect-large .v-icon + [class*="input"] { + padding-left: 44px; +} + +.mytheme .v-filterselect-large img.v-icon { + max-height: 44px; + margin-left: 8px; +} + +.mytheme .v-filterselect-large span.v-icon { + + width: 44px; + line-height: 1; + padding-top: 0.12em; +} + +.mytheme .v-filterselect-large [class$="button"] { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + position: absolute; + width: 44px; + border-radius: 0 4px 4px 0; +} + +.mytheme .v-filterselect-large [class$="button"]:before { + font-family: ThemeIcons; + content: "\f078"; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; + position: absolute; + width: 44px; + text-align: center; + top: 50%; + line-height: 1; + margin-top: -0.47em; +} + +.mytheme .v-filterselect-large [class$="button"]:active:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; +} + +.mytheme .v-filterselect-large.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-filterselect-large.v-disabled [class$="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-filterselect-large.v-disabled [class$="button"]:active:after { + display: none; +} + +.mytheme .v-filterselect-large.v-readonly [class*="input"] { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-filterselect-large.v-readonly [class*="input"]:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-filterselect-large.v-readonly [class$="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-filterselect-large.v-readonly [class$="button"]:active:after { + display: none; +} + +.mytheme .v-filterselect-huge { + height: 59px; + + font-size: 26px; +} + +.mytheme .v-filterselect-huge [class*="input"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 59px; + + padding: 7px 10px; + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + width: 100% !important; + height: 100%; + padding-right: 60px; + border-radius: inherit; +} + +.v-ie8 .mytheme .v-filterselect-huge [class*="input"], .v-ie9 .mytheme .v-filterselect-huge [class*="input"] { + line-height: 59px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-filterselect-huge .v-icon + [class*="input"] { + padding-left: 59px; +} + +.mytheme .v-filterselect-huge img.v-icon { + max-height: 59px; + margin-left: 10px; +} + +.mytheme .v-filterselect-huge span.v-icon { + + width: 59px; + line-height: 1; + padding-top: 0.12em; +} + +.mytheme .v-filterselect-huge [class$="button"] { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + position: absolute; + width: 59px; + border-radius: 0 4px 4px 0; +} + +.mytheme .v-filterselect-huge [class$="button"]:before { + font-family: ThemeIcons; + content: "\f078"; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; + position: absolute; + width: 59px; + text-align: center; + top: 50%; + line-height: 1; + margin-top: -0.47em; +} + +.mytheme .v-filterselect-huge [class$="button"]:active:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; +} + +.mytheme .v-filterselect-huge.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-filterselect-huge.v-disabled [class$="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-filterselect-huge.v-disabled [class$="button"]:active:after { + display: none; +} + +.mytheme .v-filterselect-huge.v-readonly [class*="input"] { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-filterselect-huge.v-readonly [class*="input"]:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-filterselect-huge.v-readonly [class$="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-filterselect-huge.v-readonly [class$="button"]:active:after { + display: none; +} + +.mytheme .v-csslayout-well { + background: #f5f5f5; + color: #454545; + -webkit-box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.05), inset 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.05), inset 0 2px 3px rgba(0, 0, 0, 0.05); + border-radius: 4px; + border: 1px solid #c5c5c5; +} + +.mytheme .v-csslayout-well > div > [class*="-caption"] { + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-csslayout-well > .v-margin-top { + padding-top: 12px; +} + +.mytheme .v-csslayout-well > .v-margin-right { + padding-right: 12px; +} + +.mytheme .v-csslayout-well > .v-margin-bottom { + padding-bottom: 12px; +} + +.mytheme .v-csslayout-well > .v-margin-left { + padding-left: 12px; +} + +.mytheme .v-csslayout-card { + background: white; + color: #474747; + border-radius: 4px; + border: 1px solid #d5d5d5; + -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); +} + +.mytheme .v-csslayout-card > .v-margin-top { + padding-top: 12px; +} + +.mytheme .v-csslayout-card > .v-margin-right { + padding-right: 12px; +} + +.mytheme .v-csslayout-card > .v-margin-bottom { + padding-bottom: 12px; +} + +.mytheme .v-csslayout-card > .v-margin-left { + padding-left: 12px; +} + +.mytheme .v-csslayout-v-component-group { + white-space: nowrap; + position: relative; +} + +.mytheme .v-csslayout-v-component-group .v-widget ~ .v-widget:not(:last-child) { + border-radius: 0; +} + +.mytheme .v-csslayout-v-component-group .v-widget:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.mytheme .v-csslayout-v-component-group .v-widget:first-child, .mytheme .v-csslayout-v-component-group .v-caption:first-child + .v-widget { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.mytheme .v-csslayout-v-component-group .v-widget ~ .v-widget.first.first { + border-radius: 4px 0 0 4px; +} + +.mytheme .v-csslayout-v-component-group .v-widget ~ .v-widget.last.last { + border-radius: 0 4px 4px 0; +} + +.mytheme .v-csslayout-v-component-group .v-widget { + vertical-align: middle; + margin-left: -1px; +} + +.mytheme .v-csslayout-v-component-group .v-widget:first-child { + margin-left: 0; +} + +.mytheme .v-csslayout-v-component-group .v-widget:focus, .mytheme .v-csslayout-v-component-group .v-widget[class*="focus"], .mytheme .v-csslayout-v-component-group .v-widget [class*="focus"] { + position: relative; + z-index: 5; +} + +.mytheme .v-form fieldset { + border: none; + padding: 0; + margin: 0; + height: 100%; +} + +.mytheme .v-form-content { + height: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.mytheme [class*="spacing"] > tbody > [class*="row"] > td { + padding-top: 12px; +} + +.mytheme [class*="spacing"] > tbody > [class*="firstrow"] > td { + padding-top: 0; +} + +.mytheme [class*="margin-top"] > tbody > [class*="firstrow"] > td { + padding-top: 37px; +} + +.mytheme [class*="margin-bottom"] > tbody > [class*="lastrow"] > td { + padding-bottom: 37px; +} + +.mytheme [class*="margin-left"] > tbody > [class*="row"] > [class*="captioncell"] { + padding-left: 37px; +} + +.mytheme [class*="margin-left"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h2, .mytheme [class*="margin-left"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h3, .mytheme [class*="margin-left"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h4 { + left: 37px; +} + +.mytheme [class*="margin-right"] > tbody > [class*="row"] > [class*="contentcell"] { + padding-right: 37px; +} + +.mytheme [class*="margin-right"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h2, .mytheme [class*="margin-right"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h3, .mytheme [class*="margin-right"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h4 { + right: 37px; +} + +.mytheme .v-formlayout > table { + border-spacing: 0; + position: relative; +} + +.mytheme .v-formlayout.v-has-width > table, .mytheme .v-formlayout.v-has-width .v-formlayout-contentcell { + width: 100%; +} + +.mytheme .v-formlayout-error-indicator { + width: 19px; +} + +.mytheme .v-formlayout-captioncell { + vertical-align: top; + line-height: 36px; +} + +.mytheme .v-formlayout-captioncell .v-caption { + padding-bottom: 0; +} + +.mytheme .v-formlayout-captioncell .v-caption-h2, .mytheme .v-formlayout-captioncell .v-caption-h3, .mytheme .v-formlayout-captioncell .v-caption-h4 { + height: 3em; +} + +.mytheme .v-formlayout-contentcell .v-checkbox, .mytheme .v-formlayout-contentcell .v-radiobutton { + font-weight: 400; +} + +.mytheme .v-formlayout-contentcell > .v-label-h2, .mytheme .v-formlayout-contentcell > .v-label-h3, .mytheme .v-formlayout-contentcell > .v-label-h4 { + position: absolute; + left: 0; + right: 0; + width: auto !important; + margin-top: -0.5em; + padding-bottom: 0.5em; + border-bottom: 1px solid #dfdfdf; +} + +.mytheme .v-formlayout.light > table { + padding: 0; +} + +.mytheme .v-formlayout.light > table > tbody > tr > td { + padding-top: 0; + height: 37px; + border-bottom: 1px solid #eaeaea; +} + +.mytheme .v-formlayout.light > table > tbody > [class*="lastrow"] > td { + border-bottom: none; +} + +.mytheme .v-formlayout.light > table > tbody > tr > [class*="captioncell"] { + color: #7d7d7d; + text-align: right; + padding-left: 13px; + line-height: 37px; +} + +.mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] { + padding-right: 0; +} + +.mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textfield, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textarea, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-filterselect, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-datefield, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-filterselect-input, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-datefield-textfield { + width: 100%; +} + +.mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textfield, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textarea, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-filterselect input, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-datefield input, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-richtextarea { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 37px; + border-radius: 0; + padding: 4px 7px; + + -webkit-box-shadow: none; + box-shadow: none; + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + background: transparent; + border: none; + color: inherit; +} + +.v-ie8 .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textfield, .v-ie9 .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textfield, .v-ie8 .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textarea, .v-ie9 .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textarea, .v-ie8 .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-filterselect input, .v-ie9 .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-filterselect input, .v-ie8 .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-datefield input, .v-ie9 .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-datefield input, .v-ie8 .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-richtextarea, .v-ie9 .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-richtextarea { + line-height: 37px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textfield.v-disabled, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textarea.v-disabled, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-filterselect input.v-disabled, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-datefield input.v-disabled, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-richtextarea.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textfield:focus, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textarea:focus, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-filterselect input:focus, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-datefield input:focus, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-richtextarea:focus { + outline: none; + -webkit-transition: none; + -moz-transition: none; + transition: none; + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), none; + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), none; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textfield:focus, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textarea:focus, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-filterselect input:focus, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-datefield input:focus, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-richtextarea:focus { + box-shadow: none; +} + +.mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textfield-prompt, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textarea-prompt, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-filterselect-prompt input, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-datefield-prompt input { + color: #a3a3a3; +} + +.mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-textarea, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-richtextarea { + height: auto; +} + +.mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h2, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h3, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h4 { + border-bottom: none; + left: 0; + right: 0; +} + +.mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h3, .mytheme .v-formlayout.light > table > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h4 { + margin-top: 0; +} + +.mytheme .v-formlayout.light .v-richtextarea { + margin: 5px 0; +} + +.mytheme .v-formlayout.light .v-filterselect-button, .mytheme .v-formlayout.light .v-datefield-button { + border: none; +} + +.mytheme .v-formlayout.light .v-filterselect-button:active:after, .mytheme .v-formlayout.light .v-datefield-button:active:after { + display: none; +} + +.mytheme .v-formlayout.light .v-datefield-button { + right: 0; + left: auto; +} + +.mytheme .v-formlayout.light .v-checkbox { + margin-left: 7px; +} + +.mytheme .v-grid { + position: relative; +} + +.mytheme .v-grid-scroller { + position: absolute; + z-index: 1; + outline: none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.mytheme .v-grid-scroller-horizontal { + left: 0; + right: 0; + bottom: 0; + overflow-y: hidden; + -ms-overflow-y: hidden; +} + +.mytheme .v-grid-scroller-vertical { + right: 0; + top: 0; + bottom: 0; + overflow-x: hidden; + -ms-overflow-x: hidden; +} + +.mytheme .v-grid-tablewrapper { + position: absolute; + overflow: hidden; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + z-index: 5; +} + +.mytheme .v-grid-tablewrapper > table { + border-spacing: 0; + table-layout: fixed; + width: inherit; +} + +.mytheme .v-grid-header-deco, .mytheme .v-grid-footer-deco { + position: absolute; + right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.mytheme .v-grid-horizontal-scrollbar-deco { + position: absolute; + bottom: 0; + left: 0; + right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.mytheme .v-grid-header, .mytheme .v-grid-body, .mytheme .v-grid-footer { + position: absolute; + left: 0; + width: inherit; + z-index: 10; +} + +.mytheme .v-grid-header, .mytheme .v-grid-header-deco { + top: 0; +} + +.mytheme .v-grid-footer, .mytheme .v-grid-footer-deco { + bottom: 0; +} + +.mytheme .v-grid-body { + -ms-touch-action: none; + touch-action: none; + z-index: 0; + top: 0; +} + +.mytheme .v-grid-body .v-grid-row { + position: absolute; + top: 0; + left: 0; +} + +.mytheme .v-grid-row { + display: block; +} + +.v-ie8 .mytheme .v-grid-row, .v-ie9 .mytheme .v-grid-row { + float: left; + clear: left; + margin-top: 0; +} + +.mytheme .v-grid-row > td, .mytheme .v-grid-row > th { + background-color: white; +} + +.mytheme .v-grid-row { + width: inherit; +} + +.mytheme .v-grid-cell { + display: block; + float: left; + padding: 2px; + white-space: nowrap; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + overflow: hidden; + font-size: 16px; +} + +.mytheme .v-grid-cell.frozen { + position: relative; + z-index: 1; +} + +.mytheme .v-grid-spacer { + position: absolute; + display: block; + background-color: white; +} + +.mytheme .v-grid-spacer > td { + width: 100%; + height: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.v-ie8 .mytheme .v-grid-spacer, .v-ie9 .mytheme .v-grid-spacer { + margin-top: 0; +} + +.mytheme .v-grid { + outline: none; +} + +.mytheme .v-grid-scroller-vertical, .mytheme .v-grid-scroller-horizontal { + border: 1px solid #d4d4d4; +} + +.mytheme .v-grid-scroller-vertical { + border-left: none; +} + +.mytheme .v-grid-scroller-horizontal { + border-top: none; +} + +.mytheme .v-grid-tablewrapper { + border: 1px solid #d4d4d4; +} + +.mytheme .v-grid .header-drag-table { + border-spacing: 0; + position: relative; + table-layout: fixed; + width: inherit; +} + +.mytheme .v-grid .header-drag-table .v-grid-header { + position: absolute; +} + +.mytheme .v-grid .header-drag-table .v-grid-header > .v-grid-cell { + border: 1px solid #d4d4d4; + margin-top: -10px; + opacity: 0.9; + filter: alpha(opacity=90); + z-index: 30000; +} + +.mytheme .v-grid .header-drag-table .v-grid-header > .v-grid-drop-marker { + background-color: #197de1; + position: absolute; + width: 3px; +} + +.mytheme .v-grid-sidebar.v-contextmenu { + -webkit-box-shadow: none; + box-shadow: none; + border-radius: 0; + position: absolute; + top: 0; + right: 0; + background-color: #fafafa; + border: 1px solid #d4d4d4; + padding: 0; + z-index: 5; +} + +.mytheme .v-grid-sidebar.v-contextmenu.v-grid-sidebar-popup { + right: auto; +} + +.mytheme .v-grid-sidebar.v-contextmenu .v-grid-sidebar-button { + background: transparent; + border: none; + color: inherit; + cursor: pointer; + outline: none; + padding: 0 4px; + text-align: right; + line-height: 1; +} + +.mytheme .v-grid-sidebar.v-contextmenu .v-grid-sidebar-button[disabled] { + cursor: default; +} + +.mytheme .v-grid-sidebar.v-contextmenu .v-grid-sidebar-button::-moz-focus-inner { + border: 0; +} + +.mytheme .v-grid-sidebar.v-contextmenu .v-grid-sidebar-button:after { + content: "\f0c9"; + display: block; + font-family: ThemeIcons, sans-serif; + font-size: 14px; +} + +.mytheme .v-grid-sidebar.v-contextmenu.closed { + border-radius: 0; +} + +.mytheme .v-grid-sidebar.v-contextmenu.open .v-grid-sidebar-button { + width: 100%; +} + +.mytheme .v-grid-sidebar.v-contextmenu.open .v-grid-sidebar-button:after { + content: "\f0c9"; + font-size: 14px; + line-height: 1; +} + +.v-ie .mytheme .v-grid-sidebar.v-contextmenu.open .v-grid-sidebar-button { + vertical-align: middle; +} + +.v-ie8 .mytheme .v-grid-sidebar.v-contextmenu.open .v-grid-sidebar-button:after { + vertical-align: middle; + text-align: center; + display: inline; +} + +.mytheme .v-grid-sidebar.v-contextmenu .v-grid-sidebar-content { + padding: 4px 0; + overflow-y: auto; + overflow-x: hidden; +} + +.mytheme .v-grid-sidebar.v-contextmenu .v-grid-sidebar-content .gwt-MenuBar .gwt-MenuItem .column-hiding-toggle { + text-shadow: none; +} + +.mytheme .v-grid-cell { + background-color: white; + padding: 0 18px; + line-height: 37px; + text-overflow: ellipsis; +} + +.mytheme .v-grid-cell > * { + line-height: 1.55; + vertical-align: middle; +} + +.mytheme .v-grid-cell > div { + display: inline-block; +} + +.mytheme .v-grid-cell.frozen { + -webkit-box-shadow: 1px 0 2px rgba(0, 0, 0, 0.1); + box-shadow: 1px 0 2px rgba(0, 0, 0, 0.1); + border-right: 1px solid #d4d4d4; +} + +.mytheme .v-grid-cell.frozen + th, .mytheme .v-grid-cell.frozen + td { + border-left: none; +} + +.mytheme .v-grid-row > td, .mytheme .v-grid-editor-cells > div { + border-left: 1px solid #d4d4d4; + border-bottom: 1px solid #d4d4d4; +} + +.mytheme .v-grid-row > td:first-child, .mytheme .v-grid-editor-cells > div:first-child { + border-left: none; +} + +.mytheme .v-grid-editor-cells.frozen > div { + -webkit-box-shadow: 1px 0 2px rgba(0, 0, 0, 0.1); + box-shadow: 1px 0 2px rgba(0, 0, 0, 0.1); + border-right: 1px solid #d4d4d4; + border-left: none; +} + +.mytheme .v-grid-row-stripe > td { + background-color: #f5f5f5; +} + +.mytheme .v-grid-row-selected > td { + background: #197de1; +} + +.mytheme .v-grid-row-focused > td { + +} + +.mytheme .v-grid-header th { + position: relative; + background-color: #fafafa; + font-size: 14px; + font-weight: inherit; + border-left: 1px solid #d4d4d4; + border-bottom: 1px solid #d4d4d4; + + text-align: left; +} + +.mytheme .v-grid-header th:first-child { + border-left: none; +} + +.mytheme .v-grid-header .sort-asc, .mytheme .v-grid-header .sort-desc { + padding-right: 35px; +} + +.mytheme .v-grid-header .sort-asc:after, .mytheme .v-grid-header .sort-desc:after { + font-family: ThemeIcons, sans-serif; + content: "\f0de" " " attr(sort-order); + position: absolute; + right: 18px; + font-size: 12px; +} + +.mytheme .v-grid-header .sort-desc:after { + content: "\f0dd" " " attr(sort-order); +} + +.mytheme .v-grid-column-resize-handle { + position: absolute; + width: 36px; + right: -18px; + top: 0px; + bottom: 0px; + cursor: col-resize; + z-index: 10; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.mytheme .v-grid-column-resize-simple-indicator { + position: absolute; + width: 3px; + top: 0px; + left: 18px; + z-index: 9001; + background: #fff; + box-shadow: 0px 0px 5px #000; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.mytheme .v-grid-footer td { + background-color: #fafafa; + font-size: 14px; + font-weight: inherit; + border-left: 1px solid #d4d4d4; + border-top: 1px solid #d4d4d4; + border-bottom: none; + +} + +.mytheme .v-grid-footer td:first-child { + border-left: none; +} + +.mytheme .v-grid-header .v-grid-cell, .mytheme .v-grid-footer .v-grid-cell { + overflow: visible; +} + +.mytheme .v-grid-column-header-content, .mytheme .v-grid-column-footer-content { + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + line-height: 37px; + vertical-align: baseline; +} + +.mytheme .v-grid-header-deco { + border-top: 1px solid #d4d4d4; + border-right: 1px solid #d4d4d4; + background-color: #fafafa; +} + +.mytheme .v-grid-footer-deco { + border-bottom: 1px solid #d4d4d4; + border-right: 1px solid #d4d4d4; + background-color: #fafafa; +} + +.mytheme .v-grid-horizontal-scrollbar-deco { + background-color: #fafafa; + border: 1px solid #d4d4d4; + border-top: none; +} + +.mytheme .v-grid-cell-focused { + position: relative; +} + +.mytheme .v-grid-cell-focused:before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border: 2px solid #197de1; + display: none; + pointer-events: none; +} + +.ie8 .mytheme .v-grid-cell-focused:before, .ie9 .mytheme .v-grid-cell-focused:before, .ie10 .mytheme .v-grid-cell-focused:before { + content: url(data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==); +} + +.mytheme .v-grid:focus .v-grid-cell-focused:before { + display: block; +} + +.mytheme .v-grid.v-disabled:focus .v-grid-cell-focused:before { + display: none; +} + +.mytheme .v-grid-editor { + position: absolute; + z-index: 20; + overflow: hidden; + left: 0; + right: 0; + border: 1px solid #d4d4d4; + box-sizing: border-box; + -moz-box-sizing: border-box; + margin-top: -1px; + -webkit-box-shadow: 0 0 9px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 9px rgba(0, 0, 0, 0.2); +} + +.mytheme .v-grid-editor.unbuffered .v-grid-editor-footer { + width: 100%; +} + +.mytheme .v-grid-editor-cells { + position: relative; + white-space: nowrap; +} + +.mytheme .v-grid-editor-cells.frozen { + z-index: 2; +} + +.mytheme .v-grid-editor-cells > div { + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + vertical-align: middle; + background: white; +} + +.mytheme .v-grid-editor-cells > div:first-child { + border-left: none; +} + +.mytheme .v-grid-editor-cells > div > * { + vertical-align: middle; + display: inline-block; +} + +.mytheme .v-grid-editor-cells > div .v-filterselect { + padding-left: 0; +} + +.mytheme .v-grid-editor-cells > div input[type="text"], .mytheme .v-grid-editor-cells > div input[type="text"].v-filterselect-input, .mytheme .v-grid-editor-cells > div input[type="password"] { + padding-left: 18px; +} + +.mytheme .v-grid-editor-cells > div input[type="text"]:not(.v-filterselect-input), .mytheme .v-grid-editor-cells > div input[type="password"] { + padding-right: 9px; +} + +.mytheme .v-grid-editor-cells > div input[type="checkbox"] { + margin-left: 18px; +} + +.mytheme .v-grid-editor-cells > div .v-textfield, .mytheme .v-grid-editor-cells > div .v-datefield, .mytheme .v-grid-editor-cells > div .v-filterselect { + min-width: 100%; + max-width: 100%; + min-height: 100%; + max-height: 100%; +} + +.v-ie8 .mytheme .v-grid-editor-cells > div .v-datefield-button { + margin-left: -37px; +} + +.v-ie8 .mytheme .v-grid-editor-cells > div .v-filterselect-button { + margin-left: -25px; +} + +.mytheme .v-grid-editor-cells > div .v-select, .mytheme .v-grid-editor-cells > div .v-select-select { + min-width: 100%; + max-width: 100%; +} + +.mytheme .v-grid-editor-cells > div.not-editable.v-grid-cell { + float: none; +} + +.mytheme .v-grid-editor-cells .error::before { + position: absolute; + display: block; + height: 0; + width: 0; + content: ""; + border-top: 5px solid red; + border-right: 5px solid transparent; +} + +.mytheme .v-grid-editor-cells .error, .mytheme .v-grid-editor-cells .error > input { + background-color: #fee; +} + +.mytheme .v-grid-editor-footer { + display: table; + height: 37px; + border-top: 1px solid #d4d4d4; + margin-top: -1px; + background: white; + padding: 0 5px; +} + +.mytheme .v-grid-editor-footer + .v-grid-editor-cells > div { + border-bottom: none; + border-top: 1px solid #d4d4d4; +} + +.mytheme .v-grid-editor-footer:first-child { + border-top: none; + margin-top: 0; + border-bottom: 1px solid #d4d4d4; + margin-bottom: -1px; +} + +.mytheme .v-grid-editor-message, .mytheme .v-grid-editor-buttons { + display: table-cell; + white-space: nowrap; + vertical-align: middle; +} + +.mytheme .v-grid-editor-message { + width: 100%; + position: relative; +} + +.mytheme .v-grid-editor-message > div { + position: absolute; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + line-height: 37px; + top: 0; +} + +.mytheme .v-grid-editor-save { + margin-right: 4px; +} + +.mytheme .v-grid-spacer { + padding-left: 1px; +} + +.mytheme .v-grid-spacer > td { + display: block; + padding: 0; + background-color: white; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #d4d4d4; +} + +.mytheme .v-grid-spacer.stripe > td { + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + border-bottom: 1px solid #d4d4d4; +} + +.mytheme .v-grid-spacer-deco-container { + border-top: 1px solid transparent; + position: relative; + top: 0; + z-index: 5; +} + +.mytheme .v-grid-spacer-deco { + top: 0; + left: 0; + width: 2px; + background-color: #197de1; + position: absolute; + height: 100%; + pointer-events: none; +} + +.ie8 .mytheme .v-grid-spacer-deco:before, .ie9 .mytheme .v-grid-spacer-deco:before, .ie10 .mytheme .v-grid-spacer-deco:before { + content: url(data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==); +} + +.mytheme .v-grid-cell > .v-progressbar { + width: 100%; +} + +.mytheme .v-grid { + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + background-color: #fafafa; +} + +.mytheme .v-grid.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-grid-header .v-grid-cell { + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); +} + +.mytheme .v-grid-header .v-grid-cell.dragged { + opacity: 0.5; + filter: alpha(opacity=50) ; + -webkit-transition: opacity 0.3s ease-in-out; + -moz-transition: opacity 0.3s ease-in-out; + transition: opacity 0.3s ease-in-out; +} + +.mytheme .v-grid-header .v-grid-cell.dragged-column-header { + margin-top: -19px; +} + +.mytheme .v-grid-footer .v-grid-cell { + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); +} + +.mytheme .v-grid-header-deco { + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); +} + +.mytheme .v-grid-footer-deco, .mytheme .v-grid-horizontal-scrollbar-deco { + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); +} + +.mytheme .v-grid-row-selected > .v-grid-cell { + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + color: #c8dbed; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); + border-color: #1d69b4; +} + +.mytheme .v-grid-row-selected > .v-grid-cell-focused:before { + border-color: #71b0ef; +} + +.mytheme .v-grid-editor { + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + border-color: #197de1; +} + +.mytheme .v-grid-editor-footer { + font-size: 14px; + padding: 0 6px; + background: #fafafa; + -webkit-animation: valo-grid-editor-footer-animate-in 200ms 120ms backwards; + -moz-animation: valo-grid-editor-footer-animate-in 200ms 120ms backwards; + animation: valo-grid-editor-footer-animate-in 200ms 120ms backwards; +} + +.mytheme .v-grid-editor-footer:first-child { + -webkit-animation: valo-grid-editor-footer-animate-in-alt 200ms 120ms backwards; + -moz-animation: valo-grid-editor-footer-animate-in-alt 200ms 120ms backwards; + animation: valo-grid-editor-footer-animate-in-alt 200ms 120ms backwards; +} + +.mytheme .v-grid-editor-cells { + z-index: 1; +} + +.mytheme .v-grid-editor-cells > div:before { + content: ""; + display: inline-block; + height: 100%; + vertical-align: middle; +} + +.mytheme .v-grid-editor-cells > div.not-editable.v-grid-cell { + float: none; +} + +.mytheme .v-grid-editor-cells > div .error::before { + border-top: 9px solid #ed473b; + border-right: 9px solid transparent; +} + +.mytheme .v-grid-editor-cells > div .error, .mytheme .v-grid-editor-cells > div .error > input { + background-color: #fffbfb; +} + +.mytheme .v-grid-editor-cells > div .v-textfield, .mytheme .v-grid-editor-cells > div .v-textfield-focus, .mytheme .v-grid-editor-cells > div .v-datefield, .mytheme .v-grid-editor-cells > div .v-datefield .v-textfield-focus, .mytheme .v-grid-editor-cells > div .v-filterselect-input, .mytheme .v-grid-editor-cells > div .v-filterselect-input:focus { + border: none; + border-radius: 0; + background: transparent; + -webkit-box-shadow: inset 0 1px 0 #f2f2f2; + box-shadow: inset 0 1px 0 #f2f2f2; +} + +.mytheme .v-grid-editor-cells > div input[type="text"].v-datefield-textfield { + padding-left: 44.4px; +} + +.v-ie8 .mytheme .v-grid-editor-cells > div .v-datefield-button { + margin-left: 0px; +} + +.v-ie8 .mytheme .v-grid-editor-cells > div .v-filterselect-button { + margin-left: 0px; +} + +.mytheme .v-grid-editor-cells > div .v-textfield-focus, .mytheme .v-grid-editor-cells > div .v-datefield .v-textfield-focus, .mytheme .v-grid-editor-cells > div .v-filterselect-input:focus { + position: relative; +} + +.mytheme .v-grid-editor-cells > div .v-select { + padding-left: 9px; + padding-right: 9px; +} + +.mytheme .v-grid-editor-cells > div .v-checkbox { + margin: 0 9px 0 18px; +} + +.mytheme .v-grid-editor-cells > div .v-checkbox > input[type="checkbox"] { + margin-left: 0; +} + +.mytheme .v-grid-editor-cells > div .v-checkbox > label { + white-space: nowrap; +} + +.mytheme .v-grid-editor-message > div:before { + display: inline-block; + color: #ed473b; + font-weight: 600; + width: 19px; + text-align: center; + content: "!"; +} + +.mytheme .v-grid-editor-save, .mytheme .v-grid-editor-cancel { + cursor: pointer; + color: #197de1; + text-decoration: underline; + font-weight: inherit; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; + font-weight: 400; + text-decoration: none; + border: none; + background: transparent; + padding: 6px 6px; + margin: 0; + outline: none; +} + +.mytheme .v-grid-editor-save:hover, .mytheme .v-grid-editor-cancel:hover { + color: #4396ea; +} + +.mytheme .v-grid-editor-save.v-disabled, .mytheme .v-grid-editor-cancel.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-grid-spacer { + margin-top: -1px; +} + +.mytheme .v-grid-sidebar.v-contextmenu.open .v-grid-sidebar-content { + margin: 0 0 2px; + padding: 4px 4px 2px; + overflow-y: auto; + overflow-x: hidden; +} + +.mytheme .v-grid-sidebar.v-contextmenu.closed { + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); +} + +.mytheme .v-grid-scroller::-webkit-scrollbar { + border: none; +} + +.mytheme .v-grid-scroller::-webkit-scrollbar-thumb { + border-radius: 10px; + border: 4px solid transparent; + background: rgba(0, 0, 0, 0.3); + -webkit-background-clip: content-box; + background-clip: content-box; +} + +.mytheme .v-grid-scroller-vertical::-webkit-scrollbar-thumb { + min-height: 30px; +} + +.mytheme .v-grid-scroller-horizontal::-webkit-scrollbar-thumb { + min-width: 30px; +} + +.mytheme .v-textfield { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 37px; + border-radius: 4px; + padding: 4px 9px; + border: 1px solid #c5c5c5; + background: white; + color: #474747; + -webkit-box-shadow: inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + width: 185px; +} + +.v-ie8 .mytheme .v-textfield, .v-ie9 .mytheme .v-textfield { + line-height: 37px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-textfield.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-textfield:focus { + outline: none; + -webkit-transition: none; + -moz-transition: none; + transition: none; + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-textfield[class*="prompt"] { + color: #a3a3a3; +} + +.mytheme .v-textfield-readonly { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-textfield-readonly:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-textfield-error { + border-color: #ed473b !important; + background: #fffbfb; + color: #6c2621; +} + +.mytheme .v-textfield-borderless { + border: none; + border-radius: 0; + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; + color: inherit; +} + +.mytheme .v-textfield-borderless:focus { + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-textfield-borderless[class*="prompt"] { + color: inherit; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-textfield-tiny { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 28px; + border-radius: 4px; + padding: 3px 7px; + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + font-size: 12px; +} + +.v-ie8 .mytheme .v-textfield-tiny, .v-ie9 .mytheme .v-textfield-tiny { + line-height: 28px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-textfield-compact, .mytheme .v-textfield-small { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 31px; + border-radius: 4px; + padding: 3px 8px; + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; +} + +.v-ie8 .mytheme .v-textfield-compact, .v-ie9 .mytheme .v-textfield-compact, .v-ie8 .mytheme .v-textfield-small, .v-ie9 .mytheme .v-textfield-small { + line-height: 31px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-textfield-small { + font-size: 14px; +} + +.mytheme .v-textfield-large { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 44px; + border-radius: 4px; + padding: 5px 10px; + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + font-size: 20px; +} + +.v-ie8 .mytheme .v-textfield-large, .v-ie9 .mytheme .v-textfield-large { + line-height: 44px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-textfield-huge { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 59px; + border-radius: 4px; + padding: 7px 12px; + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + font-size: 26px; +} + +.v-ie8 .mytheme .v-textfield-huge, .v-ie9 .mytheme .v-textfield-huge { + line-height: 59px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-slot-inline-icon { + position: relative; +} + +.mytheme .v-caption-inline-icon { + padding: 0; +} + +.mytheme .v-caption-inline-icon .v-captiontext { + font-size: 14px; + font-weight: 400; + padding-bottom: 0.3em; + padding-left: 1px; + margin: 0; +} + +.mytheme .v-caption-inline-icon .v-icon { + position: absolute; + z-index: 10; +} + +.mytheme .v-caption-inline-icon span.v-icon { + left: 1px; + bottom: 1px; + width: 37px; + line-height: 35px; + text-align: center; + font-size: 16px; +} + +.mytheme .v-caption-inline-icon img.v-icon { + left: 11px; + bottom: 11px; +} + +.mytheme .v-textfield-inline-icon { + padding-left: 37px; +} + +.mytheme .v-slot-inline-icon.v-slot-tiny { + position: relative; +} + +.mytheme .v-caption-inline-icon.v-caption-tiny { + padding: 0; +} + +.mytheme .v-caption-inline-icon.v-caption-tiny .v-captiontext { + font-size: 14px; + font-weight: 400; + padding-bottom: 0.3em; + padding-left: 1px; + margin: 0; +} + +.mytheme .v-caption-inline-icon.v-caption-tiny .v-icon { + position: absolute; + z-index: 10; +} + +.mytheme .v-caption-inline-icon.v-caption-tiny span.v-icon { + left: 1px; + bottom: 1px; + width: 28px; + line-height: 26px; + text-align: center; + font-size: 12px; +} + +.mytheme .v-caption-inline-icon.v-caption-tiny img.v-icon { + left: 6px; + bottom: 6px; +} + +.mytheme .v-textfield-inline-icon.v-textfield-tiny { + padding-left: 28px; +} + +.mytheme .v-slot-inline-icon.v-slot-compact { + position: relative; +} + +.mytheme .v-caption-inline-icon.v-caption-compact { + padding: 0; +} + +.mytheme .v-caption-inline-icon.v-caption-compact .v-captiontext { + font-size: 14px; + font-weight: 400; + padding-bottom: 0.3em; + padding-left: 1px; + margin: 0; +} + +.mytheme .v-caption-inline-icon.v-caption-compact .v-icon { + position: absolute; + z-index: 10; +} + +.mytheme .v-caption-inline-icon.v-caption-compact span.v-icon { + left: 1px; + bottom: 1px; + width: 31px; + line-height: 29px; + text-align: center; + font-size: 16px; +} + +.mytheme .v-caption-inline-icon.v-caption-compact img.v-icon { + left: 8px; + bottom: 8px; +} + +.mytheme .v-textfield-inline-icon.v-textfield-compact { + padding-left: 31px; +} + +.mytheme .v-slot-inline-icon.v-slot-small { + position: relative; +} + +.mytheme .v-caption-inline-icon.v-caption-small { + padding: 0; +} + +.mytheme .v-caption-inline-icon.v-caption-small .v-captiontext { + font-size: 14px; + font-weight: 400; + padding-bottom: 0.3em; + padding-left: 1px; + margin: 0; +} + +.mytheme .v-caption-inline-icon.v-caption-small .v-icon { + position: absolute; + z-index: 10; +} + +.mytheme .v-caption-inline-icon.v-caption-small span.v-icon { + left: 1px; + bottom: 1px; + width: 31px; + line-height: 29px; + text-align: center; + font-size: 14px; +} + +.mytheme .v-caption-inline-icon.v-caption-small img.v-icon { + left: 8px; + bottom: 8px; +} + +.mytheme .v-textfield-inline-icon.v-textfield-small { + padding-left: 31px; +} + +.mytheme .v-slot-inline-icon.v-slot-large { + position: relative; +} + +.mytheme .v-caption-inline-icon.v-caption-large { + padding: 0; +} + +.mytheme .v-caption-inline-icon.v-caption-large .v-captiontext { + font-size: 14px; + font-weight: 400; + padding-bottom: 0.3em; + padding-left: 1px; + margin: 0; +} + +.mytheme .v-caption-inline-icon.v-caption-large .v-icon { + position: absolute; + z-index: 10; +} + +.mytheme .v-caption-inline-icon.v-caption-large span.v-icon { + left: 1px; + bottom: 1px; + width: 44px; + line-height: 42px; + text-align: center; + font-size: 20px; +} + +.mytheme .v-caption-inline-icon.v-caption-large img.v-icon { + left: 14px; + bottom: 14px; +} + +.mytheme .v-textfield-inline-icon.v-textfield-large { + padding-left: 44px; +} + +.mytheme .v-slot-inline-icon.v-slot-huge { + position: relative; +} + +.mytheme .v-caption-inline-icon.v-caption-huge { + padding: 0; +} + +.mytheme .v-caption-inline-icon.v-caption-huge .v-captiontext { + font-size: 14px; + font-weight: 400; + padding-bottom: 0.3em; + padding-left: 1px; + margin: 0; +} + +.mytheme .v-caption-inline-icon.v-caption-huge .v-icon { + position: absolute; + z-index: 10; +} + +.mytheme .v-caption-inline-icon.v-caption-huge span.v-icon { + left: 1px; + bottom: 1px; + width: 59px; + line-height: 57px; + text-align: center; + font-size: 26px; +} + +.mytheme .v-caption-inline-icon.v-caption-huge img.v-icon { + left: 22px; + bottom: 22px; +} + +.mytheme .v-textfield-inline-icon.v-textfield-huge { + padding-left: 59px; +} + +.mytheme .v-textfield-align-right { + text-align: right; +} + +.mytheme .v-textfield-align-center { + text-align: center; +} + +.mytheme .v-textarea { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 37px; + border-radius: 4px; + padding: 6px; + border: 1px solid #c5c5c5; + background: white; + color: #474747; + -webkit-box-shadow: inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + height: auto; + resize: none; + white-space: pre-wrap; + width: 185px; +} + +.v-ie8 .mytheme .v-textarea, .v-ie9 .mytheme .v-textarea { + line-height: 37px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-textarea.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-textarea:focus { + outline: none; + -webkit-transition: none; + -moz-transition: none; + transition: none; + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-textarea[class*="prompt"] { + color: #a3a3a3; +} + +.v-ie8 .mytheme .v-textarea, .v-ie9 .mytheme .v-textarea { + line-height: inherit; + padding-top: 4px; + padding-bottom: 4px; +} + +.mytheme .v-textarea-readonly { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-textarea-readonly:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-textarea-error { + border-color: #ed473b !important; + background: #fffbfb; + color: #6c2621; +} + +.mytheme .v-textarea-borderless { + border: none; + border-radius: 0; + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; + color: inherit; +} + +.mytheme .v-textarea-borderless:focus { + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-textarea-borderless[class*="prompt"] { + color: inherit; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-textarea-tiny { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 28px; + border-radius: 4px; + padding: 6px; + + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + height: auto; + resize: none; + white-space: pre-wrap; + font-size: 12px; +} + +.v-ie8 .mytheme .v-textarea-tiny, .v-ie9 .mytheme .v-textarea-tiny { + line-height: 28px; + padding-top: 0; + padding-bottom: 0; +} + +.v-ie8 .mytheme .v-textarea-tiny, .v-ie9 .mytheme .v-textarea-tiny { + line-height: inherit; + padding-top: 3px; + padding-bottom: 3px; +} + +.mytheme .v-textarea-small { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 31px; + border-radius: 4px; + padding: 6px; + + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + height: auto; + resize: none; + white-space: pre-wrap; + font-size: 14px; +} + +.v-ie8 .mytheme .v-textarea-small, .v-ie9 .mytheme .v-textarea-small { + line-height: 31px; + padding-top: 0; + padding-bottom: 0; +} + +.v-ie8 .mytheme .v-textarea-small, .v-ie9 .mytheme .v-textarea-small { + line-height: inherit; + padding-top: 3px; + padding-bottom: 3px; +} + +.mytheme .v-textarea-large { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 44px; + border-radius: 4px; + padding: 6px; + + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + height: auto; + resize: none; + white-space: pre-wrap; + font-size: 20px; +} + +.v-ie8 .mytheme .v-textarea-large, .v-ie9 .mytheme .v-textarea-large { + line-height: 44px; + padding-top: 0; + padding-bottom: 0; +} + +.v-ie8 .mytheme .v-textarea-large, .v-ie9 .mytheme .v-textarea-large { + line-height: inherit; + padding-top: 5px; + padding-bottom: 5px; +} + +.mytheme .v-textarea-huge { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 59px; + border-radius: 4px; + padding: 6px; + + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + height: auto; + resize: none; + white-space: pre-wrap; + font-size: 26px; +} + +.v-ie8 .mytheme .v-textarea-huge, .v-ie9 .mytheme .v-textarea-huge { + line-height: 59px; + padding-top: 0; + padding-bottom: 0; +} + +.v-ie8 .mytheme .v-textarea-huge, .v-ie9 .mytheme .v-textarea-huge { + line-height: inherit; + padding-top: 7px; + padding-bottom: 7px; +} + +.mytheme .v-textarea-align-right { + text-align: right; +} + +.mytheme .v-textarea-align-center { + text-align: center; +} + +.mytheme .v-datefield { + position: relative; + width: 185px; + height: 37px; + border-radius: 4px; +} + +.mytheme .v-datefield [class*="textfield"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 37px; + border-radius: 4px; + padding: 4px 9px; + border: 1px solid #c5c5c5; + background: white; + color: #474747; + -webkit-box-shadow: inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + padding-left: 44.4px; + width: 100%; + height: 100%; + border-radius: inherit; +} + +.v-ie8 .mytheme .v-datefield [class*="textfield"], .v-ie9 .mytheme .v-datefield [class*="textfield"] { + line-height: 37px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-datefield [class*="textfield"].v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-datefield [class*="textfield"]:focus { + outline: none; + -webkit-transition: none; + -moz-transition: none; + transition: none; + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-datefield [class*="textfield"][class*="prompt"] { + color: #a3a3a3; +} + +.mytheme .v-datefield[class*="prompt"] > [class*="textfield"] { + color: #a3a3a3; +} + +.mytheme .v-datefield [class*="button"] { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + -webkit-appearance: none; + background: transparent; + padding: 0; + position: absolute; + z-index: 10; + width: 37px; + line-height: 35px; + text-align: center; + font: inherit; + outline: none; + margin: 0; + top: 1px; + bottom: 1px; + left: 1px; + border: none; + border-right: 1px solid #e4e4e4; + color: #a3a3a3; + border-radius: 3px 0 0 3px; +} + +.mytheme .v-datefield [class*="button"]:hover { + color: #474747; +} + +.mytheme .v-datefield [class*="button"]:before { + font-family: ThemeIcons; + content: "\f073"; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme .v-datefield [class*="button"]:active:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: rgba(128, 128, 128, 0.2); + border-radius: inherit; +} + +.mytheme .v-datefield.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-datefield.v-disabled [class*="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-datefield.v-disabled [class*="button"]:active:after { + display: none; +} + +.mytheme .v-datefield.v-readonly [class*="textfield"] { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-datefield.v-readonly [class*="textfield"]:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-datefield.v-readonly [class*="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-datefield.v-readonly [class*="button"]:active:after { + display: none; +} + +.mytheme .v-datefield-error .v-datefield-textfield { + border-color: #ed473b !important; + background: #fffbfb; + color: #6c2621; +} + +.mytheme .v-datefield-error .v-datefield-button { + color: #ed473b; + border-color: #ed473b; +} + +.mytheme .v-datefield-full { + width: 240px; +} + +.mytheme .v-datefield-day { + width: 185px; +} + +.mytheme .v-datefield-month { + width: 120px; +} + +.mytheme .v-datefield-year { + width: 104px; +} + +.mytheme .v-datefield-popup { + padding: 4px 4px; + border-radius: 4px; + background-color: white; + color: #474747; + -webkit-box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + backface-visibility: hidden; + margin-top: 5px !important; + margin-bottom: 5px !important; + margin-right: 5px !important; + cursor: default; + width: auto; +} + +.mytheme .v-datefield-popup[class*="animate-in"] { + -webkit-animation: valo-overlay-animate-in 120ms; + -moz-animation: valo-overlay-animate-in 120ms; + animation: valo-overlay-animate-in 120ms; +} + +.mytheme .v-datefield-popup[class*="animate-out"] { + -webkit-animation: valo-animate-out-fade 120ms; + -moz-animation: valo-animate-out-fade 120ms; + animation: valo-animate-out-fade 120ms; +} + +.mytheme .v-datefield-popup table { + border-collapse: collapse; + border-spacing: 0; + margin: 0 auto; +} + +.mytheme .v-datefield-popup td { + padding: 2px; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel { + font-size: 16px; + text-align: center; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel:focus { + outline: none; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-day { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 30px; + height: 26px; + border: 1px solid transparent; + line-height: 26px; + text-align: center; + font-size: 14px; + background: #fafafa; + border-radius: 2px; + -webkit-transition: color 200ms; + -moz-transition: color 200ms; + transition: color 200ms; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-day:hover { + color: #197de1; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-day-offmonth { + color: #a0a0a0; + background: transparent; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-day-today { + color: #191919; + font-weight: 600; + border-color: #afafaf; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-selected, .mytheme .v-datefield-popup .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-selected:hover { + color: #c8dbed; + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + border: none; + font-weight: 600; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-focused { + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + position: relative; +} + +.v-ie8 .mytheme .v-datefield-popup .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-focused { + border-color: #197de1; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-outside-range, .mytheme .v-datefield-popup .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-outside-range:hover { + color: #a0a0a0; + cursor: not-allowed; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-weekdays { + height: 26px; + color: rgba(133, 133, 133, 0.85); +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-weekdays strong { + font: inherit; + font-size: 14px; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-header { + white-space: nowrap; +} + +.mytheme .v-datefield-popup td[class*="year"] button, .mytheme .v-datefield-popup td[class*="month"] button { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + border: none; + background: transparent; + padding: 0; + margin: 0; + cursor: pointer; + color: transparent; + font-size: 0; + width: 19px; + height: 25px; + outline: none; + position: relative; + vertical-align: middle; +} + +.mytheme .v-datefield-popup td[class*="year"] button:before, .mytheme .v-datefield-popup td[class*="month"] button:before { + color: #a0a0a0; + font-size: 21px; + line-height: 24px; + -webkit-transition: color 200ms; + -moz-transition: color 200ms; + transition: color 200ms; +} + +.mytheme .v-datefield-popup td[class*="year"] button:hover:before, .mytheme .v-datefield-popup td[class*="month"] button:hover:before { + color: #197de1; +} + +.mytheme .v-datefield-popup td[class*="year"] button.outside-range, .mytheme .v-datefield-popup td[class*="month"] button.outside-range { + cursor: default; + opacity: 0.3; + filter: alpha(opacity=30.0) ; +} + +.mytheme .v-datefield-popup td[class*="year"] button.outside-range:hover:before, .mytheme .v-datefield-popup td[class*="month"] button.outside-range:hover:before { + color: #a0a0a0; +} + +.mytheme .v-datefield-popup .v-button-prevyear:before { + font-family: ThemeIcons; + content: "\f100"; +} + +.mytheme .v-datefield-popup .v-button-prevmonth:before { + font-family: ThemeIcons; + content: "\f104"; +} + +.mytheme .v-datefield-popup .v-button-nextyear:before { + font-family: ThemeIcons; + content: "\f101"; +} + +.mytheme .v-datefield-popup .v-button-nextmonth:before { + font-family: ThemeIcons; + content: "\f105"; +} + +.mytheme .v-datefield-popup td.v-datefield-calendarpanel-month { + width: 148px; + color: #197de1; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-year td.v-datefield-calendarpanel-month { + width: 74px; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-weeknumber, .mytheme .v-datefield-popup .v-datefield-calendarpanel-weekdays.v-datefield-calendarpanel-weeknumbers td:first-child { + width: 30px; + color: rgba(133, 133, 133, 0.85); + font-size: 14px; + display: inline-block; + text-align: left; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-weeknumber { + position: relative; +} + +.mytheme .v-datefield-popup .v-datefield-calendarpanel-weeknumbers .v-first:before { + content: ""; + position: absolute; + top: 38px; + bottom: 0; + left: 0; + width: 34px; + border-top: 1px solid #eaeaea; + border-right: 1px solid #eaeaea; + border-top-right-radius: 4px; + border-bottom-left-radius: 4px; + background: #fafafa; +} + +.mytheme .v-datefield-popup td.v-datefield-calendarpanel-time { + width: 100%; + font-size: 14px; +} + +.mytheme .v-datefield-popup td.v-datefield-calendarpanel-time .v-label { + display: inline; + margin: 0 0.1em; + font-weight: 400; +} + +.mytheme .v-datefield-calendarpanel { + font-size: 16px; + text-align: center; +} + +.mytheme .v-datefield-calendarpanel:focus { + outline: none; +} + +.mytheme .v-datefield-calendarpanel-day { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 30px; + height: 26px; + border: 1px solid transparent; + line-height: 26px; + text-align: center; + font-size: 14px; + background: #fafafa; + border-radius: 2px; + -webkit-transition: color 200ms; + -moz-transition: color 200ms; + transition: color 200ms; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer; +} + +.mytheme .v-datefield-calendarpanel-day:hover { + color: #197de1; +} + +.mytheme .v-datefield-calendarpanel-day-offmonth { + color: #a0a0a0; + background: transparent; +} + +.mytheme .v-datefield-calendarpanel-day-today { + color: #191919; + font-weight: 600; + border-color: #afafaf; +} + +.mytheme .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-selected, .mytheme .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-selected:hover { + color: #c8dbed; + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + border: none; + font-weight: 600; +} + +.mytheme .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-focused { + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + position: relative; +} + +.v-ie8 .mytheme .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-focused { + border-color: #197de1; +} + +.mytheme .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-outside-range, .mytheme .v-datefield-calendarpanel-day.v-datefield-calendarpanel-day-outside-range:hover { + color: #a0a0a0; + cursor: not-allowed; +} + +.mytheme .v-datefield-calendarpanel-weekdays { + height: 26px; + color: rgba(133, 133, 133, 0.85); +} + +.mytheme .v-datefield-calendarpanel-weekdays strong { + font: inherit; + font-size: 14px; +} + +.mytheme .v-datefield-calendarpanel-header { + white-space: nowrap; +} + +.mytheme td[class*="year"] button, .mytheme td[class*="month"] button { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + border: none; + background: transparent; + padding: 0; + margin: 0; + cursor: pointer; + color: transparent; + font-size: 0; + width: 19px; + height: 25px; + outline: none; + position: relative; + vertical-align: middle; +} + +.mytheme td[class*="year"] button:before, .mytheme td[class*="month"] button:before { + color: #a0a0a0; + font-size: 21px; + line-height: 24px; + -webkit-transition: color 200ms; + -moz-transition: color 200ms; + transition: color 200ms; +} + +.mytheme td[class*="year"] button:hover:before, .mytheme td[class*="month"] button:hover:before { + color: #197de1; +} + +.mytheme td[class*="year"] button.outside-range, .mytheme td[class*="month"] button.outside-range { + cursor: default; + opacity: 0.3; + filter: alpha(opacity=30.0) ; +} + +.mytheme td[class*="year"] button.outside-range:hover:before, .mytheme td[class*="month"] button.outside-range:hover:before { + color: #a0a0a0; +} + +.mytheme .v-button-prevyear:before { + font-family: ThemeIcons; + content: "\f100"; +} + +.mytheme .v-button-prevmonth:before { + font-family: ThemeIcons; + content: "\f104"; +} + +.mytheme .v-button-nextyear:before { + font-family: ThemeIcons; + content: "\f101"; +} + +.mytheme .v-button-nextmonth:before { + font-family: ThemeIcons; + content: "\f105"; +} + +.mytheme td.v-datefield-calendarpanel-month { + width: 148px; + color: #197de1; +} + +.mytheme .v-datefield-calendarpanel-year td.v-datefield-calendarpanel-month { + width: 74px; +} + +.mytheme .v-datefield-calendarpanel-weeknumber, .mytheme .v-datefield-calendarpanel-weekdays.v-datefield-calendarpanel-weeknumbers td:first-child { + width: 30px; + color: rgba(133, 133, 133, 0.85); + font-size: 14px; + display: inline-block; + text-align: left; +} + +.mytheme .v-datefield-calendarpanel-weeknumber { + position: relative; +} + +.mytheme .v-datefield-calendarpanel-weeknumbers .v-first:before { + content: ""; + position: absolute; + top: 38px; + bottom: 0; + left: 0; + width: 34px; + border-top: 1px solid #eaeaea; + border-right: 1px solid #eaeaea; + border-top-right-radius: 4px; + border-bottom-left-radius: 4px; + background: #fafafa; +} + +.mytheme td.v-datefield-calendarpanel-time { + width: 100%; + font-size: 14px; +} + +.mytheme td.v-datefield-calendarpanel-time .v-label { + display: inline; + margin: 0 0.1em; + font-weight: 400; +} + +.mytheme .v-datefield-borderless .v-datefield-textfield { + border: none; + border-radius: 0; + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; + color: inherit; +} + +.mytheme .v-datefield-borderless .v-datefield-textfield:focus { + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-datefield-borderless .v-datefield-textfield[class*="prompt"] { + color: inherit; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-datefield-borderless .v-datefield-button { + border: none; + color: inherit; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-datefield-align-right input { + text-align: right; +} + +.mytheme .v-datefield-align-center input { + text-align: center; +} + +.mytheme .v-datefield-tiny { + height: 28px; + border-radius: 4px; + font-size: 12px; +} + +.mytheme .v-datefield-tiny [class*="textfield"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 28px; + border-radius: 4px; + padding: 3px 7px; + + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + padding-left: 33.6px; + width: 100%; + height: 100%; + border-radius: inherit; +} + +.v-ie8 .mytheme .v-datefield-tiny [class*="textfield"], .v-ie9 .mytheme .v-datefield-tiny [class*="textfield"] { + line-height: 28px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-datefield-tiny [class*="button"] { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + -webkit-appearance: none; + background: transparent; + padding: 0; + position: absolute; + z-index: 10; + width: 28px; + line-height: 28px; + text-align: center; + font: inherit; + outline: none; + margin: 0; + border-radius: 4px 0 0 4px; +} + +.mytheme .v-datefield-tiny [class*="button"]:before { + font-family: ThemeIcons; + content: "\f073"; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme .v-datefield-tiny [class*="button"]:active:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; +} + +.mytheme .v-datefield-tiny.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-datefield-tiny.v-disabled [class*="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-datefield-tiny.v-disabled [class*="button"]:active:after { + display: none; +} + +.mytheme .v-datefield-tiny.v-readonly [class*="textfield"] { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-datefield-tiny.v-readonly [class*="textfield"]:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-datefield-tiny.v-readonly [class*="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-datefield-tiny.v-readonly [class*="button"]:active:after { + display: none; +} + +.mytheme .v-datefield-compact, .mytheme .v-datefield-small { + height: 31px; + border-radius: 4px; +} + +.mytheme .v-datefield-compact [class*="textfield"], .mytheme .v-datefield-small [class*="textfield"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 31px; + border-radius: 4px; + padding: 3px 8px; + + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + padding-left: 37.2px; + width: 100%; + height: 100%; + border-radius: inherit; +} + +.v-ie8 .mytheme .v-datefield-compact [class*="textfield"], .v-ie9 .mytheme .v-datefield-compact [class*="textfield"], .v-ie8 .mytheme .v-datefield-small [class*="textfield"], .v-ie9 .mytheme .v-datefield-small [class*="textfield"] { + line-height: 31px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-datefield-compact [class*="button"], .mytheme .v-datefield-small [class*="button"] { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + -webkit-appearance: none; + background: transparent; + padding: 0; + position: absolute; + z-index: 10; + width: 31px; + line-height: 31px; + text-align: center; + font: inherit; + outline: none; + margin: 0; + border-radius: 4px 0 0 4px; +} + +.mytheme .v-datefield-compact [class*="button"]:before, .mytheme .v-datefield-small [class*="button"]:before { + font-family: ThemeIcons; + content: "\f073"; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme .v-datefield-compact [class*="button"]:active:after, .mytheme .v-datefield-small [class*="button"]:active:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; +} + +.mytheme .v-datefield-compact.v-disabled, .mytheme .v-datefield-small.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-datefield-compact.v-disabled [class*="button"], .mytheme .v-datefield-small.v-disabled [class*="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-datefield-compact.v-disabled [class*="button"]:active:after, .mytheme .v-datefield-small.v-disabled [class*="button"]:active:after { + display: none; +} + +.mytheme .v-datefield-compact.v-readonly [class*="textfield"], .mytheme .v-datefield-small.v-readonly [class*="textfield"] { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-datefield-compact.v-readonly [class*="textfield"]:focus, .mytheme .v-datefield-small.v-readonly [class*="textfield"]:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-datefield-compact.v-readonly [class*="button"], .mytheme .v-datefield-small.v-readonly [class*="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-datefield-compact.v-readonly [class*="button"]:active:after, .mytheme .v-datefield-small.v-readonly [class*="button"]:active:after { + display: none; +} + +.mytheme .v-datefield-small { + font-size: 14px; +} + +.mytheme .v-datefield-large { + height: 44px; + border-radius: 4px; + font-size: 20px; +} + +.mytheme .v-datefield-large [class*="textfield"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 44px; + border-radius: 4px; + padding: 5px 10px; + + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + padding-left: 52.8px; + width: 100%; + height: 100%; + border-radius: inherit; +} + +.v-ie8 .mytheme .v-datefield-large [class*="textfield"], .v-ie9 .mytheme .v-datefield-large [class*="textfield"] { + line-height: 44px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-datefield-large [class*="button"] { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + -webkit-appearance: none; + background: transparent; + padding: 0; + position: absolute; + z-index: 10; + width: 44px; + line-height: 44px; + text-align: center; + font: inherit; + outline: none; + margin: 0; + border-radius: 4px 0 0 4px; +} + +.mytheme .v-datefield-large [class*="button"]:before { + font-family: ThemeIcons; + content: "\f073"; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme .v-datefield-large [class*="button"]:active:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; +} + +.mytheme .v-datefield-large.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-datefield-large.v-disabled [class*="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-datefield-large.v-disabled [class*="button"]:active:after { + display: none; +} + +.mytheme .v-datefield-large.v-readonly [class*="textfield"] { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-datefield-large.v-readonly [class*="textfield"]:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-datefield-large.v-readonly [class*="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-datefield-large.v-readonly [class*="button"]:active:after { + display: none; +} + +.mytheme .v-datefield-huge { + height: 59px; + border-radius: 4px; + font-size: 26px; +} + +.mytheme .v-datefield-huge [class*="textfield"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 59px; + border-radius: 4px; + padding: 7px 12px; + + + + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + padding-left: 70.8px; + width: 100%; + height: 100%; + border-radius: inherit; +} + +.v-ie8 .mytheme .v-datefield-huge [class*="textfield"], .v-ie9 .mytheme .v-datefield-huge [class*="textfield"] { + line-height: 59px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-datefield-huge [class*="button"] { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + -webkit-appearance: none; + background: transparent; + padding: 0; + position: absolute; + z-index: 10; + width: 59px; + line-height: 59px; + text-align: center; + font: inherit; + outline: none; + margin: 0; + border-radius: 4px 0 0 4px; +} + +.mytheme .v-datefield-huge [class*="button"]:before { + font-family: ThemeIcons; + content: "\f073"; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme .v-datefield-huge [class*="button"]:active:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; +} + +.mytheme .v-datefield-huge.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-datefield-huge.v-disabled [class*="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-datefield-huge.v-disabled [class*="button"]:active:after { + display: none; +} + +.mytheme .v-datefield-huge.v-readonly [class*="textfield"] { + background: #fafafa; + color: #464646; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-datefield-huge.v-readonly [class*="textfield"]:focus { + box-shadow: none; + border-color: #c5c5c5; +} + +.mytheme .v-datefield-huge.v-readonly [class*="button"] { + cursor: default; + pointer-events: none; +} + +.mytheme .v-datefield-huge.v-readonly [class*="button"]:active:after { + display: none; +} + +.mytheme .v-inline-datefield-calendarpanel { + font-size: 16px; + text-align: center; +} + +.mytheme .v-inline-datefield-calendarpanel:focus { + outline: none; +} + +.mytheme .v-inline-datefield-calendarpanel-day { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 30px; + height: 26px; + border: 1px solid transparent; + line-height: 26px; + text-align: center; + font-size: 14px; + background: #fafafa; + border-radius: 2px; + -webkit-transition: color 200ms; + -moz-transition: color 200ms; + transition: color 200ms; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer; +} + +.mytheme .v-inline-datefield-calendarpanel-day:hover { + color: #197de1; +} + +.mytheme .v-inline-datefield-calendarpanel-day-offmonth { + color: #a0a0a0; + background: transparent; +} + +.mytheme .v-inline-datefield-calendarpanel-day-today { + color: #191919; + font-weight: 600; + border-color: #afafaf; +} + +.mytheme .v-inline-datefield-calendarpanel-day.v-inline-datefield-calendarpanel-day-selected, .mytheme .v-inline-datefield-calendarpanel-day.v-inline-datefield-calendarpanel-day-selected:hover { + color: #c8dbed; + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + border: none; + font-weight: 600; +} + +.mytheme .v-inline-datefield-calendarpanel-day.v-inline-datefield-calendarpanel-day-focused { + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + position: relative; +} + +.v-ie8 .mytheme .v-inline-datefield-calendarpanel-day.v-inline-datefield-calendarpanel-day-focused { + border-color: #197de1; +} + +.mytheme .v-inline-datefield-calendarpanel-day.v-inline-datefield-calendarpanel-day-outside-range, .mytheme .v-inline-datefield-calendarpanel-day.v-inline-datefield-calendarpanel-day-outside-range:hover { + color: #a0a0a0; + cursor: not-allowed; +} + +.mytheme .v-inline-datefield-calendarpanel-weekdays { + height: 26px; + color: rgba(133, 133, 133, 0.85); +} + +.mytheme .v-inline-datefield-calendarpanel-weekdays strong { + font: inherit; + font-size: 14px; +} + +.mytheme .v-inline-datefield-calendarpanel-header { + white-space: nowrap; +} + +.mytheme td[class*="year"] button, .mytheme td[class*="month"] button { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + border: none; + background: transparent; + padding: 0; + margin: 0; + cursor: pointer; + color: transparent; + font-size: 0; + width: 19px; + height: 25px; + outline: none; + position: relative; + vertical-align: middle; +} + +.mytheme td[class*="year"] button:before, .mytheme td[class*="month"] button:before { + color: #a0a0a0; + font-size: 21px; + line-height: 24px; + -webkit-transition: color 200ms; + -moz-transition: color 200ms; + transition: color 200ms; +} + +.mytheme td[class*="year"] button:hover:before, .mytheme td[class*="month"] button:hover:before { + color: #197de1; +} + +.mytheme td[class*="year"] button.outside-range, .mytheme td[class*="month"] button.outside-range { + cursor: default; + opacity: 0.3; + filter: alpha(opacity=30.0) ; +} + +.mytheme td[class*="year"] button.outside-range:hover:before, .mytheme td[class*="month"] button.outside-range:hover:before { + color: #a0a0a0; +} + +.mytheme .v-button-prevyear:before { + font-family: ThemeIcons; + content: "\f100"; +} + +.mytheme .v-button-prevmonth:before { + font-family: ThemeIcons; + content: "\f104"; +} + +.mytheme .v-button-nextyear:before { + font-family: ThemeIcons; + content: "\f101"; +} + +.mytheme .v-button-nextmonth:before { + font-family: ThemeIcons; + content: "\f105"; +} + +.mytheme td.v-inline-datefield-calendarpanel-month { + width: 148px; + color: #197de1; +} + +.mytheme .v-inline-datefield-calendarpanel-year td.v-inline-datefield-calendarpanel-month { + width: 74px; +} + +.mytheme .v-inline-datefield-calendarpanel-weeknumber, .mytheme .v-inline-datefield-calendarpanel-weekdays.v-inline-datefield-calendarpanel-weeknumbers td:first-child { + width: 30px; + color: rgba(133, 133, 133, 0.85); + font-size: 14px; + display: inline-block; + text-align: left; +} + +.mytheme .v-inline-datefield-calendarpanel-weeknumber { + position: relative; +} + +.mytheme .v-inline-datefield-calendarpanel-weeknumbers .v-first:before { + content: ""; + position: absolute; + top: 38px; + bottom: 0; + left: 0; + width: 34px; + border-top: 1px solid #eaeaea; + border-right: 1px solid #eaeaea; + border-top-right-radius: 4px; + border-bottom-left-radius: 4px; + background: #fafafa; +} + +.mytheme td.v-inline-datefield-calendarpanel-time { + width: 100%; + font-size: 14px; +} + +.mytheme td.v-inline-datefield-calendarpanel-time .v-label { + display: inline; + margin: 0 0.1em; + font-weight: 400; +} + +.mytheme .v-inline-datefield-calendarpanel { + position: relative; + background: white; + padding: 6px; +} + +.mytheme .v-gridlayout-margin-top { + padding-top: 37px; +} + +.mytheme .v-gridlayout-margin-bottom { + padding-bottom: 37px; +} + +.mytheme .v-gridlayout-margin-left { + padding-left: 37px; +} + +.mytheme .v-gridlayout-margin-right { + padding-right: 37px; +} + +.mytheme .v-gridlayout-spacing-on { + padding-left: 12px; + padding-top: 12px; +} + +.mytheme .v-menubar { + position: relative; + text-align: center; + white-space: nowrap; + outline: none; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + height: 37px; + padding: 0 16px; + color: #191919; + font-weight: 400; + + cursor: default; + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + padding: 0; + text-align: left; + line-height: 35px; +} + +.mytheme .v-menubar:after { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; +} + +.mytheme .v-menubar:focus:after { + -webkit-transition: none; + -moz-transition: none; + transition: none; +} + +.mytheme .v-menubar.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-menubar.v-disabled:after { + display: none; +} + +.mytheme .v-menubar:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-menubar:focus:after { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-menubar > .v-menubar-menuitem { + padding: 0 14px; +} + +.mytheme .v-menubar > .v-menubar-menuitem[class*="-icon-only"] { + width: 37px; +} + +.mytheme .v-menubar:active:after { + background: transparent; +} + +.mytheme .v-menubar > .v-menubar-menuitem { + position: relative; + z-index: 1; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + height: 37px; + padding: 0 15px; + color: inherit; + font-weight: 400; + + cursor: pointer; + border-radius: 0; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7; + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7; + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; + border-width: 0 1px 0 0; + border-color: inherit; + height: 100%; + line-height: inherit; + vertical-align: top; + text-align: center; +} + +.mytheme .v-menubar > .v-menubar-menuitem:first-child { + border-left-width: 0; + border-radius: 3px 0 0 3px; +} + +.mytheme .v-menubar > .v-menubar-menuitem:last-child { + border-radius: 0 3px 3px 0; + border-right-width: 0; +} + +.mytheme .v-menubar > .v-menubar-menuitem:first-child:last-child { + border-radius: 3px; +} + +.mytheme .v-menubar > .v-menubar-menuitem:before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; +} + +.mytheme .v-menubar > .v-menubar-menuitem:hover { + zoom: 1; +} + +.mytheme .v-menubar > .v-menubar-menuitem:hover:before { + background-color: rgba(186, 186, 186, 0.1); + border: none; +} + +.mytheme .v-menubar > .v-menubar-menuitem:active:before { + background-color: rgba(125, 125, 125, 0.2); +} + +.mytheme .v-menubar > .v-menubar-menuitem .v-icon { + margin: 0 4px 0 -4px; + cursor: inherit; +} + +.mytheme .v-menubar > .v-menubar-menuitem[class*="-icon-only"] { + width: 37px; + padding: 0; +} + +.mytheme .v-menubar > .v-menubar-menuitem[class*="-icon-only"] .v-icon { + margin: 0; +} + +.mytheme .v-menubar > .v-menubar-menuitem-checked { + -webkit-box-shadow: none; + box-shadow: none; + background-color: #ededed; + background-image: -webkit-linear-gradient(bottom, #ededed 2%, #e9e9e9 98%); + background-image: linear-gradient(to top,#ededed 2%, #e9e9e9 98%); + color: #181818; +} + +.mytheme .v-disabled > .v-menubar-menuitem, .mytheme .v-menubar > .v-menubar-menuitem-disabled { + cursor: default; +} + +.mytheme .v-disabled > .v-menubar-menuitem:before, .mytheme .v-menubar > .v-menubar-menuitem-disabled:before { + display: none; +} + +.mytheme .v-menubar-menuitem-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-menubar > .v-menubar-menuitem-selected { + color: #ecf2f8; + + + + border-radius: 0; + border: 1px solid #1362b1; + border-top-color: #156ab3; + border-bottom-color: #1156a8; + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + -webkit-box-shadow: inset 0 1px 0 #4d98e6, inset 0 -1px 0 #166bca; + box-shadow: inset 0 1px 0 #4d98e6, inset 0 -1px 0 #166bca; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); + border-top-width: 0; + border-left-width: 0; + border-bottom-width: 0; + z-index: 2; +} + +.mytheme .v-menubar > .v-menubar-menuitem-selected:hover:before { + background: none; +} + +.mytheme .v-menubar .v-menubar-submenu-indicator { + display: none; +} + +.mytheme .v-menubar .v-menubar-submenu-indicator + .v-menubar-menuitem-caption:after { + font-family: ThemeIcons; + content: "\f078"; + font-size: 0.7em; + vertical-align: 0.15em; + margin: 0 -0.2em 0 0.5em; + opacity: 0.5; +} + +.mytheme .v-menubar .v-menubar-submenu-indicator + .v-menubar-menuitem-caption:empty:after { + margin-left: -0.2em; +} + +.mytheme .v-menubar-popup { + padding: 4px 4px; + border-radius: 4px; + background-color: white; + color: #474747; + -webkit-box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + backface-visibility: hidden; + padding: 4px 4px; + margin: 5px 0 0 1px !important; +} + +.mytheme .v-menubar-popup[class*="animate-in"] { + -webkit-animation: valo-overlay-animate-in 120ms; + -moz-animation: valo-overlay-animate-in 120ms; + animation: valo-overlay-animate-in 120ms; +} + +.mytheme .v-menubar-popup[class*="animate-out"] { + -webkit-animation: valo-animate-out-fade 120ms; + -moz-animation: valo-animate-out-fade 120ms; + animation: valo-animate-out-fade 120ms; +} + +.mytheme .v-menubar-popup .v-menubar-submenu { + outline: none; +} + +.mytheme .v-menubar-popup .v-menubar-menuitem { + display: block; + cursor: pointer; + line-height: 27px; + padding: 0 20px 0 10px; + border-radius: 3px; + font-weight: 400; + white-space: nowrap; + position: relative; + padding-left: 32px; + padding-right: 37px; + position: relative; +} + +.mytheme .v-menubar-popup .v-menubar-menuitem:active:before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: #0957a6; + opacity: 0.15; + filter: alpha(opacity=15.0) ; + pointer-events: none; + border-radius: inherit; +} + +.mytheme .v-menubar-popup .v-menubar-menuitem .v-icon { + max-height: 27px; + margin-right: 5px; + min-width: 1em; +} + +.mytheme .v-menubar-popup .v-menubar-submenu-indicator { + display: none; +} + +.mytheme .v-menubar-popup .v-menubar-submenu-indicator + .v-menubar-menuitem-caption:after { + position: absolute; + right: 10px; + font-family: ThemeIcons; + content: "\f054"; + line-height: 29px; +} + +.mytheme .v-menubar-popup .v-menubar-menuitem-selected { + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + color: #ecf2f8; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); +} + +.mytheme .v-menubar-popup .v-menubar-separator { + display: block; + margin: 4px 0; + height: 0; + overflow: hidden; + border-bottom: 1px solid #e4e4e4; +} + +.mytheme .v-menubar-popup [class*="checked"] .v-menubar-menuitem-caption:before { + content: "\f00c"; + font-family: ThemeIcons; + position: absolute; + left: 10px; +} + +.mytheme .v-menubar-popup [class*="unchecked"] .v-menubar-menuitem-caption:before { + content: ""; +} + +.mytheme .v-menubar-popup [class*="disabled"] { + cursor: default; +} + +.mytheme .v-menubar-small { + height: 31px; + padding: 0 14px; + + font-weight: 400; + + cursor: default; + border-radius: 4px; + padding: 0; + text-align: left; + line-height: 29px; + font-size: 14px; +} + +.mytheme .v-menubar-small:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-menubar-small > .v-menubar-menuitem { + padding: 0 12px; +} + +.mytheme .v-menubar-small > .v-menubar-menuitem[class*="-icon-only"] { + width: 31px; +} + +.mytheme .v-menubar-borderless { + border: none; + border-radius: 0; + padding: 1px; + -webkit-box-shadow: none; + box-shadow: none; + text-shadow: none; + background: transparent; + color: inherit; +} + +.mytheme .v-menubar-borderless:focus:after { + display: none; +} + +.mytheme .v-menubar-borderless .v-menubar-menuitem { + -webkit-box-shadow: none; + box-shadow: none; + border: none; + margin-right: 1px; + border-radius: 4px; + color: #197de1; + padding: 0 12px; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme .v-menubar-borderless .v-menubar-menuitem:first-child, .mytheme .v-menubar-borderless .v-menubar-menuitem:last-child, .mytheme .v-menubar-borderless .v-menubar-menuitem:first-child:last-child { + border-radius: 4px; +} + +.mytheme .v-menubar-borderless .v-menubar-menuitem:before { + content: none; +} + +.mytheme .v-menubar-borderless .v-menubar-menuitem:hover { + color: #4396ea; +} + +.mytheme .v-menubar-borderless .v-menubar-menuitem:active { + color: inherit; +} + +.mytheme .v-menubar-borderless .v-menubar-menuitem-checked, .mytheme .v-menubar-borderless .v-menubar-menuitem-checked:first-child { + border: 1px solid #c5c5c5; + color: #197de1; +} + +.mytheme .v-menubar-borderless .v-menubar-menuitem-checked .v-menubar-menuitem-caption, .mytheme .v-menubar-borderless .v-menubar-menuitem-checked:first-child .v-menubar-menuitem-caption { + position: relative; + top: -1px; +} + +.mytheme .v-menubar-borderless .v-menubar-menuitem-selected { + color: #ecf2f8; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); +} + +.mytheme .v-menubar-borderless .v-menubar-menuitem-selected:hover { + color: #ecf2f8; +} + +.mytheme .v-menubar-borderless .v-menubar-menuitem-disabled, .mytheme .v-menubar-borderless .v-menubar-menuitem-disabled:hover { + color: inherit; +} + +.mytheme .v-radiobutton { + position: relative; + line-height: 19px; + white-space: nowrap; +} + +.mytheme .v-radiobutton.v-has-width label { + white-space: normal; +} + +:root .mytheme .v-radiobutton { + padding-left: 25px; +} + +:root .mytheme .v-radiobutton label { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + display: inline-block; +} + +:root .mytheme .v-radiobutton > input { + position: absolute; + clip: rect(0, 0, 0, 0); + left: 0.2em; + top: 0.2em; + z-index: 0; + margin: 0; +} + +:root .mytheme .v-radiobutton > input:focus ~ label:before { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); +} + +:root .mytheme .v-radiobutton > input ~ label:before, :root .mytheme .v-radiobutton > input ~ label:after { + content: ""; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 19px; + height: 19px; + position: absolute; + top: 0; + left: 0; + border-radius: 4px; + font-size: 13px; + text-align: center; +} + +:root .mytheme .v-radiobutton > input ~ label:before { + height: 18.5px; + padding: 0 9px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + padding: 0; + height: 19px; +} + +:root .mytheme .v-radiobutton > input ~ label:after { + content: "\f00c"; + font-family: ThemeIcons; + color: transparent; + -webkit-transition: color 100ms; + -moz-transition: color 100ms; + transition: color 100ms; +} + +:root .mytheme .v-radiobutton > input:active ~ label:after { + background-color: rgba(125, 125, 125, 0.2); +} + +:root .mytheme .v-radiobutton > input:checked ~ label:after { + color: #197de1; +} + +.mytheme .v-radiobutton > .v-icon, .mytheme .v-radiobutton > label .v-icon { + margin: 0 6px 0 3px; + min-width: 1em; + cursor: pointer; +} + +.mytheme .v-radiobutton.v-disabled > label, .mytheme .v-radiobutton.v-disabled > .v-icon { + cursor: default; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-radiobutton.v-disabled > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-radiobutton.v-disabled > input:active ~ label:after { + background: transparent; +} + +.mytheme .v-radiobutton.v-readonly > label, .mytheme .v-radiobutton.v-readonly > .v-icon { + cursor: default; +} + +.mytheme .v-radiobutton.v-readonly > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-radiobutton.v-readonly > input:active ~ label:after { + background: transparent; +} + +:root .mytheme .v-radiobutton.v-readonly > input ~ label:after { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +:root .mytheme .v-radiobutton > input:checked ~ label:after { + width: 7px; + height: 7px; + top: 6px; + left: 6px; + background: #197de1; +} + +:root .mytheme .v-radiobutton > input ~ label:before, :root .mytheme .v-radiobutton > input ~ label:after { + border-radius: 50%; + content: ""; +} + +.mytheme .v-select-optiongroup .v-radiobutton, .mytheme .v-select-optiongroup .v-checkbox { + display: block; + margin: 9px 16px 0 0; +} + +.mytheme .v-select-optiongroup .v-radiobutton:first-child, .mytheme .v-select-optiongroup .v-checkbox:first-child { + margin-top: 6px; +} + +.mytheme .v-select-optiongroup .v-radiobutton:last-child, .mytheme .v-select-optiongroup .v-checkbox:last-child { + margin-bottom: 6px; +} + +.mytheme .v-select-optiongroup.v-has-width label { + white-space: normal; +} + +.mytheme .v-select-optiongroup-small { + font-size: 14px; +} + +.mytheme .v-select-optiongroup-small .v-checkbox { + position: relative; + line-height: 16px; + white-space: nowrap; +} + +.mytheme .v-select-optiongroup-small .v-checkbox.v-has-width label { + white-space: normal; +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox { + padding-left: 21px; +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox label { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + display: inline-block; +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox > input { + position: absolute; + clip: rect(0, 0, 0, 0); + left: 0.2em; + top: 0.2em; + z-index: 0; + margin: 0; +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox > input:focus ~ label:before { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox > input ~ label:before, :root .mytheme .v-select-optiongroup-small .v-checkbox > input ~ label:after { + content: ""; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 16px; + height: 16px; + position: absolute; + top: 0; + left: 0; + border-radius: 4px; + font-size: 11px; + text-align: center; +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox > input ~ label:before { + height: 15.5px; + padding: 0 7px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + padding: 0; + height: 16px; +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox > input ~ label:after { + content: "\f00c"; + font-family: ThemeIcons; + color: transparent; + -webkit-transition: color 100ms; + -moz-transition: color 100ms; + transition: color 100ms; +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox > input:active ~ label:after { + background-color: rgba(125, 125, 125, 0.2); +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox > input:checked ~ label:after { + color: #197de1; +} + +.mytheme .v-select-optiongroup-small .v-checkbox > .v-icon, .mytheme .v-select-optiongroup-small .v-checkbox > label .v-icon { + margin: 0 5px 0 3px; + min-width: 1em; + cursor: pointer; +} + +.mytheme .v-select-optiongroup-small .v-checkbox.v-disabled > label, .mytheme .v-select-optiongroup-small .v-checkbox.v-disabled > .v-icon { + cursor: default; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-select-optiongroup-small .v-checkbox.v-disabled > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox.v-disabled > input:active ~ label:after { + background: transparent; +} + +.mytheme .v-select-optiongroup-small .v-checkbox.v-readonly > label, .mytheme .v-select-optiongroup-small .v-checkbox.v-readonly > .v-icon { + cursor: default; +} + +.mytheme .v-select-optiongroup-small .v-checkbox.v-readonly > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox.v-readonly > input:active ~ label:after { + background: transparent; +} + +:root .mytheme .v-select-optiongroup-small .v-checkbox.v-readonly > input ~ label:after { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-select-optiongroup-small .v-radiobutton { + position: relative; + line-height: 16px; + white-space: nowrap; +} + +.mytheme .v-select-optiongroup-small .v-radiobutton.v-has-width label { + white-space: normal; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton { + padding-left: 21px; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton label { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + display: inline-block; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton > input { + position: absolute; + clip: rect(0, 0, 0, 0); + left: 0.2em; + top: 0.2em; + z-index: 0; + margin: 0; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton > input:focus ~ label:before { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton > input ~ label:before, :root .mytheme .v-select-optiongroup-small .v-radiobutton > input ~ label:after { + content: ""; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 16px; + height: 16px; + position: absolute; + top: 0; + left: 0; + border-radius: 4px; + font-size: 11px; + text-align: center; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton > input ~ label:before { + height: 15.5px; + padding: 0 7px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + padding: 0; + height: 16px; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton > input ~ label:after { + content: "\f00c"; + font-family: ThemeIcons; + color: transparent; + -webkit-transition: color 100ms; + -moz-transition: color 100ms; + transition: color 100ms; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton > input:active ~ label:after { + background-color: rgba(125, 125, 125, 0.2); +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton > input:checked ~ label:after { + color: #197de1; +} + +.mytheme .v-select-optiongroup-small .v-radiobutton > .v-icon, .mytheme .v-select-optiongroup-small .v-radiobutton > label .v-icon { + margin: 0 5px 0 3px; + min-width: 1em; + cursor: pointer; +} + +.mytheme .v-select-optiongroup-small .v-radiobutton.v-disabled > label, .mytheme .v-select-optiongroup-small .v-radiobutton.v-disabled > .v-icon { + cursor: default; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-select-optiongroup-small .v-radiobutton.v-disabled > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton.v-disabled > input:active ~ label:after { + background: transparent; +} + +.mytheme .v-select-optiongroup-small .v-radiobutton.v-readonly > label, .mytheme .v-select-optiongroup-small .v-radiobutton.v-readonly > .v-icon { + cursor: default; +} + +.mytheme .v-select-optiongroup-small .v-radiobutton.v-readonly > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton.v-readonly > input:active ~ label:after { + background: transparent; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton.v-readonly > input ~ label:after { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton > input:checked ~ label:after { + width: 6px; + height: 6px; + top: 5px; + left: 5px; + background: #197de1; +} + +:root .mytheme .v-select-optiongroup-small .v-radiobutton > input ~ label:before, :root .mytheme .v-select-optiongroup-small .v-radiobutton > input ~ label:after { + border-radius: 50%; + content: ""; +} + +.mytheme .v-select-optiongroup-small .v-radiobutton, .mytheme .v-select-optiongroup-small .v-checkbox { + display: block; + margin: 8px 16px 0 0; +} + +.mytheme .v-select-optiongroup-small .v-radiobutton:first-child, .mytheme .v-select-optiongroup-small .v-checkbox:first-child { + margin-top: 5px; +} + +.mytheme .v-select-optiongroup-small .v-radiobutton:last-child, .mytheme .v-select-optiongroup-small .v-checkbox:last-child { + margin-bottom: 5px; +} + +.mytheme .v-select-optiongroup-small.v-has-width label { + white-space: normal; +} + +.mytheme .v-select-optiongroup-large { + font-size: 20px; +} + +.mytheme .v-select-optiongroup-large .v-checkbox { + position: relative; + line-height: 22px; + white-space: nowrap; +} + +.mytheme .v-select-optiongroup-large .v-checkbox.v-has-width label { + white-space: normal; +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox { + padding-left: 29px; +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox label { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + display: inline-block; +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox > input { + position: absolute; + clip: rect(0, 0, 0, 0); + left: 0.2em; + top: 0.2em; + z-index: 0; + margin: 0; +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox > input:focus ~ label:before { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox > input ~ label:before, :root .mytheme .v-select-optiongroup-large .v-checkbox > input ~ label:after { + content: ""; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 22px; + height: 22px; + position: absolute; + top: 0; + left: 0; + border-radius: 4px; + font-size: 15px; + text-align: center; +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox > input ~ label:before { + height: 22px; + padding: 0 10px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + padding: 0; + height: 22px; +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox > input ~ label:after { + content: "\f00c"; + font-family: ThemeIcons; + color: transparent; + -webkit-transition: color 100ms; + -moz-transition: color 100ms; + transition: color 100ms; +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox > input:active ~ label:after { + background-color: rgba(125, 125, 125, 0.2); +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox > input:checked ~ label:after { + color: #197de1; +} + +.mytheme .v-select-optiongroup-large .v-checkbox > .v-icon, .mytheme .v-select-optiongroup-large .v-checkbox > label .v-icon { + margin: 0 7px 0 4px; + min-width: 1em; + cursor: pointer; +} + +.mytheme .v-select-optiongroup-large .v-checkbox.v-disabled > label, .mytheme .v-select-optiongroup-large .v-checkbox.v-disabled > .v-icon { + cursor: default; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-select-optiongroup-large .v-checkbox.v-disabled > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox.v-disabled > input:active ~ label:after { + background: transparent; +} + +.mytheme .v-select-optiongroup-large .v-checkbox.v-readonly > label, .mytheme .v-select-optiongroup-large .v-checkbox.v-readonly > .v-icon { + cursor: default; +} + +.mytheme .v-select-optiongroup-large .v-checkbox.v-readonly > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox.v-readonly > input:active ~ label:after { + background: transparent; +} + +:root .mytheme .v-select-optiongroup-large .v-checkbox.v-readonly > input ~ label:after { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-select-optiongroup-large .v-radiobutton { + position: relative; + line-height: 22px; + white-space: nowrap; +} + +.mytheme .v-select-optiongroup-large .v-radiobutton.v-has-width label { + white-space: normal; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton { + padding-left: 29px; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton label { + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + cursor: pointer; + display: inline-block; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton > input { + position: absolute; + clip: rect(0, 0, 0, 0); + left: 0.2em; + top: 0.2em; + z-index: 0; + margin: 0; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton > input:focus ~ label:before { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5), inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton > input ~ label:before, :root .mytheme .v-select-optiongroup-large .v-radiobutton > input ~ label:after { + content: ""; + display: inline-block; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 22px; + height: 22px; + position: absolute; + top: 0; + left: 0; + border-radius: 4px; + font-size: 15px; + text-align: center; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton > input ~ label:before { + height: 22px; + padding: 0 10px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + padding: 0; + height: 22px; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton > input ~ label:after { + content: "\f00c"; + font-family: ThemeIcons; + color: transparent; + -webkit-transition: color 100ms; + -moz-transition: color 100ms; + transition: color 100ms; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton > input:active ~ label:after { + background-color: rgba(125, 125, 125, 0.2); +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton > input:checked ~ label:after { + color: #197de1; +} + +.mytheme .v-select-optiongroup-large .v-radiobutton > .v-icon, .mytheme .v-select-optiongroup-large .v-radiobutton > label .v-icon { + margin: 0 7px 0 4px; + min-width: 1em; + cursor: pointer; +} + +.mytheme .v-select-optiongroup-large .v-radiobutton.v-disabled > label, .mytheme .v-select-optiongroup-large .v-radiobutton.v-disabled > .v-icon { + cursor: default; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-select-optiongroup-large .v-radiobutton.v-disabled > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton.v-disabled > input:active ~ label:after { + background: transparent; +} + +.mytheme .v-select-optiongroup-large .v-radiobutton.v-readonly > label, .mytheme .v-select-optiongroup-large .v-radiobutton.v-readonly > .v-icon { + cursor: default; +} + +.mytheme .v-select-optiongroup-large .v-radiobutton.v-readonly > label > .v-icon { + cursor: default; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton.v-readonly > input:active ~ label:after { + background: transparent; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton.v-readonly > input ~ label:after { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton > input:checked ~ label:after { + width: 8px; + height: 8px; + top: 7px; + left: 7px; + background: #197de1; +} + +:root .mytheme .v-select-optiongroup-large .v-radiobutton > input ~ label:before, :root .mytheme .v-select-optiongroup-large .v-radiobutton > input ~ label:after { + border-radius: 50%; + content: ""; +} + +.mytheme .v-select-optiongroup-large .v-radiobutton, .mytheme .v-select-optiongroup-large .v-checkbox { + display: block; + margin: 11px 16px 0 0; +} + +.mytheme .v-select-optiongroup-large .v-radiobutton:first-child, .mytheme .v-select-optiongroup-large .v-checkbox:first-child { + margin-top: 7px; +} + +.mytheme .v-select-optiongroup-large .v-radiobutton:last-child, .mytheme .v-select-optiongroup-large .v-checkbox:last-child { + margin-bottom: 7px; +} + +.mytheme .v-select-optiongroup-large.v-has-width label { + white-space: normal; +} + +.mytheme .v-select-optiongroup-horizontal { + white-space: nowrap; +} + +.mytheme .v-select-optiongroup-horizontal .v-radiobutton, .mytheme .v-select-optiongroup-horizontal .v-checkbox { + display: inline-block; +} + +.mytheme .v-select-optiongroup-horizontal.v-has-width { + white-space: normal; +} + +.mytheme .v-select-optiongroup-horizontal.v-has-width label { + white-space: nowrap; +} + +.mytheme .v-link { + cursor: pointer; + color: #197de1; + text-decoration: underline; + font-weight: inherit; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme .v-link:hover { + color: #4396ea; +} + +.mytheme .v-link.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-link a { + cursor: inherit; + color: inherit; + text-decoration: inherit; + -webkit-transition: inherit; + -moz-transition: inherit; + transition: inherit; +} + +.mytheme .v-link .v-icon { + cursor: inherit; +} + +.mytheme .v-link-small { + font-size: 14px; +} + +.mytheme .v-link-large { + font-size: 20px; +} + +.mytheme .v-window { + padding: 4px 4px; + border-radius: 4px; + background-color: white; + color: #474747; + -webkit-box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1), 0 16px 80px -6px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.09098); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1), 0 16px 80px -6px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.09098); + padding: 0; + min-width: 148px !important; + min-height: 37px !important; + white-space: nowrap; + overflow: hidden !important; + -webkit-transition: width 200ms, height 200ms, top 200ms, left 200ms; + -moz-transition: width 200ms, height 200ms, top 200ms, left 200ms; + transition: width 200ms, height 200ms, top 200ms, left 200ms; +} + +.mytheme .v-window[class*="animate-in"] { + -webkit-animation: valo-animate-in-fade 140ms; + -moz-animation: valo-animate-in-fade 140ms; + animation: valo-animate-in-fade 140ms; +} + +.mytheme .v-window[class*="animate-out"] { + -webkit-animation: valo-animate-out-scale-down-fade 100ms; + -moz-animation: valo-animate-out-scale-down-fade 100ms; + animation: valo-animate-out-scale-down-fade 100ms; +} + +.mytheme .v-window.v-window-animate-in { + -webkit-transition: none; + -moz-transition: none; + transition: none; +} + +.mytheme .v-window-modalitycurtain { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: #222; + background-image: -webkit-radial-gradient(50% 50%, circle, #222, #0e0e0e); + background-image: radial-gradient( circle at 50% 50%, #222, #0e0e0e); + opacity: 0.72; + filter: alpha(opacity=72) ; + -webkit-animation: valo-animate-in-fade 400ms 100ms backwards; + -moz-animation: valo-animate-in-fade 400ms 100ms backwards; + animation: valo-animate-in-fade 400ms 100ms backwards; +} + +.v-op12 .mytheme .v-window-modalitycurtain { + -webkit-animation: none; + -moz-animation: none; + animation: none; +} + +.mytheme .v-window-draggingCurtain { + position: fixed !important; +} + +.mytheme .v-window-resizingCurtain + .v-window, .mytheme .v-window-draggingCurtain + .v-window { + -webkit-transition: none; + -moz-transition: none; + transition: none; +} + +.mytheme .v-window-outerheader { + cursor: move; + position: absolute; + z-index: 2; + top: 0; + left: 0; + right: 0; + -webkit-transform: translatez(0); + -moz-transform: translatez(0); + -ms-transform: translatez(0); + -o-transform: translatez(0); + transform: translatez(0); +} + +.mytheme .v-window-outerheader:after { + content: ""; + position: absolute; + bottom: -1px; + right: 0; + left: 0; + height: 0; + border-top: 1px solid #dfdfdf; + border-color: rgba(197, 197, 197, 0.5); +} + +.mytheme .v-window-header { + line-height: 36px; + padding-left: 12px; + margin-right: 74px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + color: #7e7e7e; +} + +.mytheme .v-window-restorebox-disabled ~ .v-window-closebox ~ .v-window-header, .mytheme .v-window-maximizebox-disabled ~ .v-window-closebox ~ .v-window-header { + margin-right: 37px; +} + +.mytheme .v-window-restorebox-disabled ~ .v-window-closebox-disabled ~ .v-window-header, .mytheme .v-window-maximizebox-disabled ~ .v-window-closebox-disabled ~ .v-window-header { + margin-right: 12px; +} + +.mytheme .v-window-closebox, .mytheme .v-window-maximizebox, .mytheme .v-window-restorebox { + position: absolute; + z-index: 3; + top: 0; + right: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 33px; + height: 36px; + background-color: white; + line-height: 34px; + text-align: center; + cursor: pointer; + font-size: 21px; + color: #999999; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme .v-window-closebox:focus, .mytheme .v-window-maximizebox:focus, .mytheme .v-window-restorebox:focus { + outline: none; +} + +.mytheme .v-window-closebox:hover, .mytheme .v-window-maximizebox:hover, .mytheme .v-window-restorebox:hover { + opacity: 1; + filter: none ; + color: #197de1; +} + +.mytheme .v-window-closebox:active, .mytheme .v-window-maximizebox:active, .mytheme .v-window-restorebox:active { + color: inherit; +} + +.mytheme .v-window-closebox { + padding-right: 4px; + border-radius: 0 4px 0 4px; +} + +.mytheme .v-window-closebox:before { + content: "\00d7"; +} + +.mytheme .v-window-maximizebox, .mytheme .v-window-restorebox { + right: 33px; + padding-left: 4px; + border-radius: 0 0 0 4px; +} + +.mytheme .v-window-maximizebox + .v-window-closebox, .mytheme .v-window-restorebox + .v-window-closebox { + border-bottom-left-radius: 0; +} + +.mytheme .v-window-closebox-disabled, .mytheme .v-window-resizebox-disabled, .mytheme .v-window-restorebox-disabled, .mytheme .v-window-maximizebox-disabled { + display: none; +} + +.mytheme .v-window-closebox-disabled + .v-window-closebox, .mytheme .v-window-resizebox-disabled + .v-window-closebox, .mytheme .v-window-restorebox-disabled + .v-window-closebox, .mytheme .v-window-maximizebox-disabled + .v-window-closebox { + width: 37px; + padding-right: 0; + border-bottom-left-radius: 4px; +} + +.mytheme .v-window-maximizebox:before { + content: "+"; +} + +.mytheme .v-window-restorebox:before { + content: "\2013"; +} + +.mytheme .v-window > .popupContent, .mytheme .v-window-wrap, .mytheme .v-window-contents, .mytheme .v-window-contents > .v-scrollable { + height: 100%; +} + +.mytheme .v-window-contents { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + border-radius: 4px; + margin-top: 0 !important; +} + +.mytheme .v-window-contents > .v-scrollable { + position: relative; +} + +.mytheme .v-window-contents > .v-scrollable > .v-margin-top { + padding-top: 12px; +} + +.mytheme .v-window-contents > .v-scrollable > .v-margin-right { + padding-right: 12px; +} + +.mytheme .v-window-contents > .v-scrollable > .v-margin-bottom { + padding-bottom: 12px; +} + +.mytheme .v-window-contents > .v-scrollable > .v-margin-left { + padding-left: 12px; +} + +.mytheme .v-window-contents > .v-scrollable > .v-formlayout [class*="margin-top"] > tbody > [class*="firstrow"] > td { + padding-top: 12px; +} + +.mytheme .v-window-contents > .v-scrollable > .v-formlayout [class*="margin-bottom"] > tbody > [class*="lastrow"] > td { + padding-bottom: 12px; +} + +.mytheme .v-window-contents > .v-scrollable > .v-formlayout [class*="margin-left"] > tbody > [class*="row"] > [class*="captioncell"] { + padding-left: 12px; +} + +.mytheme .v-window-contents > .v-scrollable > .v-formlayout [class*="margin-left"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h2, .mytheme .v-window-contents > .v-scrollable > .v-formlayout [class*="margin-left"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h3, .mytheme .v-window-contents > .v-scrollable > .v-formlayout [class*="margin-left"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h4 { + left: 12px; +} + +.mytheme .v-window-contents > .v-scrollable > .v-formlayout [class*="margin-right"] > tbody > [class*="row"] > [class*="contentcell"] { + padding-right: 12px; +} + +.mytheme .v-window-contents > .v-scrollable > .v-formlayout [class*="margin-right"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h2, .mytheme .v-window-contents > .v-scrollable > .v-formlayout [class*="margin-right"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h3, .mytheme .v-window-contents > .v-scrollable > .v-formlayout [class*="margin-right"] > tbody > [class*="row"] > [class*="contentcell"] > .v-label-h4 { + right: 12px; +} + +.mytheme .v-window-contents > .v-scrollable:focus { + outline: none; +} + +.mytheme .v-window-contents > .v-scrollable:before { + content: ""; + position: absolute; + z-index: 2; + top: 0; + height: 0; + border-top: 1px solid white; + left: 0; + right: 0; +} + +.mytheme .v-window-contents > .v-scrollable .v-panel-captionwrap:after { + border-color: #dfdfdf; +} + +.mytheme .v-window-contents > .v-scrollable .v-panel-content:before { + border-color: white; +} + +.mytheme .v-window-footer { + height: 0; +} + +.mytheme .v-window-resizebox { + position: absolute; + z-index: 1000; + right: 0; + bottom: 0; + width: 19px; + height: 19px; + cursor: nwse-resize; +} + +.v-ie8 .mytheme .v-window-resizebox { + background: #000; + filter: alpha(opacity=0.1); +} + +.v-ie8 .mytheme .v-window-resizebox, .v-ie9 .mytheme .v-window-resizebox { + cursor: se-resize; +} + +.mytheme .v-window-modalitycurtain:active ~ .v-window { + -webkit-animation: none; + -moz-animation: none; + animation: none; +} + +.mytheme .v-window-top-toolbar > .v-widget, .mytheme .v-window-bottom-toolbar > .v-widget { + vertical-align: top; +} + +.mytheme .v-window-top-toolbar .v-label, .mytheme .v-window-bottom-toolbar .v-label { + line-height: 36px; +} + +.mytheme .v-window-top-toolbar .v-spacing, .mytheme .v-window-bottom-toolbar .v-spacing { + width: 6px; +} + +.mytheme .v-window-top-toolbar.v-layout { + padding: 7px 12px; + position: relative; + z-index: 2; + border-top: 1px solid #dfdfdf; + border-bottom: 1px solid #dfdfdf; + background-color: #fafafa; +} + +.mytheme .v-window-top-toolbar.v-menubar { + margin: 12px 12px 6px; +} + +.mytheme .v-window-top-toolbar.v-menubar-borderless { + padding-left: 6px; + padding-right: 6px; + margin: 5px 0; +} + +.mytheme .v-window-bottom-toolbar.v-layout { + padding: 7px 12px; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #f0f0f0 0, #fafafa 4px); + background-image: linear-gradient(to bottom,#f0f0f0 0, #fafafa 4px); + border-top: 1px solid #dfdfdf; + border-radius: 0 0 4px 4px; +} + +.mytheme .v-margin-left.v-margin-right.v-margin-top .v-window-top-toolbar.v-layout { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + margin: -12px -12px 0; +} + +.mytheme .v-margin-left.v-margin-right.v-margin-top .v-window-top-toolbar.v-menubar { + margin: 0; +} + +.mytheme .v-margin-left.v-margin-right.v-margin-top .v-window-top-toolbar.v-menubar-borderless { + margin: -6px -6px 0; + padding: 0; +} + +.mytheme .v-margin-left.v-margin-right.v-margin-bottom .v-window-bottom-toolbar.v-layout { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + margin: 0 -12px -12px; +} + +.mytheme .v-tree { + position: relative; + white-space: nowrap; +} + +.mytheme .v-tree:focus { + outline: none; +} + +.mytheme .v-tree-node:before { + content: ""; + position: absolute; + display: inline-block; + z-index: 3; + width: 1.9em; + height: 28px; + cursor: pointer; + background: red; + opacity: 0; +} + +.v-ie8 .mytheme .v-tree-node:before { + position: static; + margin-left: -1.9em; + vertical-align: top; + content: "\f0da"; + font-family: ThemeIcons; + text-align: center; + background: transparent; +} + +.v-ie8 .mytheme .v-tree-node { + padding-left: 1.9em; +} + +.mytheme .v-tree-node-caption { + height: 28px; + line-height: 27px; + overflow: hidden; + white-space: nowrap; + vertical-align: top; +} + +.mytheme .v-tree-node-caption > div { + display: inline-block; + width: 100%; + position: relative; + z-index: 2; +} + +.mytheme .v-tree-node-caption > div:before { + content: "\f0da"; + font-family: ThemeIcons; + display: inline-block; + width: 0.5em; + text-align: center; + margin: 0 0.6em 0 0.8em; + -webkit-transition: all 100ms; + -moz-transition: all 100ms; + transition: all 100ms; +} + +.v-ie8 .mytheme .v-tree-node-caption > div:before { + display: none; +} + +.mytheme .v-tree-node-caption span { + padding-right: 28px; + cursor: pointer; + display: inline-block; + width: 100%; +} + +.v-ie .mytheme .v-tree-node-caption span { + width: auto; +} + +.mytheme .v-tree-node-caption .v-icon { + padding-right: 0; + width: auto; + min-width: 1em; +} + +.mytheme .v-tree-node-caption:after { + content: ""; + display: block; + vertical-align: top; + position: absolute; + z-index: 1; + left: 0; + margin-top: -28px; + width: 100%; + height: 28px; + border-radius: 4px; + opacity: 0; + -webkit-transition: opacity 120ms; + -moz-transition: opacity 120ms; + transition: opacity 120ms; +} + +.v-ie8 .mytheme .v-tree-node-caption:after { + content: none; +} + +.v-ie8 .mytheme .v-tree-node-caption { + display: inline-block; +} + +.mytheme .v-tree-node-expanded > .v-tree-node-caption > div:before { + -webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -ms-transform: rotate(90deg); + -o-transform: rotate(90deg); + transform: rotate(90deg); + content: "\f0da"; + font-family: ThemeIcons; +} + +.v-ie8 .mytheme .v-tree-node-expanded:before { + content: "\f0d7"; + font-family: ThemeIcons; +} + +.mytheme .v-tree-node-leaf:before, .mytheme .v-tree-node-leaf > .v-tree-node-caption > div:before { + visibility: hidden; +} + +.mytheme .v-tree-node-focused:after { + opacity: 1; + border: 1px solid #197de1; +} + +.v-ie8 .mytheme .v-tree-node-focused { + outline: 1px dotted #197de1; +} + +.mytheme .v-tree-node-selected { + color: #ecf2f8; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); +} + +.mytheme .v-tree-node-selected:after { + opacity: 1; + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + border: none; +} + +.v-ie8 .mytheme .v-tree-node-selected { + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); +} + +.mytheme .v-tree-node-children { + padding-left: 19px; +} + +.v-ie8 .mytheme .v-tree-node-children { + padding-left: 0; +} + +.mytheme .v-tree-node-drag-top:before, .mytheme .v-tree-node-drag-bottom:after, .mytheme .v-tree-node-drag-bottom.v-tree-node-dragfolder.v-tree-node-expanded > .v-tree-node-children:before { + content: "\2022"; + display: block; + position: absolute; + height: 2px; + width: 100%; + background: #197de1; + font-size: 32px; + line-height: 2px; + color: #197de1; + text-indent: -4px; + text-shadow: 0 0 1px #fafafa, 0 0 1px #fafafa; + opacity: 1; + visibility: visible; +} + +.mytheme .v-tree-node-drag-bottom.v-tree-node-dragfolder.v-tree-node-expanded:after { + content: none; +} + +.mytheme .v-tree-node-caption-drag-center { + -webkit-box-shadow: 0 0 0 2px #197de1; + box-shadow: 0 0 0 2px #197de1; + position: relative; + border-radius: 4px; +} + +.v-ie8 .mytheme .v-tree-node-caption-drag-center { + outline: 2px solid #197de1; +} + +.v-ff .mytheme .v-tree-node-drag-top:before, .v-ff .mytheme .v-tree-node-drag-bottom:after { + line-height: 1px; +} + +.v-ie8 .mytheme .v-tree-node-drag-top:before, .v-ie8 .mytheme .v-tree-node-drag-bottom:after { + line-height: 0; +} + +.mytheme .v-table { + position: relative; + background: #fafafa; + color: #464646; + overflow: hidden; +} + +.mytheme .v-table-header table, .mytheme .v-table-footer table, .mytheme .v-table-table { + -webkit-box-shadow: 0 0 0 1px #d4d4d4; + box-shadow: 0 0 0 1px #d4d4d4; +} + +.v-ie8 .mytheme .v-table-header table, .v-ie8 .mytheme .v-table-footer table, .v-ie8 .mytheme .v-table-table { + outline: 1px solid #d4d4d4; +} + +.mytheme .v-table-header-wrap, .mytheme .v-table-footer-wrap, .mytheme .v-table-header-drag { + border: 1px solid #d4d4d4; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + white-space: nowrap; + font-size: 14px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); +} + +.mytheme .v-table-header-wrap { + position: relative; + border-bottom: none; +} + +.mytheme .v-table-footer-wrap { + border-top: none; +} + +.mytheme .v-table-footer td { + border-left: 1px solid #d4d4d4; +} + +.mytheme .v-table-footer-container, .mytheme .v-table-caption-container { + overflow: hidden; + line-height: 1; + min-height: 37px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.v-ie8 .mytheme .v-table-footer-container, .v-ie8 .mytheme .v-table-caption-container { + min-height: 14px; +} + +.mytheme .v-table-footer-container { + padding: 11px 12px 12px; + float: right; +} + +.mytheme [class^="v-table-header-cell"] { + position: relative; +} + +.mytheme .v-table-caption-container, .mytheme .v-table-header-drag { + padding: 12px 12px 11px; + border-left: 1px solid #d4d4d4; +} + +.mytheme .v-table-caption-container-align-right { + padding-right: 4px; +} + +.mytheme .v-table-resizer { + height: 37px; + width: 8px; + cursor: e-resize; + cursor: col-resize; + position: relative; + right: -4px; + z-index: 1; + margin-left: -8px; +} + +.mytheme .v-table-cell-content { + border-left: 1px solid #d4d4d4; + overflow: hidden; + height: 37px; + vertical-align: middle; +} + +.mytheme .v-table-cell-content:first-child { + border-left: none; + padding-left: 1px; +} + +.mytheme .v-table-header td:first-child .v-table-caption-container, .mytheme .v-table-footer td:first-child { + border-left-color: transparent; +} + +.mytheme .v-table-cell-wrapper { + line-height: 1; + padding: 0 12px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + margin-right: 0 !important; +} + +.mytheme .v-table-cell-wrapper > .v-widget { + margin: 3px -6px; +} + +.mytheme .v-table-cell-wrapper > .v-widget.v-label, .mytheme .v-table-cell-wrapper > .v-widget.v-checkbox, .mytheme .v-table-cell-wrapper > .v-widget.v-select-optiongroup { + margin: 0; +} + +.mytheme .v-table-cell-wrapper > .v-widget.v-progressbar { + margin-left: 0; + margin-right: 0; +} + +.mytheme .v-table-body { + border: 1px solid #d4d4d4; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +.mytheme .v-table-table { + background-color: white; + white-space: nowrap; +} + +.mytheme .v-table-table td { + border-top: 1px solid #d4d4d4; +} + +.mytheme .v-table-table tr:first-child > td { + border-top: none; +} + +.mytheme .v-table-row { + background-color: white; + cursor: pointer; +} + +.mytheme .v-table-row-odd { + background-color: #f5f5f5; + cursor: pointer; +} + +.mytheme .v-table-body-noselection .v-table-row, .mytheme .v-table-body-noselection .v-table-row-odd { + cursor: default; +} + +.mytheme .v-table [class*="-row"].v-selected { + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + background-origin: border-box; + color: #ecf2f8; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); +} + +.mytheme .v-table [class*="-row"].v-selected + .v-selected { + background: #166ed5; +} + +.mytheme .v-table [class*="-row"].v-selected + .v-selected td { + border-top-color: #166ed5; +} + +.mytheme .v-table [class*="-row"].v-selected .v-table-cell-content { + border-color: transparent; + border-left-color: #1d69b4; +} + +.mytheme .v-table [class*="-row"].v-selected .v-table-cell-content:first-child { + border-left-color: transparent; +} + +.mytheme .v-table-header-cell-asc .v-table-sort-indicator, .mytheme .v-table-header-cell-desc .v-table-sort-indicator { + background: transparent; + width: 19px; + height: 37px; + line-height: 37px; + margin-left: -19px; +} + +.mytheme .v-table-header-cell-asc .v-table-sort-indicator:before, .mytheme .v-table-header-cell-desc .v-table-sort-indicator:before { + font-style: normal; + font-weight: normal; + display: inline-block; +} + +.mytheme .v-table-header-cell-asc .v-table-sort-indicator:before { + content: "\f0de"; + font-family: ThemeIcons; +} + +.mytheme .v-table-header-cell-desc .v-table-sort-indicator:before { + content: "\f0dd"; + font-family: ThemeIcons; +} + +.mytheme [class*="rowheader"] span.v-icon { + min-width: 1em; +} + +.mytheme .v-table-focus { + outline: 1px solid #197de1; + outline-offset: -1px; +} + +.mytheme .v-drag-element.v-table-focus, .mytheme .v-drag-element .v-table-focus { + outline: none; +} + +.mytheme .v-table-header-drag { + position: absolute; + opacity: 0.9; + filter: alpha(opacity=90) ; + margin-top: -19px; + z-index: 30000; + line-height: 1; +} + +.mytheme .v-table-focus-slot-right { + border-right: 3px solid #197de1; + right: -2px; + margin-left: -11px !important; +} + +.mytheme .v-table-focus-slot-left { + float: left; + border-left: 3px solid #197de1; + left: -1px; + right: auto; + margin-left: 0 !important; + margin-right: -11px; +} + +.mytheme .v-table-column-selector { + height: 37px; + padding: 0 16px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7; + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + position: absolute; + z-index: 2; + top: 0; + right: 0; + width: 19px; + height: 19px; + line-height: 19px; + padding: 0; + border-top-width: 0; + border-right-width: 0; + border-radius: 0 0 0 4px; + cursor: pointer; + text-align: center; + opacity: 0; + filter: alpha(opacity=0) ; + -webkit-transition: opacity 200ms 2s; + -moz-transition: opacity 200ms 2s; + transition: opacity 200ms 2s; +} + +.mytheme .v-table-column-selector:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-table-column-selector:hover:after { + background-color: rgba(186, 186, 186, 0.1); +} + +.mytheme .v-table-column-selector:focus:after { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-table-column-selector:active:after { + background-color: rgba(125, 125, 125, 0.2); +} + +.mytheme .v-table-column-selector:after { + content: ""; + position: absolute; + border: none; + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +.mytheme .v-table-column-selector:active:after { + background-color: rgba(125, 125, 125, 0.2); +} + +.mytheme .v-table-column-selector:before { + font-family: ThemeIcons; + content: "\f013"; +} + +.mytheme .v-table-header-wrap:hover .v-table-column-selector { + opacity: 1; + filter: none ; + -webkit-transition-delay: 200ms; + -moz-transition-delay: 200ms; + transition-delay: 200ms; +} + +.mytheme .v-on:before, .mytheme .v-off:before { + content: "\f00c"; + font-family: ThemeIcons; + font-size: 0.9em; + margin-right: 6px; +} + +.mytheme .v-on div, .mytheme .v-off div { + display: inline; +} + +.mytheme .v-on.v-disabled, .mytheme .v-off.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-off:before { + visibility: hidden; +} + +.mytheme tbody.v-drag-element { + display: block; + overflow: visible; + -webkit-box-shadow: none; + box-shadow: none; + background: transparent; + opacity: 1; + filter: none ; +} + +.mytheme tbody.v-drag-element tr { + display: block; + + + -webkit-box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); + border-radius: 4px; + overflow: hidden; + opacity: 0.5; + filter: alpha(opacity=50) ; + background: white; +} + +.mytheme .v-table-body { + position: relative; + z-index: 1; +} + +.mytheme .v-table-scrollposition { + position: absolute; + top: 50%; + width: 100%; + height: 37px; + line-height: 37px; + margin: -19px 0 0 !important; + text-align: center; +} + +.mytheme .v-table-drag { + overflow: visible; +} + +.mytheme .v-table-drag .v-table-body { + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + border-color: #197de1; +} + +.v-ie8 .mytheme .v-table-drag .v-table-body { + border-color: #197de1; +} + +.mytheme .v-table-drag .v-table-body .v-table-focus { + outline: none; +} + +.mytheme .v-table-row-drag-middle .v-table-cell-content { + background-color: #d1e5f9; + color: #214060; +} + +.mytheme .v-table-row-drag-bottom td.v-table-cell-content { + border-bottom: 2px solid #197de1; + height: 35px; +} + +.mytheme .v-table-row-drag-bottom .v-table-cell-wrapper { + margin-bottom: -2px; +} + +.mytheme .v-table-row-drag-top td.v-table-cell-content { + border-top: 2px solid #197de1; + height: 36px; +} + +.mytheme .v-table-row-drag-top .v-table-cell-wrapper { + margin-top: -1px; +} + +.mytheme .v-table-no-stripes .v-table-row, .mytheme .v-table-no-stripes .v-table-row-odd { + background: transparent; +} + +.mytheme .v-table-no-vertical-lines .v-table-cell-content { + border-left: none; + padding-left: 1px; +} + +.mytheme .v-table-no-vertical-lines.v-treetable .v-table-cell-content { + padding-left: 13px; +} + +.mytheme .v-table-no-horizontal-lines .v-table-cell-content { + border-top: none; + border-bottom: none; +} + +.mytheme .v-table-no-horizontal-lines .v-table-row-drag-top .v-table-cell-content, .mytheme .v-table-no-horizontal-lines .v-table-row-drag-bottom .v-table-cell-content { + height: 36px; +} + +.mytheme .v-table-no-header .v-table-header-wrap { + display: none; +} + +.mytheme .v-table-borderless .v-table-header-wrap, .mytheme .v-table-borderless .v-table-footer-wrap, .mytheme .v-table-borderless .v-table-header-drag, .mytheme .v-table-borderless .v-table-body { + border: none; +} + +.mytheme .v-table-borderless .v-table-header-wrap { + border-bottom: 1px solid #d9d9d9; +} + +.mytheme .v-table-borderless .v-table-footer-wrap { + border-top: 1px solid #d9d9d9; +} + +.mytheme .v-table-compact .v-table-header-wrap, .mytheme .v-table-compact .v-table-footer-wrap, .mytheme .v-table-compact .v-table-header-drag, .mytheme .v-table-small .v-table-header-wrap, .mytheme .v-table-small .v-table-footer-wrap, .mytheme .v-table-small .v-table-header-drag { + font-size: 14px; +} + +.mytheme .v-table-compact .v-table-footer-container, .mytheme .v-table-small .v-table-footer-container { + padding: 8px 7px 9px; +} + +.mytheme .v-table-compact .v-table-caption-container, .mytheme .v-table-compact .v-table-header-drag, .mytheme .v-table-small .v-table-caption-container, .mytheme .v-table-small .v-table-header-drag { + padding-top: 9px; + padding-bottom: 8px; + padding-left: 6px; + padding-right: 6px; +} + +.mytheme .v-table-compact .v-table-caption-container-align-right, .mytheme .v-table-small .v-table-caption-container-align-right { + padding-right: 0; +} + +.mytheme .v-table-compact .v-table-resizer, .mytheme .v-table-small .v-table-resizer { + height: 31px; +} + +.mytheme .v-table-compact .v-table-cell-content, .mytheme .v-table-small .v-table-cell-content { + height: 31px; +} + +.mytheme .v-table-compact .v-table-cell-wrapper, .mytheme .v-table-small .v-table-cell-wrapper { + padding-left: 6px; + padding-right: 6px; +} + +.mytheme .v-table-compact .v-table-cell-wrapper > .v-widget, .mytheme .v-table-small .v-table-cell-wrapper > .v-widget { + margin: 2px -3px; +} + +.mytheme .v-table-compact .v-table-cell-wrapper > .v-widget.v-label, .mytheme .v-table-compact .v-table-cell-wrapper > .v-widget.v-checkbox, .mytheme .v-table-compact .v-table-cell-wrapper > .v-widget.v-select-optiongroup, .mytheme .v-table-small .v-table-cell-wrapper > .v-widget.v-label, .mytheme .v-table-small .v-table-cell-wrapper > .v-widget.v-checkbox, .mytheme .v-table-small .v-table-cell-wrapper > .v-widget.v-select-optiongroup { + margin: 0; +} + +.mytheme .v-table-compact .v-table-cell-wrapper > .v-widget.v-progressbar, .mytheme .v-table-small .v-table-cell-wrapper > .v-widget.v-progressbar { + margin-left: 0; + margin-right: 0; +} + +.mytheme .v-table-compact .v-table-header-cell-asc .v-table-sort-indicator, .mytheme .v-table-compact .v-table-header-cell-desc .v-table-sort-indicator, .mytheme .v-table-small .v-table-header-cell-asc .v-table-sort-indicator, .mytheme .v-table-small .v-table-header-cell-desc .v-table-sort-indicator { + height: 31px; + line-height: 31px; +} + +.mytheme .v-table-compact .v-table-header-drag, .mytheme .v-table-small .v-table-header-drag { + margin-top: -16px; +} + +.mytheme .v-table-compact.v-treetable .v-table-cell-wrapper, .mytheme .v-table-small.v-treetable .v-table-cell-wrapper { + padding-left: 0; + padding-right: 0; + min-height: 16px; +} + +.mytheme .v-table-compact.v-treetable .v-table-cell-content, .mytheme .v-table-small.v-treetable .v-table-cell-content { + padding-left: 6px; + padding-right: 6px; +} + +.mytheme .v-table-compact.v-treetable .v-table-cell-content:first-child, .mytheme .v-table-small.v-treetable .v-table-cell-content:first-child { + padding-left: 7px; +} + +.mytheme .v-table-compact.v-treetable .v-table-footer-container, .mytheme .v-table-small.v-treetable .v-table-footer-container { + padding-left: 6px; + padding-right: 6px; +} + +.mytheme .v-table-compact .v-table-row-drag-top .v-table-cell-content, .mytheme .v-table-compact .v-table-row-drag-bottom .v-table-cell-content, .mytheme .v-table-small .v-table-row-drag-top .v-table-cell-content, .mytheme .v-table-small .v-table-row-drag-bottom .v-table-cell-content { + height: 30px; +} + +.mytheme .v-table-small { + font-size: 14px; +} + +.mytheme .v-table-small.v-treetable .v-table-cell-wrapper { + min-height: 14px; +} + +.mytheme .v-treetable [class*="caption-container"], .mytheme .v-treetable [class*="footer-container"], .mytheme .v-treetable [class*="cell-wrapper"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + padding-left: 0; + padding-right: 0; +} + +.mytheme .v-treetable [class*="caption-container"], .mytheme .v-treetable [class*="footer-container"] { + min-height: 14px; +} + +.mytheme .v-treetable [class*="cell-wrapper"] { + min-height: 16px; +} + +.mytheme .v-treetable [class*="caption-container"] { + padding-left: 12px; +} + +.mytheme .v-treetable [class*="caption-container-align-right"] { + padding-left: 20px; +} + +.mytheme .v-treetable [class*="footer-container"] { + padding-right: 12px; +} + +.mytheme .v-treetable [class*="cell-content"] { + padding-left: 12px; + padding-right: 12px; +} + +.mytheme .v-treetable [class*="cell-content"]:first-child { + padding-left: 13px; +} + +.mytheme .v-treetable-treespacer { + display: inline-block; + position: absolute; + width: 19px !important; + margin-left: -25px; + text-align: center; + cursor: pointer; +} + +.mytheme .v-treetable-node-closed:before { + content: "\f0da"; + font-family: ThemeIcons; +} + +.mytheme .v-treetable-node-open:before { + content: "\f0d7"; + font-family: ThemeIcons; +} + +.mytheme .v-splitpanel-horizontal > div > .v-splitpanel-hsplitter { + width: 1px; +} + +.mytheme .v-splitpanel-horizontal > div > .v-splitpanel-hsplitter:after { + left: -6px; + right: -6px; +} + +.mytheme .v-splitpanel-horizontal > div > .v-splitpanel-hsplitter div:before { + height: 37px; + padding: 0 16px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, none; + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, none; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + height: auto; + padding: 0; + border-radius: 0; + background-color: #fafafa; + background-image: -webkit-linear-gradient(left, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to right,#fafafa 2%, #efefef 98%); +} + +.mytheme .v-splitpanel-horizontal > div > .v-splitpanel-hsplitter div:before:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-splitpanel-horizontal > div > .v-splitpanel-hsplitter div:before:hover:after { + background-color: rgba(186, 186, 186, 0.1); +} + +.mytheme .v-splitpanel-horizontal > div > .v-splitpanel-hsplitter div:before:focus:after { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-splitpanel-horizontal > div > .v-splitpanel-hsplitter div:before:active:after { + background-color: rgba(125, 125, 125, 0.2); +} + +.mytheme .v-splitpanel-horizontal > div > .v-splitpanel-second-container { + margin-left: 1px; +} + +.mytheme .v-splitpanel-vertical > div > .v-splitpanel-vsplitter { + height: 1px; +} + +.mytheme .v-splitpanel-vertical > div > .v-splitpanel-vsplitter:after { + top: -6px; + bottom: -6px; +} + +.mytheme .v-splitpanel-vertical > div > .v-splitpanel-vsplitter div:before { + height: 37px; + padding: 0 16px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, none; + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, none; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + height: auto; + padding: 0; + border-radius: 0; +} + +.mytheme .v-splitpanel-vertical > div > .v-splitpanel-vsplitter div:before:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-splitpanel-vertical > div > .v-splitpanel-vsplitter div:before:hover:after { + background-color: rgba(186, 186, 186, 0.1); +} + +.mytheme .v-splitpanel-vertical > div > .v-splitpanel-vsplitter div:before:focus:after { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-splitpanel-vertical > div > .v-splitpanel-vsplitter div:before:active:after { + background-color: rgba(125, 125, 125, 0.2); +} + +.mytheme .v-splitpanel-horizontal.large > div > .v-splitpanel-hsplitter { + width: 12px; +} + +.mytheme .v-splitpanel-horizontal.large > div > .v-splitpanel-hsplitter:after { + left: 0px; + right: 0px; +} + +.mytheme .v-splitpanel-horizontal.large > div > .v-splitpanel-hsplitter div:before { + height: 37px; + padding: 0 16px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, none; + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, none; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + height: auto; + padding: 0; + border-radius: 0; + background-color: #fafafa; + background-image: -webkit-linear-gradient(left, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to right,#fafafa 2%, #efefef 98%); +} + +.mytheme .v-splitpanel-horizontal.large > div > .v-splitpanel-hsplitter div:before:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-splitpanel-horizontal.large > div > .v-splitpanel-hsplitter div:before:hover:after { + background-color: rgba(186, 186, 186, 0.1); +} + +.mytheme .v-splitpanel-horizontal.large > div > .v-splitpanel-hsplitter div:before:focus:after { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-splitpanel-horizontal.large > div > .v-splitpanel-hsplitter div:before:active:after { + background-color: rgba(125, 125, 125, 0.2); +} + +.mytheme .v-splitpanel-horizontal.large > div > .v-splitpanel-hsplitter div:after { + content: ""; + border: 1px solid #dadada; + border-top-color: #bababa; + border-left-color: #bababa; + position: absolute; + top: 50%; + left: 50%; + width: 0; + height: 37px; + margin-left: -1px; + margin-top: -19px; +} + +.mytheme .v-splitpanel-horizontal.large > div > .v-splitpanel-second-container { + margin-left: 12px; +} + +.mytheme .v-splitpanel-vertical.large > div > .v-splitpanel-vsplitter { + height: 12px; +} + +.mytheme .v-splitpanel-vertical.large > div > .v-splitpanel-vsplitter:after { + top: 0px; + bottom: 0px; +} + +.mytheme .v-splitpanel-vertical.large > div > .v-splitpanel-vsplitter div:before { + height: 37px; + padding: 0 16px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, none; + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, none; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + height: auto; + padding: 0; + border-radius: 0; +} + +.mytheme .v-splitpanel-vertical.large > div > .v-splitpanel-vsplitter div:before:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-splitpanel-vertical.large > div > .v-splitpanel-vsplitter div:before:hover:after { + background-color: rgba(186, 186, 186, 0.1); +} + +.mytheme .v-splitpanel-vertical.large > div > .v-splitpanel-vsplitter div:before:focus:after { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-splitpanel-vertical.large > div > .v-splitpanel-vsplitter div:before:active:after { + background-color: rgba(125, 125, 125, 0.2); +} + +.mytheme .v-splitpanel-vertical.large > div > .v-splitpanel-vsplitter div:after { + content: ""; + border: 1px solid #dadada; + border-top-color: #bababa; + border-left-color: #bababa; + position: absolute; + top: 50%; + left: 50%; + width: 37px; + height: 0; + margin-left: -19px; + margin-top: -1px; +} + +.mytheme .v-progressbar-wrapper { + border-radius: 4px; + height: 9px; + background-color: #d4d4d4; + background-image: -webkit-linear-gradient(bottom, #d7d7d7 2%, #c7c7c7 98%); + background-image: linear-gradient(to top,#d7d7d7 2%, #c7c7c7 98%); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + min-width: 74px; +} + +.mytheme .v-progressbar-indicator { + border-radius: 4px; + height: inherit; + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + + + border: 1px solid #1362b1; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + max-width: 100%; + min-width: 8px; + -webkit-transition: width 160ms; + -moz-transition: width 160ms; + transition: width 160ms; +} + +.mytheme .v-progressbar-point .v-progressbar-indicator { + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; + border: none; + text-align: right; + overflow: hidden; +} + +.mytheme .v-progressbar-point .v-progressbar-indicator:before { + content: ""; + display: inline-block; + border-radius: 4px; + height: inherit; + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + + + border: 1px solid #1362b1; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + max-width: 100%; + width: 9px; + vertical-align: top; +} + +.mytheme .v-progressbar-indeterminate { + height: 24px !important; + width: 24px !important; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + border: 2px solid rgba(25, 125, 225, 0.2); + border-top-color: #197de1; + border-right-color: #197de1; + border-radius: 100%; + -webkit-animation: v-rotate-360 500ms infinite linear; + -moz-animation: v-rotate-360 500ms infinite linear; + animation: v-rotate-360 500ms infinite linear; + pointer-events: none; +} + +.v-ie8 .mytheme .v-progressbar-indeterminate, .v-ie9 .mytheme .v-progressbar-indeterminate { + border: none; + border-radius: 4px; + background: #fff url(../valo/shared/img/spinner.gif) no-repeat 50% 50%; + background-size: 80%; +} + +.v-ie8 .mytheme .v-progressbar-indeterminate { + min-width: 30px; + min-height: 30px; +} + +.mytheme .v-progressbar-indeterminate .v-progressbar-wrapper { + display: none; +} + +.mytheme .v-slider { + position: relative; +} + +.mytheme .v-slider:focus { + outline: none; +} + +.mytheme .v-slider:focus .v-slider-handle:after { + opacity: 1; +} + +.v-ie8 .mytheme .v-slider:focus .v-slider-handle:after { + visibility: visible; +} + +.mytheme .v-slider.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-slider-base { + border-radius: 4px; + height: 9px; + background-color: #d4d4d4; + background-image: -webkit-linear-gradient(bottom, #d7d7d7 2%, #c7c7c7 98%); + background-image: linear-gradient(to top,#d7d7d7 2%, #c7c7c7 98%); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + min-width: 74px; + height: 6px; + margin: 16px 11px; + white-space: nowrap; + overflow: hidden; + +} + +.mytheme .v-slider-base:before { + content: ""; + position: absolute; + top: 16px; + bottom: 16px; + left: 11px; + width: 8px; + border-radius: 4px; + border-left: 1px solid #1362b1; +} + +.mytheme .v-slider-base:after { + border-radius: 4px; + height: inherit; + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + + + border: 1px solid #1362b1; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + max-width: 100%; + content: ""; + display: inline-block; + margin-left: -100%; + width: 100%; + vertical-align: top; +} + +.v-ie8 .mytheme .v-slider-base:after { + position: relative; + left: -11px; +} + +.mytheme .v-has-width > .v-slider-base { + min-width: 0; +} + +.mytheme .v-slider-handle { + margin-top: -16px; + width: 0.1px; + display: inline-block; + vertical-align: top; +} + +.mytheme .v-slider-handle:before { + height: 37px; + padding: 0 16px; + color: #191919; + font-weight: 400; + + + border-radius: 4px; + border: 1px solid #c5c5c5; + border-top-color: #c5c5c5; + border-bottom-color: #bcbcbc; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7, 0 2px 3px rgba(0, 0, 0, 0.05); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); +} + +.mytheme .v-slider-handle:before:after { + border: inherit; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; +} + +.mytheme .v-slider-handle:before:hover:after { + background-color: rgba(186, 186, 186, 0.1); +} + +.mytheme .v-slider-handle:before:focus:after { + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-slider-handle:before:active:after { + background-color: rgba(125, 125, 125, 0.2); +} + +.mytheme .v-slider-handle:after { + border: 1px solid #c5c5c5; + border-color: #197de1; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + opacity: 0; + -webkit-transition: opacity 200ms; + -moz-transition: opacity 200ms; + transition: opacity 200ms; +} + +.v-ie8 .mytheme .v-slider-handle:after { + visibility: hidden; +} + +.mytheme .v-slider-handle:before, .mytheme .v-slider-handle:after { + content: ""; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; + width: 22px; + height: 22px; + border-radius: 11px; + position: absolute; + z-index: 1; + margin-top: 8px; + margin-left: -11px; +} + +.mytheme .v-slider-feedback { + background-color: #323232; + background-color: rgba(50, 50, 50, 0.9); + -webkit-box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2); + color: white; + padding: 5px 9px; + border-radius: 3px; + max-width: 35em; + overflow: hidden !important; + font-size: 14px; +} + +.mytheme .v-slider-vertical { + padding: 11px 0; + height: 96px; +} + +.mytheme .v-slider-vertical .v-slider-base { + background-color: #d4d4d4; + background-image: -webkit-linear-gradient(right, #d7d7d7 2%, #c7c7c7 98%); + background-image: linear-gradient(to left,#d7d7d7 2%, #c7c7c7 98%); + width: 6px; + height: 100% !important; + min-width: 0; + margin: 0 16px; +} + +.mytheme .v-slider-vertical .v-slider-base:before { + top: auto; + bottom: 11px; + left: 16px; + right: 16px; + width: auto; + height: 8px; + border-left: none; + border-bottom: 1px solid #1362b1; +} + +.mytheme .v-slider-vertical .v-slider-base:after { + height: 101%; + margin-left: 0; + background-color: #197de1; + background-image: -webkit-linear-gradient(left, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to right,#1b87e3 2%, #166ed5 98%); +} + +.v-ie8 .mytheme .v-slider-vertical .v-slider-base:after { + top: 11px; + left: 0; + height: 130%; +} + +.mytheme .v-slider-vertical .v-slider-handle { + width: 0; + height: 0.1px; + width: 37px; + display: block; +} + +.mytheme .v-slider-vertical .v-slider-handle:before, .mytheme .v-slider-vertical .v-slider-handle:after { + width: 22px; + height: 22px; + margin-top: -11px; + margin-left: -8px; +} + +.mytheme .v-slider-no-indicator .v-slider-base:before, .mytheme .v-slider-no-indicator .v-slider-base:after { + display: none; +} + +.mytheme .v-tabsheet:not(.v-has-width) { + width: auto !important; +} + +.mytheme .v-tabsheet-spacertd { + display: none !important; +} + +.mytheme .v-tabsheet-tabcontainer { + position: relative; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.mytheme .v-tabsheet-tabcontainer:before { + content: ""; + position: absolute; + height: 0; + border-top: 1px solid #dfdfdf; + bottom: 0; + left: 0; + right: 0; +} + +.mytheme .v-tabsheet-tabcontainer .v-tabsheet-tabs { + position: relative; +} + +.mytheme .v-tabsheet-tabitemcell { + vertical-align: bottom; +} + +.mytheme .v-tabsheet-tabitemcell .v-tabsheet-tabitem { + line-height: 0; + overflow: hidden; +} + +.mytheme .v-tabsheet-tabitemcell .v-caption { + margin-left: 19px; + padding: 0 4px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer; + text-align: center; + line-height: 37px; + font-size: 15px; + font-weight: 300; + color: #696969; + width: auto !important; + overflow: hidden; + text-overflow: ellipsis; + border-bottom: 2px solid transparent; + position: relative; + -webkit-transition: border-bottom 200ms, color 200ms; + -moz-transition: border-bottom 200ms, color 200ms; + transition: border-bottom 200ms, color 200ms; +} + +.mytheme .v-tabsheet-tabitemcell .v-caption .v-captiontext { + display: inline; +} + +.mytheme .v-tabsheet-tabitemcell .v-caption .v-icon + .v-captiontext { + margin-left: 9px; +} + +.mytheme .v-tabsheet-tabitemcell .v-caption:hover { + color: #197de1; +} + +.mytheme .v-tabsheet-tabitemcell .v-caption.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; + cursor: default; + color: inherit !important; +} + +.mytheme .v-tabsheet-tabitemcell:first-child .v-caption, .mytheme .v-tabsheet-tabitemcell[aria-hidden="true"] + td .v-caption { + margin-left: 0; +} + +.mytheme .v-tabsheet-tabitemcell:focus { + outline: none; +} + +.mytheme .v-tabsheet-tabitemcell:focus .v-caption { + color: #197de1; +} + +.mytheme .v-tabsheet-tabitemcell .v-tabsheet-tabitem-selected .v-caption.v-caption { + border-bottom-color: #197de1; + color: #197de1; +} + +.mytheme .v-tabsheet-tabitemcell .v-caption-closable { + padding-right: 22px; +} + +.mytheme .v-tabsheet-tabitemcell.icons-on-top .v-caption-closable { + padding-right: 4px; +} + +.mytheme .v-tabsheet-tabitemcell .v-tabsheet-caption-close { + position: absolute; + right: 0; + top: 50%; + margin: -8px 0 0; + font-size: 18px; + line-height: 18px; + width: 18px; + text-align: center; + border-radius: 2px; + color: #969696; +} + +.mytheme .v-tabsheet-tabitemcell .v-tabsheet-caption-close:hover { + background: rgba(0, 0, 0, 0.03); + color: #197de1; +} + +.mytheme .v-tabsheet-tabitemcell .v-tabsheet-caption-close:active { + background: #197de1; + color: #c8dbed; +} + +.mytheme .v-tabsheet-scroller { + position: absolute; + top: 0; + right: 0; + bottom: 0; + padding-left: 19px; + background-color: transparent; + background-image: -webkit-linear-gradient(right, #fafafa 70%, rgba(250, 250, 250, 0) 100%); + background-image: linear-gradient(to left,#fafafa 70%, rgba(250, 250, 250, 0) 100%); + pointer-events: none; +} + +.mytheme .v-tabsheet-scroller:after { + content: ""; + height: 1px; + position: absolute; + bottom: 0; + left: 0; + right: 0; + display: block; + background-color: transparent; + background-image: -webkit-linear-gradient(right, #dfdfdf 70%, rgba(223, 223, 223, 0) 100%); + background-image: linear-gradient(to left,#dfdfdf 70%, rgba(223, 223, 223, 0) 100%); +} + +.v-ie8 .mytheme .v-tabsheet-scroller, .v-ie9 .mytheme .v-tabsheet-scroller { + background-color: #fafafa; +} + +.v-ie8 .mytheme .v-tabsheet-scroller:after, .v-ie9 .mytheme .v-tabsheet-scroller:after { + background-color: #dfdfdf; +} + +.mytheme .v-tabsheet-scroller button { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + border: none; + background: transparent; + font: inherit; + color: inherit; + height: 100%; + margin: 0; + padding: 0 9px; + outline: none; + cursor: pointer; + pointer-events: auto; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-tabsheet-scroller button:hover { + opacity: 1; + filter: none ; + color: #197de1; +} + +.mytheme .v-tabsheet-scroller button:active { + opacity: 0.7; + filter: alpha(opacity=70) ; + color: #197de1; +} + +.mytheme .v-tabsheet-scroller button::-moz-focus-inner { + padding: 0; + border: 0; +} + +.mytheme .v-tabsheet-scroller [class*="Next"] { + padding-left: 5px; +} + +.mytheme .v-tabsheet-scroller [class*="Next"]:before { + font-family: ThemeIcons; + content: "\f054"; +} + +.mytheme .v-tabsheet-scroller [class*="Prev"] { + padding-right: 5px; +} + +.mytheme .v-tabsheet-scroller [class*="Prev"]:before { + font-family: ThemeIcons; + content: "\f053"; +} + +.mytheme .v-tabsheet-scroller [class*="disabled"] { + cursor: default; + color: inherit !important; + opacity: 0.1 !important; + filter: alpha(opacity=10) !important; +} + +.mytheme .v-tabsheet-tabsheetpanel > .v-scrollable > .v-widget { + -webkit-animation: valo-animate-in-fade 300ms backwards; + -moz-animation: valo-animate-in-fade 300ms backwards; + animation: valo-animate-in-fade 300ms backwards; +} + +.mytheme .v-tabsheet-deco { + height: 20px !important; + width: 20px !important; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + border: 2px solid rgba(25, 125, 225, 0.2); + border-top-color: #197de1; + border-right-color: #197de1; + border-radius: 100%; + -webkit-animation: v-rotate-360 500ms infinite linear; + -moz-animation: v-rotate-360 500ms infinite linear; + animation: v-rotate-360 500ms infinite linear; + pointer-events: none; + display: none; + position: absolute; + z-index: 1; + bottom: 50%; + margin-bottom: -29px; + left: 50%; + margin-left: -10px; +} + +.v-ie8 .mytheme .v-tabsheet-deco, .v-ie9 .mytheme .v-tabsheet-deco { + border: none; + border-radius: 4px; + background: #fff url(../valo/shared/img/spinner.gif) no-repeat 50% 50%; + background-size: 80%; +} + +.v-ie8 .mytheme .v-tabsheet-deco { + min-width: 30px; + min-height: 30px; +} + +.mytheme .v-tabsheet-loading .v-tabsheet-deco { + display: block; +} + +.mytheme .v-tabsheet-equal-width-tabs > .v-tabsheet-tabcontainer table, .mytheme .v-tabsheet-equal-width-tabs > .v-tabsheet-tabcontainer tbody, .mytheme .v-tabsheet-equal-width-tabs > .v-tabsheet-tabcontainer tr { + width: 100%; +} + +.mytheme .v-tabsheet-equal-width-tabs > .v-tabsheet-tabcontainer tr { + display: table; + table-layout: fixed; +} + +.mytheme .v-tabsheet-equal-width-tabs > .v-tabsheet-tabcontainer td { + display: table-cell; +} + +.mytheme .v-tabsheet-equal-width-tabs > .v-tabsheet-tabcontainer .v-caption { + margin: 0; + display: block; +} + +.mytheme .v-tabsheet-framed > .v-tabsheet-tabcontainer .v-caption { + margin-left: 4px; + padding: 0 12px; + background-color: #fafafa; + border: 1px solid transparent; + line-height: 36px; + border-radius: 4px 4px 0 0; + font-weight: 400; + -webkit-transition: background-color 160ms; + -moz-transition: background-color 160ms; + transition: background-color 160ms; +} + +.mytheme .v-tabsheet-framed > .v-tabsheet-tabcontainer .v-caption:hover { + background-color: #f2f2f2; + border-bottom-color: #dfdfdf; +} + +.mytheme .v-tabsheet-framed > .v-tabsheet-tabcontainer .v-caption.v-disabled:hover { + background-color: #fafafa; +} + +.mytheme .v-tabsheet-framed > .v-tabsheet-tabcontainer .v-caption-closable { + padding-right: 30px; +} + +.mytheme .v-tabsheet-framed > .v-tabsheet-tabcontainer .v-tabsheet-caption-close { + top: 4px; + right: 4px; + margin-top: 0; +} + +.mytheme .v-tabsheet-framed > .v-tabsheet-tabcontainer td:first-child .v-caption, .mytheme .v-tabsheet-framed > .v-tabsheet-tabcontainer [aria-hidden="true"] + td .v-caption { + margin-left: 0; +} + +.mytheme .v-tabsheet-framed > .v-tabsheet-tabcontainer .v-tabsheet-tabitem .v-caption { + border-color: #dfdfdf; +} + +.mytheme .v-tabsheet-framed > .v-tabsheet-tabcontainer .v-tabsheet-tabitem-selected .v-caption { + background: white; + border-color: #dfdfdf; + border-bottom: none; + padding-bottom: 1px; +} + +.mytheme .v-tabsheet-framed > .v-tabsheet-content { + border: 1px solid #dfdfdf; + border-top: none; +} + +.mytheme .v-tabsheet-framed > .v-tabsheet-content > div { + background: white; +} + +.mytheme .v-tabsheet-framed.padded-tabbar > .v-tabsheet-tabcontainer { + border: 1px solid #dfdfdf; + border-bottom: none; + background: #fafafa; + padding-top: 6px; +} + +.mytheme .v-tabsheet-framed.icons-on-top > .v-tabsheet-tabcontainer .v-tabsheet-tabitem-selected .v-caption { + padding-bottom: 7px; +} + +.mytheme .v-tabsheet-centered-tabs > .v-tabsheet-tabcontainer { + text-align: center; +} + +.mytheme .v-tabsheet-right-aligned-tabs > .v-tabsheet-tabcontainer { + text-align: right; +} + +.mytheme .v-tabsheet-padded-tabbar > .v-tabsheet-tabcontainer .v-tabsheet-tabs { + padding: 0 9px; +} + +.mytheme .v-tabsheet-icons-on-top > .v-tabsheet-tabcontainer .v-caption { + padding-top: 6px; + padding-bottom: 6px; + line-height: 1.2; +} + +.mytheme .v-tabsheet-icons-on-top > .v-tabsheet-tabcontainer .v-icon { + display: block; +} + +.mytheme .v-tabsheet-icons-on-top > .v-tabsheet-tabcontainer .v-icon + .v-captiontext.v-captiontext { + margin-left: 0; +} + +.mytheme .v-tabsheet-icons-on-top > .v-tabsheet-tabcontainer .v-caption-closable { + padding-right: 12px; +} + +.mytheme .v-tabsheet-icons-on-top > .v-tabsheet-tabcontainer .v-tabsheet-caption-close { + top: 4px; + margin-top: 0; +} + +.mytheme .v-tabsheet-compact-tabbar > .v-tabsheet-tabcontainer-compact-tabbar .v-caption { + line-height: 1.8; +} + +.mytheme .v-tabsheet-only-selected-closable > .v-tabsheet-tabcontainer .v-tabsheet-caption-close { + visibility: hidden; +} + +.mytheme .v-tabsheet-only-selected-closable > .v-tabsheet-tabcontainer .v-tabsheet-tabitem-selected .v-tabsheet-caption-close { + visibility: visible; +} + +.mytheme .v-colorpicker-popup.v-window { + min-width: 220px !important; +} + +.mytheme .v-colorpicker-popup .v-tabsheet-tabs { + padding: 0 9px; +} + +.mytheme .v-colorpicker-popup [class$="sliders"] { + padding: 12px; +} + +.mytheme .v-colorpicker-popup [class$="sliders"] .v-widget { + width: 100% !important; + vertical-align: middle; +} + +.mytheme .v-colorpicker-popup [class$="sliders"] .v-has-caption { + white-space: nowrap; + padding-left: 48px; +} + +.mytheme .v-colorpicker-popup [class$="sliders"] .v-caption { + display: inline-block; + margin-left: -48px; + width: 48px; +} + +.mytheme .v-colorpicker-popup [class$="sliders"] .v-slot-hue-slider + .v-slot .v-has-caption { + padding-left: 80px; +} + +.mytheme .v-colorpicker-popup [class$="sliders"] .v-slot-hue-slider + .v-slot .v-caption { + margin-left: -80px; + width: 80px; +} + +.mytheme .v-colorpicker-popup .v-slider-red .v-slider-base:after { + background: red; + border: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-colorpicker-popup .v-slider-green .v-slider-base:after { + background: green; + border: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-colorpicker-popup .v-slider-blue .v-slider-base:after { + background: blue; + border: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-colorpicker-popup .v-margin-bottom { + padding-bottom: 0; +} + +.mytheme .v-colorpicker-popup .resize-button { + width: 100% !important; + height: auto !important; + text-align: center; + outline: none; +} + +.mytheme .v-colorpicker-popup .resize-button:before { + font-family: ThemeIcons; + content: "\f141"; +} + +.mytheme .v-colorpicker-popup .resize-button-caption { + display: none; +} + +.mytheme .v-colorpicker-popup .v-horizontallayout { + height: auto !important; + padding: 9px 0; + background-color: #fafafa; + border-top: 1px solid #ededed; +} + +.mytheme .v-colorpicker-popup .v-horizontallayout .v-expand { + overflow: visible; +} + +.mytheme .v-colorpicker-popup .v-horizontallayout .v-button { + width: 80% !important; +} + +.mytheme .v-colorpicker-preview { + width: 100% !important; + height: auto !important; + padding: 9px; +} + +.mytheme .v-colorpicker-preview-textfield { + height: auto !important; + text-align: center; + border: none; +} + +.mytheme .v-colorpicker { + width: auto; +} + +.mytheme .v-colorpicker-button-color { + position: absolute; + top: 6px; + right: 6px; + bottom: 6px; + left: 6px; + border-radius: 3px; + border: 1px solid rgba(0, 0, 0, 0.5); + max-width: 23px; +} + +.mytheme .v-colorpicker-button-color + .v-button-caption:not(:empty) { + margin-left: 19px; +} + +.v-ie8 .mytheme .v-colorpicker-button-color { + position: relative; + top: auto; + right: auto; + bottom: auto; + left: auto; + width: 16px; + height: 16px; + display: inline-block; + vertical-align: middle; + margin: 0 -8px; +} + +.v-ie8 .mytheme .v-colorpicker-button-color + .v-button-caption { + margin-left: 19px; +} + +.mytheme .v-panel { + background: white; + color: #474747; + border-radius: 4px; + border: 1px solid #d5d5d5; + -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + overflow: visible !important; +} + +.mytheme .v-panel-caption { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0 12px; + line-height: 36px; + border-bottom: 1px solid #d5d5d5; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #f6f6f6 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #f6f6f6 98%); + color: #464646; + font-weight: 400; + font-size: 14px; + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #eeeeee; + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #eeeeee; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + border-radius: 3px 3px 0 0; +} + +.mytheme .v-panel-content { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + width: 100%; + height: 100%; +} + +.mytheme .v-panel-content > .v-margin-top { + padding-top: 12px; +} + +.mytheme .v-panel-content > .v-margin-right { + padding-right: 12px; +} + +.mytheme .v-panel-content > .v-margin-bottom { + padding-bottom: 12px; +} + +.mytheme .v-panel-content > .v-margin-left { + padding-left: 12px; +} + +.mytheme .v-panel-borderless { + background: transparent; + color: inherit; + border: none; + border-radius: 0; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-panel-borderless > div > [class*="-caption"] { + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; + color: inherit; + padding: 0; + margin: 0 12px; + border-bottom: none; +} + +.mytheme .v-panel-well { + background: #f5f5f5; + color: #454545; + -webkit-box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.05), inset 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.05), inset 0 2px 3px rgba(0, 0, 0, 0.05); + border-radius: 4px; + border: 1px solid #c5c5c5; +} + +.mytheme .v-panel-well > div > [class*="-caption"] { + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-panel-scroll-divider > [class*="-captionwrap"] { + position: relative; + z-index: 2; +} + +.mytheme .v-panel-scroll-divider > [class*="-captionwrap"]:after { + content: ""; + position: absolute; + bottom: -1px; + right: 0; + left: 0; + height: 0; + border-top: 1px solid #dfdfdf; + border-color: rgba(197, 197, 197, 0.5); +} + +.mytheme .v-panel-scroll-divider > [class*="-content"]:before { + content: ""; + position: absolute; + z-index: 2; + top: 0; + height: 0; + border-top: 1px solid #fafafa; + left: 0; + right: 0; +} + +.mytheme .v-panel-caption.v-horizontallayout { + height: auto !important; + line-height: 0; +} + +.mytheme .v-panel-caption.v-horizontallayout .v-slot { + vertical-align: middle; +} + +.mytheme .v-panel-caption.v-horizontallayout .v-label { + line-height: 37px; +} + +.mytheme .v-accordion { + background: white; + color: #474747; + border-radius: 4px; + border: 1px solid #d5d5d5; + -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #f4f4f4 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #f4f4f4 98%); + overflow: hidden; +} + +.mytheme .v-accordion-item { + position: relative; +} + +.mytheme .v-accordion-item:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} + +.mytheme .v-accordion-item:last-child { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; +} + +.mytheme .v-accordion-item:last-child [class*="item-content"] { + border-radius: inherit; +} + +.mytheme .v-accordion-item[class*="item-open"]:last-child > div > .v-caption { + border-radius: 0; +} + +.mytheme .v-accordion-item:not([class*="item-open"]):last-child > div > .v-caption { + border-bottom: none; + margin-bottom: 0; +} + +.mytheme .v-accordion-item[class*="item-open"] + [class*="item"] { + border-top: 1px solid #d9d9d9; +} + +.mytheme .v-accordion-item-caption { + border-radius: inherit; +} + +.mytheme .v-accordion-item-caption > .v-caption { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0 12px; + line-height: 36px; + border-bottom: 1px solid #d5d5d5; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #f6f6f6 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #f6f6f6 98%); + color: #464646; + font-weight: 400; + font-size: 14px; + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #eeeeee; + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #eeeeee; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); + display: block; + background: transparent; + border-bottom-color: #c9c9c9; + border-radius: inherit; + cursor: pointer; + position: relative; +} + +.mytheme .v-accordion-item-caption > .v-caption:hover:before, .mytheme .v-accordion-item-caption > .v-caption:active:before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: inherit; +} + +.mytheme .v-accordion-item-caption > .v-caption:hover:before { + background-color: rgba(186, 186, 186, 0.1); + border: none; +} + +.mytheme .v-accordion-item-caption > .v-caption:active:before { + background-color: rgba(125, 125, 125, 0.2); +} + +.mytheme .v-accordion-item-content { + -webkit-box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.05); + background-color: white; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.mytheme .v-accordion-item-content > .v-margin-top { + padding-top: 12px; +} + +.mytheme .v-accordion-item-content > .v-margin-right { + padding-right: 12px; +} + +.mytheme .v-accordion-item-content > .v-margin-bottom { + padding-bottom: 12px; +} + +.mytheme .v-accordion-item-content > .v-margin-left { + padding-left: 12px; +} + +.mytheme .v-accordion-borderless { + border: none; + border-radius: 0; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mytheme .v-accordion-borderless > .v-accordion-item, .mytheme .v-accordion-borderless > .v-accordion-item > div > .v-caption, .mytheme .v-accordion-borderless > .v-accordion-item > .v-accordion-item-content { + border-radius: 0; +} + +.mytheme .v-select-twincol { + white-space: normal; +} + +.mytheme .v-select-twincol select { + border: 1px solid #c5c5c5; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + color: #464646; +} + +.mytheme .v-select-twincol select:focus { + outline: none; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-select-twincol .v-textfield, .mytheme .v-select-twincol .v-nativebutton { + width: auto !important; + margin-top: 9px; +} + +.mytheme .v-select-twincol .v-nativebutton { + margin-left: 9px; +} + +.mytheme .v-select-twincol-caption-left, .mytheme .v-select-twincol-caption-right { + font-size: 14px; + font-weight: 400; + padding-bottom: 0.3em; + padding-left: 1px; +} + +.mytheme .v-select-twincol-buttons { + white-space: nowrap; + display: inline-block; + vertical-align: top; + position: relative; + min-width: 3.5em; +} + +.mytheme .v-select-twincol-buttons .v-button { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + display: inline-block; + vertical-align: top; + text-align: left; + white-space: normal; + position: absolute; + left: 9px; + right: 9px; + top: 36px; + padding: 0; + text-align: center; +} + +.mytheme .v-select-twincol-buttons .v-button:first-child { + top: 0; +} + +.mytheme .v-select-twincol-buttons .v-button-caption { + display: none; +} + +.mytheme .v-select-twincol-buttons .v-button:focus { + z-index: 1; +} + +.mytheme .v-select-twincol-buttons .v-button:first-child { + border-radius: 4px 4px 0 0; +} + +.mytheme .v-select-twincol-buttons .v-button:last-child { + border-radius: 0 0 4px 4px; +} + +.mytheme .v-select-twincol-buttons .v-button-wrap:before { + font-family: ThemeIcons; + content: "\f053"; +} + +.mytheme .v-select-twincol-buttons .v-button:first-child .v-button-wrap:before { + font-family: ThemeIcons; + content: "\f054"; +} + +.mytheme .v-select-twincol-error .v-select-twincol-options, .mytheme .v-select-twincol-error .v-select-twincol-selections { + border-color: #ed473b !important; + background: #fffbfb; + color: #6c2621; +} + +.mytheme .v-select select { + border: 1px solid #c5c5c5; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + color: #464646; +} + +.mytheme .v-select select:focus { + outline: none; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-select-select { + display: block; +} + +.mytheme .v-select-select + .v-textfield { + width: auto !important; + margin-top: 9px; +} + +.mytheme .v-select-select + .v-textfield + .v-nativebutton { + margin-top: 9px; + margin-left: 9px; +} + +.mytheme .v-select-error .v-select-select { + border-color: #ed473b !important; + background: #fffbfb; + color: #6c2621; +} + +.mytheme .v-calendar-header-day { + font-weight: 400; + text-align: center; + padding: 7px 0; +} + +.mytheme .v-calendar-header-week .v-calendar-back, .mytheme .v-calendar-header-week .v-calendar-next { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + background: transparent; + border: none; + padding: 0; + margin: 0; + cursor: pointer; + outline: none; + color: inherit; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-calendar-header-week .v-calendar-back:focus, .mytheme .v-calendar-header-week .v-calendar-next:focus { + outline: none; +} + +.mytheme .v-calendar-header-week .v-calendar-back:hover, .mytheme .v-calendar-header-week .v-calendar-next:hover { + opacity: 1; + filter: none ; +} + +.mytheme .v-calendar-header-week .v-calendar-back:active, .mytheme .v-calendar-header-week .v-calendar-next:active { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-calendar-header-week .v-calendar-back:before { + font-family: ThemeIcons; + content: "\f053"; +} + +.mytheme .v-calendar-header-week .v-calendar-next:before { + font-family: ThemeIcons; + content: "\f054"; +} + +.mytheme .v-calendar-month { + outline: none; + overflow: hidden; +} + +.mytheme .v-calendar-month td { + vertical-align: top; +} + +.mytheme .v-calendar-week-number { + cursor: pointer; + width: 20px; + text-align: center; + font-size: 0.8em; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-calendar-week-number:hover { + opacity: 1; + filter: none ; +} + +.mytheme .v-calendar-month-day { + outline: none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + line-height: 1.2; +} + +.mytheme .v-calendar-bottom-spacer, .mytheme .v-calendar-spacer, .mytheme .v-calendar-bottom-spacer-empty { + height: 19px; + margin-bottom: 3px; +} + +.mytheme .v-calendar-bottom-spacer { + font-size: 0.8em; + padding: 0 5px; + cursor: pointer; +} + +.mytheme .v-calendar-bottom-spacer:hover { + color: #197de1; +} + +.mytheme .v-calendar-day-number { + line-height: 25px; + font-size: 16px; + text-align: right; + margin: 0 5px; + white-space: nowrap; + border-top: 1px solid #f2f2f2; + cursor: pointer; +} + +.mytheme .v-calendar-day-number:hover { + color: #197de1; +} + +.mytheme .v-calendar-month-day-today { + background: #eef3f8; +} + +.mytheme .v-calendar-month-day-today .v-calendar-day-number { + font-weight: 400; + color: #197de1; + border-top: 2px solid #197de1; + line-height: 24px; + margin: 0; + padding: 0 5px; +} + +.mytheme .v-calendar-month-day-selected { + background-color: #e3edf7; +} + +.mytheme .v-calendar-month-day-dragemphasis { + background-color: #a8a8a8; +} + +.mytheme .v-calendar-month-day-scrollable { + overflow-y: scroll; +} + +.mytheme .v-calendar-weekly-longevents { + margin-left: 50px; + border-bottom: 3px solid #e0e0e0; +} + +.mytheme .v-calendar-weekly-longevents .v-calendar-event-all-day { + height: 22px; + line-height: 1.6; + margin-bottom: 3px; +} + +.mytheme .v-calendar-header-week td { + vertical-align: middle !important; +} + +.mytheme .v-calendar-header-week .v-calendar-header-day { + cursor: pointer; +} + +.mytheme .v-calendar-times { + width: 50px; + font-size: 0.77em; + line-height: 1; + white-space: nowrap; +} + +.mytheme .v-calendar-time { + text-align: right; + padding-right: 9px; + margin-top: -6px; + padding-bottom: 6px; +} + +.mytheme .v-calendar-day-times, .mytheme .v-calendar-day-times-today { + outline: none; + border-right: 1px solid transparent; +} + +.mytheme .v-calendar-day-times:focus, .mytheme .v-calendar-day-times-today:focus { + outline: none; +} + +.mytheme .v-calendar .v-datecellslot, .mytheme .v-calendar .v-datecellslot-even { + border-top: 1px solid #dfdfdf; +} + +.mytheme .v-calendar .v-datecellslot:first-child, .mytheme .v-calendar .v-datecellslot-even:first-child { + border-top-color: transparent; +} + +.mytheme .v-calendar .v-datecellslot { + border-top-style: dotted; +} + +.mytheme .v-calendar .v-datecellslot, .mytheme .v-calendar .v-datecellslot-even { + margin-right: 5px; +} + +.mytheme .v-calendar-current-time { + background: #197de1; + line-height: 1px; + pointer-events: none; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-calendar-current-time:before { + content: "\2022"; + color: #197de1; + font-size: 22px; + margin-left: -0.07em; +} + +.mytheme .v-calendar .v-daterange { + position: relative; +} + +.mytheme .v-calendar .v-daterange:before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: -1px; + left: 0; + background: #197de1; + opacity: 0.5; + filter: alpha(opacity=50) ; + border-radius: 4px 4px 0 0; +} + +.mytheme .v-calendar .v-daterange + .v-daterange { + border-color: transparent; +} + +.mytheme .v-calendar .v-daterange + .v-daterange:before { + border-radius: 0; +} + +.mytheme .v-calendar-event { + font-size: 0.85em; + overflow: hidden; + cursor: pointer; + outline: none; + border-radius: 4px; +} + +.mytheme .v-calendar-event:focus { + outline: none; +} + +.mytheme .v-calendar-event-month { + padding: 0 5px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + margin-bottom: 3px; + white-space: nowrap; + text-overflow: ellipsis; + height: 19px; + line-height: 19px; +} + +.mytheme .v-calendar-event-month .v-calendar-event-time { + float: right; + font-size: 0.9em; + line-height: 19px; + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-calendar-event-month:before { + content: "\25cf"; + margin-right: 0.2em; +} + +.mytheme .v-calendar-event-all-day { + padding: 0 5px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + height: 19px; + line-height: 19px; + border-radius: 0; + margin-left: -1px; + white-space: nowrap; +} + +.mytheme .v-calendar-event-all-day:before { + content: ""; +} + +.mytheme .v-calendar-event-start { + overflow: visible; + margin-left: 0; +} + +.mytheme .v-calendar-event-start.v-calendar-event-continued-to, .mytheme .v-calendar-event-start.v-calendar-event-end { + overflow: hidden; + text-overflow: ellipsis; +} + +.mytheme .v-calendar-event-start { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + margin-left: 5px; +} + +.mytheme .v-calendar-event-end { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + margin-right: 5px; +} + +.mytheme .v-calendar-event-caption { + font-weight: 500; + line-height: 1.2; + padding: 5px 0; + position: absolute; + overflow: hidden; + right: 9px; + left: 5px; + bottom: 0; + top: 0; +} + +.mytheme .v-calendar-event-caption span { + font-weight: 300; + white-space: nowrap; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event { + overflow: visible; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event-content { + margin-top: -1px; + border-radius: 5px; + border: 1px solid #fafafa; + padding-top: 3px; + margin-right: 5px; +} + +.mytheme .v-calendar-event-month:before { + color: #00ace0; +} + +.mytheme .v-calendar-event-all-day { + background-color: #c8eaf4; + background-color: rgba(200, 234, 244, 0.8); + color: #00ace0; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event { + color: #00ace0; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event .v-calendar-event-content { + background-color: #c8eaf4; + background-color: rgba(200, 234, 244, 0.8); +} + +.mytheme .v-calendar-event-month[class*="color2"]:before { + color: #2d9f19; +} + +.mytheme .v-calendar-event-all-day[class*="color2"] { + background-color: #d1e7cd; + background-color: rgba(209, 231, 205, 0.8); + color: #2d9f19; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event[class*="color2"] { + color: #2d9f19; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event[class*="color2"] .v-calendar-event-content { + background-color: #d1e7cd; + background-color: rgba(209, 231, 205, 0.8); +} + +.mytheme .v-calendar-event-month[class*="color3"]:before { + color: #d18100; +} + +.mytheme .v-calendar-event-all-day[class*="color3"] { + background-color: #f1e1c8; + background-color: rgba(241, 225, 200, 0.8); + color: #d18100; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event[class*="color3"] { + color: #d18100; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event[class*="color3"] .v-calendar-event-content { + background-color: #f1e1c8; + background-color: rgba(241, 225, 200, 0.8); +} + +.mytheme .v-calendar-event-month[class*="color4"]:before { + color: #ce3812; +} + +.mytheme .v-calendar-event-all-day[class*="color4"] { + background-color: #f1d3cb; + background-color: rgba(241, 211, 203, 0.8); + color: #ce3812; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event[class*="color4"] { + color: #ce3812; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event[class*="color4"] .v-calendar-event-content { + background-color: #f1d3cb; + background-color: rgba(241, 211, 203, 0.8); +} + +.mytheme .v-calendar-event-month[class*="color5"]:before { + color: #2d55cd; +} + +.mytheme .v-calendar-event-all-day[class*="color5"] { + background-color: #d1d9f1; + background-color: rgba(209, 217, 241, 0.8); + color: #2d55cd; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event[class*="color5"] { + color: #2d55cd; +} + +.mytheme .v-calendar-week-wrapper .v-calendar-event[class*="color5"] .v-calendar-event-content { + background-color: #d1d9f1; + background-color: rgba(209, 217, 241, 0.8); +} + +.mytheme .v-calendar.v-disabled * { + cursor: default; +} + +.mytheme .v-label { + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; +} + +.mytheme .v-label.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-label-undef-w { + white-space: nowrap; +} + +.mytheme h1, .mytheme .v-label-h1, .mytheme h2, .mytheme .v-label-h2, .mytheme h3, .mytheme .v-label-h3 { + line-height: 1.1; + font-weight: 200; + color: #141414; +} + +.mytheme h1, .mytheme .v-label-h1 { + font-size: 2.4em; + margin-top: 1.4em; + margin-bottom: 1em; + + letter-spacing: -0.03em; +} + +.mytheme h2, .mytheme .v-label-h2 { + font-size: 1.6em; + + margin-top: 1.6em; + margin-bottom: 0.77em; + letter-spacing: -0.02em; +} + +.mytheme h3, .mytheme .v-label-h3 { + font-size: 1.2em; + + margin-top: 1.8em; + margin-bottom: 0.77em; + letter-spacing: 0; +} + +.mytheme h4, .mytheme .v-label-h4 { + line-height: 1.1; + font-weight: 500; + font-size: 14px; + color: #414141; + text-transform: uppercase; + letter-spacing: 0; + margin-top: 2.4em; + margin-bottom: 0.8em; +} + +.mytheme .v-csslayout > h1:first-child, .mytheme .v-csslayout > h2:first-child, .mytheme .v-csslayout > h3:first-child, .mytheme .v-csslayout > h4 > .v-label-h1:first-child, .mytheme .v-csslayout > .v-label-h2:first-child, .mytheme .v-csslayout > .v-label-h3:first-child, .mytheme .v-csslayout > .v-label-h4:first-child { + margin-top: 16px; +} + +.mytheme .v-verticallayout > .v-slot:first-child h1, .mytheme .v-verticallayout > .v-slot:first-child .v-label-h1, .mytheme .v-verticallayout > .v-slot:first-child h2, .mytheme .v-verticallayout > .v-slot:first-child .v-label-h2, .mytheme .v-verticallayout > .v-slot:first-child h3, .mytheme .v-verticallayout > .v-slot:first-child .v-label-h3, .mytheme .v-verticallayout > .v-slot:first-child h4, .mytheme .v-verticallayout > .v-slot:first-child .v-label-h4, .mytheme .v-verticallayout > div > .v-slot:first-child h1, .mytheme .v-verticallayout > div > .v-slot:first-child .v-label-h1, .mytheme .v-verticallayout > div > .v-slot:first-child h2, .mytheme .v-verticallayout > div > .v-slot:first-child .v-label-h2, .mytheme .v-verticallayout > div > .v-slot:first-child h3, .mytheme .v-verticallayout > div > .v-slot:first-child .v-label-h3, .mytheme .v-verticallayout > div > .v-slot:first-child h4, .mytheme .v-verticallayout > div > .v-slot:first-child .v-label-h4 { + margin-top: 16px; +} + +.mytheme .v-verticallayout > .v-slot:first-child .v-formlayout-contentcell h1, .mytheme .v-verticallayout > .v-slot:first-child .v-formlayout-contentcell .v-label-h1, .mytheme .v-verticallayout > .v-slot:first-child .v-formlayout-contentcell h2, .mytheme .v-verticallayout > .v-slot:first-child .v-formlayout-contentcell .v-label-h2, .mytheme .v-verticallayout > .v-slot:first-child .v-formlayout-contentcell h3, .mytheme .v-verticallayout > .v-slot:first-child .v-formlayout-contentcell .v-label-h3, .mytheme .v-verticallayout > .v-slot:first-child .v-formlayout-contentcell h4, .mytheme .v-verticallayout > .v-slot:first-child .v-formlayout-contentcell .v-label-h4, .mytheme .v-verticallayout > div > .v-slot:first-child .v-formlayout-contentcell h1, .mytheme .v-verticallayout > div > .v-slot:first-child .v-formlayout-contentcell .v-label-h1, .mytheme .v-verticallayout > div > .v-slot:first-child .v-formlayout-contentcell h2, .mytheme .v-verticallayout > div > .v-slot:first-child .v-formlayout-contentcell .v-label-h2, .mytheme .v-verticallayout > div > .v-slot:first-child .v-formlayout-contentcell h3, .mytheme .v-verticallayout > div > .v-slot:first-child .v-formlayout-contentcell .v-label-h3, .mytheme .v-verticallayout > div > .v-slot:first-child .v-formlayout-contentcell h4, .mytheme .v-verticallayout > div > .v-slot:first-child .v-formlayout-contentcell .v-label-h4 { + margin-top: -0.5em; +} + +.mytheme h1.no-margin, .mytheme .v-label-h1.no-margin, .mytheme h2.no-margin, .mytheme .v-label-h2.no-margin, .mytheme h3.no-margin, .mytheme .v-label-h3.no-margin, .mytheme h4.no-margin, .mytheme .v-label-h4.no-margin { + margin: 0 !important; +} + +.mytheme .v-label-colored { + color: #197de1; +} + +.mytheme .v-label-large { + font-size: 20px; +} + +.mytheme .v-label-small { + font-size: 14px; +} + +.mytheme .v-label-tiny { + font-size: 12px; +} + +.mytheme .v-label-huge { + font-size: 26px; +} + +.mytheme .v-label-bold { + font-weight: 500; +} + +.mytheme .v-label-light { + font-weight: 200; + color: #7d7d7d; +} + +.mytheme .v-label-align-right { + text-align: right; +} + +.mytheme .v-label-align-center { + text-align: center; +} + +.mytheme .v-label-spinner { + height: 24px !important; + width: 24px !important; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + border: 2px solid rgba(25, 125, 225, 0.2); + border-top-color: #197de1; + border-right-color: #197de1; + border-radius: 100%; + -webkit-animation: v-rotate-360 500ms infinite linear; + -moz-animation: v-rotate-360 500ms infinite linear; + animation: v-rotate-360 500ms infinite linear; + pointer-events: none; +} + +.v-ie8 .mytheme .v-label-spinner, .v-ie9 .mytheme .v-label-spinner { + border: none; + border-radius: 4px; + background: #fff url(../valo/shared/img/spinner.gif) no-repeat 50% 50%; + background-size: 80%; +} + +.v-ie8 .mytheme .v-label-spinner { + min-width: 30px; + min-height: 30px; +} + +.mytheme .v-label-success, .mytheme .v-label-failure { + background: white; + color: #474747; + border: 2px solid #2c9720; + border-radius: 4px; + padding: 7px 19px 7px 37px; + font-weight: 400; + font-size: 15px; +} + +.mytheme .v-label-success:before, .mytheme .v-label-failure:before { + font-family: ThemeIcons; + content: "\f00c"; + margin-right: 0.5em; + margin-left: -19px; + color: #2c9720; +} + +.mytheme .v-label-failure { + border-color: #ed473b; +} + +.mytheme .v-label-failure:before { + content: "\f05e"; + color: #ed473b; +} + +.mytheme [draggable=true] { + -khtml-user-drag: element; + -webkit-user-drag: element; +} + +.mytheme .v-ddwrapper { + position: relative; +} + +.mytheme .v-ddwrapper-over:before, .mytheme .v-ddwrapper-over:after { + content: ""; + position: absolute; + z-index: 10; + top: -1px; + right: -1px; + bottom: -1px; + left: -1px; + border: 0 solid #197de1; +} + +.mytheme .v-ddwrapper-over-top:before { + border-top-width: 2px; +} + +.mytheme .v-ddwrapper-over-right:before { + border-right-width: 2px; +} + +.mytheme .v-ddwrapper-over-bottom:before { + border-bottom-width: 2px; +} + +.mytheme .v-ddwrapper-over-left:before { + border-left-width: 2px; +} + +.mytheme .no-vertical-drag-hints .v-ddwrapper-over-top:before, .mytheme .no-vertical-drag-hints.v-ddwrapper-over-top:before { + border-top-width: 0; +} + +.mytheme .no-vertical-drag-hints .v-ddwrapper-over-top:after, .mytheme .no-vertical-drag-hints.v-ddwrapper-over-top:after { + border-width: 2px; + border-radius: 4px; + opacity: 0.3; + filter: alpha(opacity=30.0) ; + background: #8abef2; +} + +.mytheme .no-vertical-drag-hints .v-ddwrapper-over-bottom:before, .mytheme .no-vertical-drag-hints.v-ddwrapper-over-bottom:before { + border-bottom-width: 0; +} + +.mytheme .no-vertical-drag-hints .v-ddwrapper-over-bottom:after, .mytheme .no-vertical-drag-hints.v-ddwrapper-over-bottom:after { + border-width: 2px; + border-radius: 4px; + opacity: 0.3; + filter: alpha(opacity=30.0) ; + background: #8abef2; +} + +.mytheme .no-horizontal-drag-hints.v-ddwrapper-over-left:before, .mytheme .no-horizontal-drag-hints .v-ddwrapper-over-left:before { + border-left-width: 0; +} + +.mytheme .no-horizontal-drag-hints.v-ddwrapper-over-left:after, .mytheme .no-horizontal-drag-hints .v-ddwrapper-over-left:after { + border-width: 2px; + border-radius: 4px; + opacity: 0.3; + filter: alpha(opacity=30.0) ; + background: #8abef2; +} + +.mytheme .no-horizontal-drag-hints.v-ddwrapper-over-right:before, .mytheme .no-horizontal-drag-hints .v-ddwrapper-over-right:before { + border-right-width: 0; +} + +.mytheme .no-horizontal-drag-hints.v-ddwrapper-over-right:after, .mytheme .no-horizontal-drag-hints .v-ddwrapper-over-right:after { + border-width: 2px; + border-radius: 4px; + opacity: 0.3; + filter: alpha(opacity=30.0) ; + background: #8abef2; +} + +.mytheme .v-ddwrapper-over-middle:after, .mytheme .v-ddwrapper-over-center:after { + border-width: 2px; + border-radius: 4px; + opacity: 0.3; + filter: alpha(opacity=30.0) ; + background: #8abef2; +} + +.mytheme .no-box-drag-hints.v-ddwrapper:after, .mytheme .no-box-drag-hints .v-ddwrapper:after { + display: none !important; + content: none; +} + +.mytheme .v-nativebutton { + -webkit-touch-callout: none; +} + +.mytheme .v-select select { + border: 1px solid #c5c5c5; + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + color: #464646; +} + +.mytheme .v-select select:focus { + outline: none; + -webkit-box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); + box-shadow: 0 0 0 2px rgba(25, 125, 225, 0.5); +} + +.mytheme .v-select-select { + display: block; +} + +.mytheme .v-select-select + .v-textfield { + width: auto !important; + margin-top: 9px; +} + +.mytheme .v-select-select + .v-textfield + .v-nativebutton { + margin-top: 9px; + margin-left: 9px; +} + +.mytheme .v-select-error .v-select-select { + border-color: #ed473b !important; + background: #fffbfb; + color: #6c2621; +} + +.mytheme .v-popupview { + cursor: pointer; + color: #197de1; + text-decoration: underline; + font-weight: inherit; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme .v-popupview:hover { + color: #4396ea; +} + +.mytheme .v-popupview.v-disabled { + opacity: 0.5; + filter: alpha(opacity=50) ; +} + +.mytheme .v-popupview-popup { + padding: 4px 4px; + border-radius: 4px; + background-color: white; + color: #474747; + -webkit-box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098); + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + backface-visibility: hidden; +} + +.mytheme .v-popupview-popup[class*="animate-in"] { + -webkit-animation: v-popupview-animate-in 120ms; + -moz-animation: v-popupview-animate-in 120ms; + animation: v-popupview-animate-in 120ms; +} + +.mytheme .v-popupview-popup[class*="animate-out"] { + -webkit-animation: valo-animate-out-fade 120ms; + -moz-animation: valo-animate-out-fade 120ms; + animation: valo-animate-out-fade 120ms; +} + +.mytheme .v-popupview-popup .popupContent > .v-margin-top { + padding-top: 12px; +} + +.mytheme .v-popupview-popup .popupContent > .v-margin-right { + padding-right: 12px; +} + +.mytheme .v-popupview-popup .popupContent > .v-margin-bottom { + padding-bottom: 12px; +} + +.mytheme .v-popupview-popup .popupContent > .v-margin-left { + padding-left: 12px; +} + +.mytheme .v-popupview-loading { + margin: 12px 12px; + height: 24px !important; + width: 24px !important; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + border: 2px solid rgba(25, 125, 225, 0.2); + border-top-color: #197de1; + border-right-color: #197de1; + border-radius: 100%; + -webkit-animation: v-rotate-360 500ms infinite linear; + -moz-animation: v-rotate-360 500ms infinite linear; + animation: v-rotate-360 500ms infinite linear; + pointer-events: none; +} + +.v-ie8 .mytheme .v-popupview-loading, .v-ie9 .mytheme .v-popupview-loading { + border: none; + border-radius: 4px; + background: #fff url(../valo/shared/img/spinner.gif) no-repeat 50% 50%; + background-size: 80%; +} + +.v-ie8 .mytheme .v-popupview-loading { + min-width: 30px; + min-height: 30px; +} + +.mytheme .v-richtextarea { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + margin: 0; + font: inherit; + + font-weight: 400; + line-height: normal; + height: 37px; + border-radius: 4px; + padding: 0; + border: 1px solid #c5c5c5; + background: white; + color: #474747; + -webkit-box-shadow: inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 #f7f7f7, 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-transition: box-shadow 180ms, border 180ms; + -moz-transition: box-shadow 180ms, border 180ms; + transition: box-shadow 180ms, border 180ms; + height: auto; + overflow: hidden; +} + +.v-ie8 .mytheme .v-richtextarea, .v-ie9 .mytheme .v-richtextarea { + line-height: 37px; + padding-top: 0; + padding-bottom: 0; +} + +.mytheme .v-richtextarea[class*="prompt"] { + color: #a3a3a3; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar { + background-color: #fafafa; + background-image: -webkit-linear-gradient(top, #fafafa 2%, #efefef 98%); + background-image: linear-gradient(to bottom,#fafafa 2%, #efefef 98%); + -webkit-box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7; + box-shadow: inset 0 1px 0 white, inset 0 -1px 0 #e7e7e7; + border-bottom: 1px solid #c5c5c5; + color: #464646; +} + +.mytheme .v-richtextarea .gwt-ToggleButton, .mytheme .v-richtextarea .gwt-PushButton { + display: inline-block; + line-height: 37px; + width: 37px; + text-align: center; + outline: none; +} + +.mytheme .v-richtextarea .gwt-ToggleButton:hover, .mytheme .v-richtextarea .gwt-PushButton:hover { + color: black; +} + +.mytheme .v-richtextarea .gwt-ToggleButton-down, .mytheme .v-richtextarea .gwt-ToggleButton-down-hovering { + background-color: #e0e0e0; + background-image: -webkit-linear-gradient(bottom, #e0e0e0 2%, #dcdcdc 98%); + background-image: linear-gradient(to top,#e0e0e0 2%, #dcdcdc 98%); +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top img { + display: none; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div:before { + font-family: ThemeIcons; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Toggle Bold"]:before { + content: "\f032"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Toggle Italic"]:before { + content: "\f033"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Toggle Underline"]:before { + content: "\f0cd"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Toggle Subscript"]:before { + content: "\f12c"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Toggle Superscript"]:before { + content: "\f12b"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Left Justify"]:before { + content: "\f036"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Center"]:before { + content: "\f037"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Right Justify"]:before { + content: "\f038"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Toggle Strikethrough"]:before { + content: "\f0cc"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Indent Right"]:before { + content: "\f03c"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Indent Left"]:before { + content: "\f03b"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Insert Horizontal Rule"]:before { + content: "\2014"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Insert Ordered List"]:before { + content: "\f0cb"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Insert Unordered List"]:before { + content: "\f0ca"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Insert Image"]:before { + content: "\f03e"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Create Link"]:before { + content: "\f0c1"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Remove Link"]:before { + content: "\f127"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-top div[title="Remove Formatting"]:before { + content: "\f12d"; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-bottom { + font-size: 13px; + padding: 0 9px 9px 0; +} + +.mytheme .v-richtextarea .gwt-RichTextToolbar-bottom select { + margin: 9px 0 0 9px; +} + +.mytheme .v-richtextarea .gwt-RichTextArea { + background: #fff; + border: none; + display: block; +} + +.mytheme .v-richtextarea-readonly { + padding: 5px 7px; + background: transparent; +} + +.mytheme .v-upload .v-button { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + display: inline-block; + vertical-align: top; + text-align: left; + white-space: normal; +} + +.mytheme .v-upload-immediate .v-button { + width: 100%; +} + +.mytheme .v-upload-immediate input[type="file"] { + opacity: 0; + filter: alpha(opacity=0) ; + z-index: -1; + position: absolute; + right: 0; + height: 37px; + text-align: right; + border: none; + background: transparent; +} + +.mytheme .v-Notification.v-position-top { + top: 12px; +} + +.mytheme .v-Notification.v-position-right { + right: 12px; +} + +.mytheme .v-Notification.v-position-bottom { + bottom: 12px; +} + +.mytheme .v-Notification.v-position-left { + left: 12px; +} + +.mytheme .v-Notification.v-position-assistive { + top: -9999px; + left: -9999px; +} + +.mytheme .v-Notification-animate-in { + -webkit-animation: valo-animate-in-fade 180ms 10ms backwards; + -moz-animation: valo-animate-in-fade 180ms 10ms backwards; + animation: valo-animate-in-fade 180ms 10ms backwards; +} + +.mytheme .v-Notification-animate-in.v-position-top { + -webkit-animation: valo-animate-in-slide-down 400ms 10ms backwards; + -moz-animation: valo-animate-in-slide-down 400ms 10ms backwards; + animation: valo-animate-in-slide-down 400ms 10ms backwards; +} + +.mytheme .v-Notification-animate-in.v-position-bottom { + -webkit-animation: valo-animate-in-slide-up 400ms 10ms backwards; + -moz-animation: valo-animate-in-slide-up 400ms 10ms backwards; + animation: valo-animate-in-slide-up 400ms 10ms backwards; +} + +.mytheme .v-Notification-animate-out { + -webkit-animation: valo-animate-out-fade 150ms; + -moz-animation: valo-animate-out-fade 150ms; + animation: valo-animate-out-fade 150ms; +} + +.mytheme .v-Notification-animate-out.v-position-top, .mytheme .v-Notification-animate-out.v-position-bottom { + -webkit-animation: valo-animate-out-slide-down-fade 200ms; + -moz-animation: valo-animate-out-slide-down-fade 200ms; + animation: valo-animate-out-slide-down-fade 200ms; +} + +.mytheme .v-Notification { + border-radius: 4px; + text-align: center; + position: fixed !important; + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + -ms-backface-visibility: hidden; + backface-visibility: hidden; + background: white; + -webkit-box-shadow: 0px 5px 15px 0px rgba(0, 0, 0, 0.15); + box-shadow: 0px 5px 15px 0px rgba(0, 0, 0, 0.15); + padding: 19px 22px; +} + +.mytheme .v-Notification .v-Notification-caption { + color: #197de1; + font-size: 19px; + line-height: 1; +} + +.mytheme .v-Notification .v-Notification-description { + line-height: 1.4; +} + +.mytheme .v-Notification-caption { + margin: 0; + display: inline-block; + text-align: left; + font-weight: inherit; + line-height: inherit; + white-space: nowrap; + letter-spacing: 0; +} + +.mytheme .v-Notification-description, .mytheme .v-Notification-details { + margin: 0; + display: inline-block; + vertical-align: middle; + max-width: 30em; + text-align: left; + max-height: 20em; + overflow: auto; +} + +.mytheme .v-Notification-caption ~ .v-Notification-description, .mytheme .v-Notification-caption ~ .v-Notification-details { + margin-left: 24px; +} + +.mytheme .v-icon + .v-Notification-caption { + margin-left: 16px; +} + +.mytheme .v-Notification-system { + left: 0 !important; + right: 0; + max-width: 100%; + margin: 0 !important; + border-radius: 0; + -webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.25); + padding: 12px 15px; + background-color: #444; + background-color: rgba(68, 68, 68, 0.9); + font-weight: 400; + line-height: 22px; +} + +.mytheme .v-Notification-system .v-Notification-description, .mytheme .v-Notification-system .v-Notification-details { + max-width: 50em; +} + +.mytheme .v-Notification-system.v-position-top { + top: 0; +} + +.mytheme .v-Notification-system.v-position-top[class*="animate-in"] { + -webkit-animation: valo-animate-in-slide-down 300ms 10ms backwards; + -moz-animation: valo-animate-in-slide-down 300ms 10ms backwards; + animation: valo-animate-in-slide-down 300ms 10ms backwards; +} + +.mytheme .v-Notification-system.v-position-top[class*="animate-out"] { + -webkit-animation: valo-animate-out-slide-up 200ms; + -moz-animation: valo-animate-out-slide-up 200ms; + animation: valo-animate-out-slide-up 200ms; +} + +.mytheme .v-Notification-system.v-position-bottom { + bottom: 0; +} + +.mytheme .v-Notification-system.v-position-bottom[class*="animate-in"] { + -webkit-animation: valo-animate-in-slide-up 300ms 10ms backwards; + -moz-animation: valo-animate-in-slide-up 300ms 10ms backwards; + animation: valo-animate-in-slide-up 300ms 10ms backwards; +} + +.mytheme .v-Notification-system.v-position-bottom[class*="animate-out"] { + -webkit-animation: valo-animate-out-slide-down 200ms; + -moz-animation: valo-animate-out-slide-down 200ms; + animation: valo-animate-out-slide-down 200ms; +} + +.mytheme .v-Notification-system .v-Notification-caption { + color: #fff; + vertical-align: middle; +} + +.mytheme .v-Notification-system .v-Notification-description, .mytheme .v-Notification-system .v-Notification-details { + color: #e6e6e6; +} + +.mytheme .v-Notification-system u { + text-decoration: none; +} + +.mytheme .v-Notification.tray { + text-align: left; +} + +.mytheme .v-Notification.tray .v-Notification-caption + .v-Notification-description { + display: block; + margin: 0.5em 0 0; +} + +.mytheme .v-Notification.warning { + background: #FFF3D2; +} + +.mytheme .v-Notification.warning .v-Notification-caption { + color: #AC7C00; +} + +.mytheme .v-Notification.warning .v-Notification-description { + color: #9D874D; +} + +.mytheme .v-Notification.error { + background: #ed473b; + font-weight: 400; + -webkit-box-shadow: 0px 5px 15px 0px rgba(0, 0, 0, 0.25); + box-shadow: 0px 5px 15px 0px rgba(0, 0, 0, 0.25); +} + +.mytheme .v-Notification.error .v-Notification-caption { + color: white; +} + +.mytheme .v-Notification.error .v-Notification-description { + color: #f4e0df; +} + +.mytheme .v-Notification.dark { + background-color: #444; + background-color: rgba(68, 68, 68, 0.9); + font-weight: 400; + line-height: 22px; +} + +.mytheme .v-Notification.dark .v-Notification-caption { + color: #fff; + vertical-align: middle; +} + +.mytheme .v-Notification.dark .v-Notification-description, .mytheme .v-Notification.dark .v-Notification-details { + color: #e6e6e6; +} + +.mytheme .v-Notification.bar { + left: 0 !important; + right: 0; + max-width: 100%; + margin: 0 !important; + border-radius: 0; + -webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.25); + padding: 12px 15px; +} + +.mytheme .v-Notification.bar .v-Notification-description, .mytheme .v-Notification.bar .v-Notification-details { + max-width: 50em; +} + +.mytheme .v-Notification.bar.v-position-top { + top: 0; +} + +.mytheme .v-Notification.bar.v-position-top[class*="animate-in"] { + -webkit-animation: valo-animate-in-slide-down 300ms 10ms backwards; + -moz-animation: valo-animate-in-slide-down 300ms 10ms backwards; + animation: valo-animate-in-slide-down 300ms 10ms backwards; +} + +.mytheme .v-Notification.bar.v-position-top[class*="animate-out"] { + -webkit-animation: valo-animate-out-slide-up 200ms; + -moz-animation: valo-animate-out-slide-up 200ms; + animation: valo-animate-out-slide-up 200ms; +} + +.mytheme .v-Notification.bar.v-position-bottom { + bottom: 0; +} + +.mytheme .v-Notification.bar.v-position-bottom[class*="animate-in"] { + -webkit-animation: valo-animate-in-slide-up 300ms 10ms backwards; + -moz-animation: valo-animate-in-slide-up 300ms 10ms backwards; + animation: valo-animate-in-slide-up 300ms 10ms backwards; +} + +.mytheme .v-Notification.bar.v-position-bottom[class*="animate-out"] { + -webkit-animation: valo-animate-out-slide-down 200ms; + -moz-animation: valo-animate-out-slide-down 200ms; + animation: valo-animate-out-slide-down 200ms; +} + +.mytheme .v-Notification.small { + padding: 11px 13px; +} + +.mytheme .v-Notification.small .v-Notification-caption { + font-size: 16px; +} + +.mytheme .v-Notification.small .v-Notification-description { + font-size: 14px; +} + +.mytheme .v-Notification.closable { + padding-right: 59px; + overflow: hidden !important; + cursor: pointer; +} + +.mytheme .v-Notification.closable:after { + content: "\00d7"; + font-size: 1.5em; + position: absolute; + top: 50%; + margin-top: -12px; + right: 12px; + width: 25px; + height: 25px; + line-height: 24px; + cursor: pointer; + color: #000; + opacity: 0.5; + filter: alpha(opacity=50) ; + text-align: center; + border: 1px solid #000; + border-color: rgba(0, 0, 0, 0.3); + border-radius: 50%; + -webkit-transition: opacity 200ms; + -moz-transition: opacity 200ms; + transition: opacity 200ms; +} + +.mytheme .v-Notification.closable:hover:after { + opacity: 1; + filter: none ; +} + +.mytheme .v-Notification.closable:active:after { + background-color: #000; + color: #fff; + opacity: 0.3; + filter: alpha(opacity=30.0) ; + -webkit-transition: none 200ms; + -moz-transition: none 200ms; + transition: none 200ms; +} + +.mytheme .v-Notification.closable.dark:after, .mytheme .v-Notification.closable.error:after, .mytheme .v-Notification.closable.system:after { + color: #fff; + border-color: #fff; + border-color: rgba(255, 255, 255, 0.3); +} + +.mytheme .v-Notification.closable.dark:active:after, .mytheme .v-Notification.closable.error:active:after, .mytheme .v-Notification.closable.system:active:after { + background-color: #fff; + color: #000; +} + +.mytheme .v-Notification.closable.tray:after { + top: 16px; + margin-top: 0; +} + +.mytheme .v-Notification.success, .mytheme .v-Notification.failure { + background: #fff; + color: #555; + border: 2px solid #2c9720; +} + +.mytheme .v-Notification.success .v-Notification-caption, .mytheme .v-Notification.failure .v-Notification-caption { + color: #2c9720; + font-weight: 400; +} + +.mytheme .v-Notification.success .v-Notification-caption:before, .mytheme .v-Notification.failure .v-Notification-caption:before { + font-family: ThemeIcons; + content: "\f00c"; + margin-right: 0.5em; +} + +.mytheme .v-Notification.success.bar, .mytheme .v-Notification.failure.bar { + margin: -2px !important; +} + +.mytheme .v-Notification.failure { + border-color: #ed473b; +} + +.mytheme .v-Notification.failure .v-Notification-caption { + color: #ed473b; +} + +.mytheme .v-Notification.failure .v-Notification-caption:before { + content: "\f05e"; +} + +.mytheme .valo-menu { + height: 100%; + background-color: #4b4b4b; + background-image: -webkit-linear-gradient(right, #414141 0%, #4b4b4b 9px); + background-image: linear-gradient(to left,#414141 0%, #4b4b4b 9px); + color: #a5a5a5; + font-size: 14px; + line-height: 30px; + border-right: 1px solid #3b3b3b; + white-space: nowrap; +} + +.mytheme .valo-menu-toggle { + display: none; + position: fixed; + z-index: 200; + top: 3px; + left: 3px; + min-width: 0; +} + +.mytheme .valo-menu-part { + border-left: 1px solid #414141; + height: 100%; + padding-bottom: 37px; + overflow: auto; +} + +.mytheme .valo-menu-part:first-child { + border-left: none; +} + +.mytheme .valo-menu-title, .mytheme .valo-menu-subtitle, .mytheme .valo-menu-item { + display: block; + line-height: inherit; + white-space: nowrap; + position: relative; +} + +.mytheme .valo-menu-title .valo-menu-badge, .mytheme .valo-menu-subtitle .valo-menu-badge, .mytheme .valo-menu-item .valo-menu-badge { + position: absolute; + right: 19px; +} + +.mytheme .valo-menu-title { + line-height: 1.2; + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + color: white; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); + padding: 12px 19px; + font-size: 14px; + border-bottom: 1px solid #1362b1; + -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + text-align: center; +} + +.mytheme .valo-menu-title .v-menubar.v-menubar { + background: transparent; + border-color: #1362b1; + color: inherit; + -webkit-box-shadow: none; + box-shadow: none; + text-shadow: inherit; +} + +.mytheme .valo-menu-title .v-menubar-menuitem { + background: transparent; + -webkit-box-shadow: inset 0 1px 0 #4d98e6, inset 0 -1px 0 #166bca; + box-shadow: inset 0 1px 0 #4d98e6, inset 0 -1px 0 #166bca; + text-shadow: inherit; + font-size: 16px; + border-color: inherit; +} + +.mytheme .valo-menu-title h1, .mytheme .valo-menu-title .v-label-h1, .mytheme .valo-menu-title h2, .mytheme .valo-menu-title .v-label-h2, .mytheme .valo-menu-title h3, .mytheme .valo-menu-title .v-label-h3, .mytheme .valo-menu-title h4, .mytheme .valo-menu-title .v-label-h4 { + margin-top: 0; + margin-bottom: 0; + color: inherit; +} + +.mytheme .v-menubar-user-menu { + border: none; + border-radius: 0; + padding: 1px; + -webkit-box-shadow: none; + box-shadow: none; + text-shadow: none; + background: transparent; + color: inherit; + margin: 19px 7px; + display: block; + overflow: hidden; + text-align: center; + height: auto; + color: inherit; +} + +.mytheme .v-menubar-user-menu:focus:after { + display: none; +} + +.mytheme .v-menubar-user-menu .v-menubar-menuitem { + -webkit-box-shadow: none; + box-shadow: none; + border: none; + margin-right: 1px; + border-radius: 4px; + color: #197de1; + padding: 0 12px; + -webkit-transition: color 140ms; + -moz-transition: color 140ms; + transition: color 140ms; +} + +.mytheme .v-menubar-user-menu .v-menubar-menuitem:first-child, .mytheme .v-menubar-user-menu .v-menubar-menuitem:last-child, .mytheme .v-menubar-user-menu .v-menubar-menuitem:first-child:last-child { + border-radius: 4px; +} + +.mytheme .v-menubar-user-menu .v-menubar-menuitem:before { + content: none; +} + +.mytheme .v-menubar-user-menu .v-menubar-menuitem:hover { + color: #4396ea; +} + +.mytheme .v-menubar-user-menu .v-menubar-menuitem:active { + color: inherit; +} + +.mytheme .v-menubar-user-menu .v-menubar-menuitem-checked, .mytheme .v-menubar-user-menu .v-menubar-menuitem-checked:first-child { + border: 1px solid #c5c5c5; + color: #197de1; +} + +.mytheme .v-menubar-user-menu .v-menubar-menuitem-checked .v-menubar-menuitem-caption, .mytheme .v-menubar-user-menu .v-menubar-menuitem-checked:first-child .v-menubar-menuitem-caption { + position: relative; + top: -1px; +} + +.mytheme .v-menubar-user-menu .v-menubar-menuitem-selected { + color: #ecf2f8; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.05); +} + +.mytheme .v-menubar-user-menu .v-menubar-menuitem-selected:hover { + color: #ecf2f8; +} + +.mytheme .v-menubar-user-menu .v-menubar-menuitem-disabled, .mytheme .v-menubar-user-menu .v-menubar-menuitem-disabled:hover { + color: inherit; +} + +.mytheme .v-menubar-user-menu > .v-menubar-menuitem { + color: inherit; + white-space: normal; + line-height: 1.4; + margin: 0; +} + +.mytheme .v-menubar-user-menu > .v-menubar-menuitem img.v-icon { + width: 56px; + height: 56px; + border-radius: 29px; + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + display: block; + margin: 0 auto 0.3em; + border: 1px solid #c5c5c5; +} + +.mytheme .v-menubar-user-menu > .v-menubar-menuitem:after { + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +.mytheme .v-menubar-user-menu .v-menubar-menuitem-selected { + background: transparent; +} + +.mytheme .valo-menu-subtitle { + color: #868686; + margin: 7px 0 7px 19px; + border-bottom: 1px solid #666666; +} + +.mytheme .valo-menu-subtitle [class*="badge"] { + color: #73a5d7; +} + +.mytheme .valo-menuitems { + display: block; +} + +.mytheme .valo-menu-item { + outline: none; + font-weight: 400; + padding: 0 37px 0 19px; + cursor: pointer; + position: relative; + overflow: hidden; + text-shadow: 0 2px 0 rgba(0, 0, 0, 0.05); + -webkit-transition: background-color 300ms, color 60ms; + -moz-transition: background-color 300ms, color 60ms; + transition: background-color 300ms, color 60ms; +} + +.mytheme .valo-menu-item [class*="caption"] { + vertical-align: middle; + display: inline-block; + width: 90%; + max-width: 15em; + padding-right: 19px; + text-overflow: ellipsis; + overflow: hidden; +} + +.mytheme .valo-menu-item [class*="badge"] { + color: #73a5d7; +} + +.mytheme .valo-menu-item.selected { + background: #434343; +} + +.mytheme .valo-menu-item.selected .v-icon { + color: #197de1; +} + +.mytheme .valo-menu-item.selected [class*="badge"] { + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + color: #c8dbed; +} + +.mytheme .valo-menu-item:focus, .mytheme .valo-menu-item:hover, .mytheme .valo-menu-item.selected { + color: white; +} + +.mytheme .valo-menu-item span.v-icon { + min-width: 1em; + margin-right: 19px; + text-align: center; + vertical-align: middle; + -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(black), to(rgba(0, 0, 0, 0.75))); +} + +.mytheme .valo-menu-item span.v-icon + span { + margin-left: 0; +} + +.mytheme .valo-menu-item [class*="badge"] { + background-color: #585858; + -webkit-transition: background-color 300ms; + -moz-transition: background-color 300ms; + transition: background-color 300ms; + line-height: 1; + padding: 4px 6px; + min-width: 11px; + text-align: center; + top: 4px; + border-radius: 4px; +} + +.mytheme .valo-menu-part.large-icons { + background-color: #4b4b4b; + min-width: 74px; + max-width: 111px; +} + +.mytheme .valo-menu-part.large-icons .valo-menu-title { + font-size: 12px; +} + +.mytheme .valo-menu-part.large-icons .valo-menu-title .v-label-undef-w { + white-space: normal; +} + +.mytheme .valo-menu-part.large-icons .v-menubar-user-menu { + margin-left: 0; + margin-right: 0; + font-size: 11px; +} + +.mytheme .valo-menu-part.large-icons .v-menubar-user-menu img.v-icon { + width: 28px; + height: 28px; +} + +.mytheme .valo-menu-part.large-icons [class*="subtitle"] { + margin: 9px 0 0; + padding: 7px 25px 7px 9px; + line-height: 1; + border: none; + text-overflow: ellipsis; + overflow: hidden; + background: #3c3c3c; + font-size: 13px; + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); +} + +.mytheme .valo-menu-part.large-icons [class*="subtitle"] [class*="badge"] { + right: 9px; +} + +.mytheme .valo-menu-part.large-icons [class*="subtitle"] + .valo-menu-item { + border-top: none; +} + +.mytheme .valo-menu-part.large-icons .valo-menu-item { + display: block; + font-size: 26px; + line-height: 1; + padding: 12px; + text-align: center; + border-top: 1px solid #555555; +} + +.mytheme .valo-menu-part.large-icons .valo-menu-item:first-child { + border-top: none; +} + +.mytheme .valo-menu-part.large-icons .valo-menu-item [class*="caption"] { + display: block; + width: auto; + margin: 0.3em 0 0; + padding: 0; + font-size: 11px; + line-height: 1.3; +} + +.mytheme .valo-menu-part.large-icons .valo-menu-item .v-icon { + margin: 0; +} + +.mytheme .valo-menu-part.large-icons .valo-menu-item span.v-icon { + opacity: 0.8; +} + +.mytheme .valo-menu-part.large-icons .valo-menu-item.selected { + background: #434343; +} + +.mytheme .valo-menu-part.large-icons .valo-menu-item.selected .v-icon { + opacity: 1; +} + +.mytheme .valo-menu-part.large-icons .valo-menu-item.selected [class*="badge"] { + border-color: #434343; +} + +.mytheme .valo-menu-part.large-icons .valo-menu-item [class*="badge"] { + padding-left: 4px; + padding-right: 4px; + top: 7px; + right: 7px; + border: 2px solid #4b4b4b; +} + +.mytheme .valo-menu-logo { + display: block; + overflow: hidden; + width: 44px !important; + height: 44px; + border-radius: 4px; + text-align: center; + background-color: #197de1; + background-image: -webkit-linear-gradient(top, #1b87e3 2%, #166ed5 98%); + background-image: linear-gradient(to bottom,#1b87e3 2%, #166ed5 98%); + color: white; + font-size: 25px; + line-height: 44px; + margin: 19px auto; + -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); +} + +.mytheme .valo-menu-logo:focus { + outline: none; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part { + background-color: #4b4b4b; + min-width: 74px; + max-width: 111px; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .valo-menu-title { + font-size: 12px; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .valo-menu-title .v-label-undef-w { + white-space: normal; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .v-menubar-user-menu { + margin-left: 0; + margin-right: 0; + font-size: 11px; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .v-menubar-user-menu img.v-icon { + width: 28px; + height: 28px; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part [class*="subtitle"] { + margin: 9px 0 0; + padding: 7px 25px 7px 9px; + line-height: 1; + border: none; + text-overflow: ellipsis; + overflow: hidden; + background: #3c3c3c; + font-size: 13px; + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.05); +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part [class*="subtitle"] [class*="badge"] { + right: 9px; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part [class*="subtitle"] + .valo-menu-item { + border-top: none; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .valo-menu-item { + display: block; + font-size: 26px; + line-height: 1; + padding: 12px; + text-align: center; + border-top: 1px solid #555555; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .valo-menu-item:first-child { + border-top: none; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .valo-menu-item [class*="caption"] { + display: block; + width: auto; + margin: 0.3em 0 0; + padding: 0; + font-size: 11px; + line-height: 1.3; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .valo-menu-item .v-icon { + margin: 0; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .valo-menu-item span.v-icon { + opacity: 0.8; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .valo-menu-item.selected { + background: #434343; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .valo-menu-item.selected .v-icon { + opacity: 1; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .valo-menu-item.selected [class*="badge"] { + border-color: #434343; +} + +.mytheme .valo-menu-responsive[width-range~="801px-1100px"] .valo-menu-part .valo-menu-item [class*="badge"] { + padding-left: 4px; + padding-right: 4px; + top: 7px; + right: 7px; + border: 2px solid #4b4b4b; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] { + padding-top: 37px; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] .v-loading-indicator { + top: 37px; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] > .v-widget { + position: relative !important; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] .valo-menu { + border-right: none; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] .valo-menu-part { + overflow: visible; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] .valo-menu-toggle { + display: inline-block; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] .valo-menu-title { + position: fixed; + z-index: 100; + top: 0; + left: 0; + right: 0; + height: 37px !important; + padding-top: 0; + padding-bottom: 0; + -webkit-backface-visibility: hidden; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] .valo-menu .v-menubar-user-menu { + position: fixed; + z-index: 100; + top: 0; + right: 0; + margin: 0; + padding: 0; + height: 37px; + color: #97bee5; + max-width: 30%; + -webkit-backface-visibility: hidden; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] .valo-menu .v-menubar-user-menu .v-menubar-menuitem { + line-height: 36px; + white-space: nowrap; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] .valo-menu .v-menubar-user-menu img.v-icon { + display: inline-block; + margin: 0 6px 0 0; + width: 19px; + height: 19px; + border-radius: 10px; + border: none; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] .valo-menuitems { + height: 100%; + background-color: #4b4b4b; + background-image: -webkit-linear-gradient(right, #414141 0%, #4b4b4b 9px); + background-image: linear-gradient(to left,#414141 0%, #4b4b4b 9px); + color: #a5a5a5; + font-size: 14px; + line-height: 30px; + border-right: 1px solid #3b3b3b; + white-space: nowrap; + position: fixed; + z-index: 9000; + top: 37px; + bottom: 0; + height: auto; + max-width: 100%; + overflow: auto; + padding: 19px 0; + -webkit-transform: translatex(-100%); + -moz-transform: translatex(-100%); + -ms-transform: translatex(-100%); + -o-transform: translatex(-100%); + transform: translatex(-100%); + -webkit-transition: all 300ms; + -moz-transition: all 300ms; + transition: all 300ms; +} + +.mytheme .valo-menu-responsive[width-range~="0-800px"] .valo-menu-visible .valo-menuitems, .mytheme .valo-menu-responsive[width-range~="0-800px"] .valo-menu-hover:hover .valo-menuitems { + -webkit-transform: translatex(0%); + -moz-transform: translatex(0%); + -ms-transform: translatex(0%); + -o-transform: translatex(0%); + transform: translatex(0%); +} + +.mytheme .valo-menu-responsive[width-range~="0-500px"] .valo-menu-toggle .v-button-caption { + display: none; +} + +.mytheme .valo-menu-responsive[width-range~="0-500px"] .valo-menu .v-menubar-user-menu .v-menubar-menuitem-caption { + display: inline-block; + width: 19px; + overflow: hidden; +} + +.mytheme .my-style { + font-family: Verdana; +} \ No newline at end of file From 47f5478b781f72399ebf7cc0c79fba5642663917 Mon Sep 17 00:00:00 2001 From: rpesek Date: Wed, 15 Aug 2018 15:00:12 +0200 Subject: [PATCH 18/85] Update from dev --- README.md | 6 +- build/pom.xml | 52 +- core/crce-metadata-api/.project | 10 +- core/crce-metadata-dao-api/.project | 10 +- core/crce-metadata-dao-mongodb/.classpath | 1 + core/crce-metadata-impl/.project | 10 +- core/crce-metadata-indexer-api/.classpath | 1 + core/crce-metadata-indexer-impl/.classpath | 1 + core/crce-metadata-json-api/.classpath | 1 + core/crce-metadata-json-impl/.classpath | 1 + core/crce-metadata-service-api/.project | 10 +- core/crce-metadata-service-impl/.project | 10 +- core/crce-plugin-api/.project | 10 +- core/crce-repository-api/.project | 10 +- core/crce-repository-impl/.project | 10 +- core/crce-resolver-api/.project | 10 +- core/crce-resolver-impl/.project | 10 +- modules/crce-compatibility-dao-api/.classpath | 1 + modules/crce-compatibility-dao-api/.project | 4 +- modules/crce-concurrency/.project | 4 +- .../META-INF/MANIFEST.MF | 2 +- modules/crce-handler-metrics/pom.xml | 2 +- modules/crce-integration-tests/.classpath | 33 - modules/crce-integration-tests/.project | 12 - modules/crce-integration-tests/pom.xml | 2 +- .../config/def/api/jaxrs_api.yml | 302 + .../config/def/api/spring_api.yml | 396 + .../config/def/dispatcher.yml | 9 + modules/crce-restimpl-indexer/osgi.bnd | 8 + modules/crce-restimpl-indexer/pom.xml | 94 + .../BytecodeDescriptorsProcessor.java | 256 + .../extracting/MyAnnotationVisitor.java | 78 + .../classmodel/extracting/MyClassVisitor.java | 76 + .../classmodel/extracting/MyFieldVisitor.java | 35 + .../extracting/MyMethodVisitor.java | 254 + .../extracting/ResultCollector.java | 31 + .../classmodel/extracting/State.java | 60 + .../classmodel/structures/Annotated.java | 12 + .../classmodel/structures/Annotation.java | 46 + .../classmodel/structures/ClassStruct.java | 68 + .../classmodel/structures/DataType.java | 59 + .../classmodel/structures/Field.java | 28 + .../classmodel/structures/Method.java | 88 + .../structures/MethodSignature.java | 33 + .../classmodel/structures/Operation.java | 116 + .../classmodel/structures/PathPart.java | 60 + .../structures/PathPartAttributes.java | 74 + .../classmodel/structures/Variable.java | 52 + .../definition/DispatcherDefinition.java | 40 + .../definition/RestApiDefinition.java | 365 + .../internal/Activator.java | 30 + .../internal/RestimplMetadataConstants.java | 55 + .../internal/RestimplMetadataManager.java | 196 + .../internal/RestimplResourceIndexer.java | 137 + .../extracting/AnnotationProcessor.java | 112 + .../extracting/BasicParameterConverter.java | 66 + .../restmodel/extracting/BodyProcessor.java | 38 + .../extracting/ClassModelProcessor.java | 132 + .../extracting/ClassModelProcessorImpl.java | 369 + .../extracting/ExceptionHandler.java | 37 + .../restmodel/extracting/MemberProcessor.java | 52 + .../extracting/MethodBodyInterpreter.java | 332 + .../extracting/ParameterNameProcessor.java | 52 + .../ParameterRequirementProcessor.java | 72 + .../extracting/RestApiReconstructor.java | 27 + .../extracting/RestApiReconstructorImpl.java | 466 + .../restmodel/structures/Endpoint.java | 105 + .../structures/EndpointParameter.java | 55 + .../structures/EndpointRequestBody.java | 37 + .../structures/EndpointResponse.java | 66 + .../structures/ParameterCategory.java | 14 + .../structures/RequestParameter.java | 39 + .../util/Util.java | 52 + .../util/WebXmlParser.java | 229 + modules/crce-webui/osgi.bnd | 40 + modules/crce-webui/pom.xml | 182 + .../kiv/crce/webui/internal/Activator.java | 177 + .../kiv/crce/webui/internal/CheckServlet.java | 80 + .../crce/webui/internal/DownloadServlet.java | 132 + .../kiv/crce/webui/internal/EditServlet.java | 1023 ++ .../zcu/kiv/crce/webui/internal/Helper.java | 26 + .../crce/webui/internal/ResourceServlet.java | 389 + .../crce/webui/internal/RuntimeServlet.java | 111 + .../crce/webui/internal/SessionListener.java | 25 + .../crce/webui/internal/UploadServlet.java | 213 + .../kiv/crce/webui/internal/VersionInfo.java | 67 + .../crce/webui/internal/bean/Category.java | 65 + .../crce/webui/internal/custom/Plugin.java | 47 + .../internal/custom/RequirementAdapter.java | 85 + .../webui/internal/custom/RequirementExt.java | 21 + .../internal/custom/RequirementsWrap.java | 42 + .../internal/custom/ResourceAdapter.java | 341 + .../webui/internal/custom/ResourceExt.java | 45 + .../webui/internal/custom/ResourceWrap.java | 482 + .../CompatibilityAvailabilityFilter.java | 39 + .../webui/internal/legacy/Capability.java | 13 + .../webui/internal/legacy/NewProperty.java | 13 + .../crce/webui/internal/legacy/Property.java | 36 + .../internal/legacy/PropertyProvider.java | 41 + .../webui/internal/legacy/Requirement.java | 36 + .../crce/webui/internal/legacy/Resource.java | 122 + .../kiv/crce/webui/internal/legacy/Type.java | 79 + .../src/main/webapp/META-INF/MANIFEST.MF | 3 + .../src/main/webapp/WEB-INF/web.xml | 89 + modules/crce-webui/src/main/webapp/crce.png | Bin 0 -> 1334 bytes .../crce-webui/src/main/webapp/css/styl.css | 612 ++ .../src/main/webapp/graphic/add.png | Bin 0 -> 733 bytes .../src/main/webapp/graphic/check.png | Bin 0 -> 1388 bytes .../src/main/webapp/graphic/commit.png | Bin 0 -> 891 bytes .../src/main/webapp/graphic/crce.png | Bin 0 -> 1334 bytes .../src/main/webapp/graphic/del.png | Bin 0 -> 715 bytes .../src/main/webapp/graphic/edit.png | Bin 0 -> 450 bytes .../src/main/webapp/graphic/heading-bg.png | Bin 0 -> 191 bytes .../src/main/webapp/graphic/hlavicka_bg.png | Bin 0 -> 10258 bytes .../src/main/webapp/graphic/hlavicka_loga.png | Bin 0 -> 22199 bytes .../src/main/webapp/graphic/logo.png | Bin 0 -> 18213 bytes .../src/main/webapp/graphic/menu_bg.png | Bin 0 -> 215 bytes .../src/main/webapp/graphic/save.png | Bin 0 -> 870 bytes .../src/main/webapp/graphic/zoom.png | Bin 0 -> 692 bytes modules/crce-webui/src/main/webapp/index.jsp | 145 + .../src/main/webapp/js/jquery-1.5.1.js | 8316 +++++++++++++++++ .../src/main/webapp/js/plus_minus_form.js | 49 + .../crce-webui/src/main/webapp/js/slide.js | 19 + .../crce-webui/src/main/webapp/jsp/buffer.jsp | 168 + .../src/main/webapp/jsp/compatibility.jsp | 69 + .../webapp/jsp/forms/capabilitiesForm.jsp | 47 + .../main/webapp/jsp/forms/capabilityForm.jsp | 31 + .../main/webapp/jsp/forms/categoriesForm.jsp | 25 + .../main/webapp/jsp/forms/categoryForm.jsp | 31 + .../src/main/webapp/jsp/forms/pluginForm.jsp | 35 + .../main/webapp/jsp/forms/propertiesForm.jsp | 58 + .../main/webapp/jsp/forms/propertyForm.jsp | 49 + .../main/webapp/jsp/forms/requirementForm.jsp | 56 + .../webapp/jsp/forms/requirementsForm.jsp | 40 + .../src/main/webapp/jsp/forms/testForm.jsp | 66 + .../src/main/webapp/jsp/include/footer.jsp | 11 + .../src/main/webapp/jsp/include/header.jsp | 98 + .../src/main/webapp/jsp/plugins.jsp | 49 + .../crce-webui/src/main/webapp/jsp/store.jsp | 178 + .../crce-webui/src/main/webapp/jsp/tags.jsp | 146 + modules/crce-webui/src/main/webapp/test.jsp | 142 + .../webui/internal/ResourceServletTest.java | 40 + modules/pom.xml | 2 +- modules/provision/pom.xml | 2 +- 144 files changed, 20054 insertions(+), 127 deletions(-) delete mode 100644 modules/crce-integration-tests/.classpath create mode 100644 modules/crce-restimpl-indexer/config/def/api/jaxrs_api.yml create mode 100644 modules/crce-restimpl-indexer/config/def/api/spring_api.yml create mode 100644 modules/crce-restimpl-indexer/config/def/dispatcher.yml create mode 100644 modules/crce-restimpl-indexer/osgi.bnd create mode 100644 modules/crce-restimpl-indexer/pom.xml create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/BytecodeDescriptorsProcessor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyAnnotationVisitor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyClassVisitor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyFieldVisitor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyMethodVisitor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/ResultCollector.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/State.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Annotated.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Annotation.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/ClassStruct.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/DataType.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Field.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Method.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/MethodSignature.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Operation.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/PathPart.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/PathPartAttributes.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Variable.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/definition/DispatcherDefinition.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/definition/RestApiDefinition.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/Activator.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplMetadataConstants.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplMetadataManager.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplResourceIndexer.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/AnnotationProcessor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/BasicParameterConverter.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/BodyProcessor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ClassModelProcessor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ClassModelProcessorImpl.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ExceptionHandler.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/MemberProcessor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/MethodBodyInterpreter.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ParameterNameProcessor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ParameterRequirementProcessor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/RestApiReconstructor.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/RestApiReconstructorImpl.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/Endpoint.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointParameter.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointRequestBody.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointResponse.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/ParameterCategory.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/RequestParameter.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/util/Util.java create mode 100644 modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/util/WebXmlParser.java create mode 100644 modules/crce-webui/osgi.bnd create mode 100644 modules/crce-webui/pom.xml create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Activator.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Helper.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/SessionListener.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/UploadServlet.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/VersionInfo.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/bean/Category.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/Plugin.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/filter/CompatibilityAvailabilityFilter.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Capability.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Property.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/PropertyProvider.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Requirement.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Resource.java create mode 100644 modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Type.java create mode 100644 modules/crce-webui/src/main/webapp/META-INF/MANIFEST.MF create mode 100644 modules/crce-webui/src/main/webapp/WEB-INF/web.xml create mode 100644 modules/crce-webui/src/main/webapp/crce.png create mode 100644 modules/crce-webui/src/main/webapp/css/styl.css create mode 100644 modules/crce-webui/src/main/webapp/graphic/add.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/check.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/commit.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/crce.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/del.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/edit.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/heading-bg.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/hlavicka_bg.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/hlavicka_loga.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/logo.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/menu_bg.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/save.png create mode 100644 modules/crce-webui/src/main/webapp/graphic/zoom.png create mode 100644 modules/crce-webui/src/main/webapp/index.jsp create mode 100644 modules/crce-webui/src/main/webapp/js/jquery-1.5.1.js create mode 100644 modules/crce-webui/src/main/webapp/js/plus_minus_form.js create mode 100644 modules/crce-webui/src/main/webapp/js/slide.js create mode 100644 modules/crce-webui/src/main/webapp/jsp/buffer.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/compatibility.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/capabilitiesForm.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/capabilityForm.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/categoriesForm.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/categoryForm.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/pluginForm.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/propertiesForm.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/propertyForm.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/requirementForm.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/requirementsForm.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/forms/testForm.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/include/footer.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/include/header.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/plugins.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/store.jsp create mode 100644 modules/crce-webui/src/main/webapp/jsp/tags.jsp create mode 100644 modules/crce-webui/src/main/webapp/test.jsp create mode 100644 modules/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java diff --git a/README.md b/README.md index 2f2719d8..10ffa4aa 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,15 @@ On linux, switching to JDK 7 for development/build can be done via `sudo update- 1. `crce-parent` in `/pom` directory 2. `shared-build-settings` in `/build` -3. everything in `/third-party` +3. everything in `/third-party` (bash: `.../third-party$ for d in * ; do cd $d; mvn clean install; cd .. ; done`) 4. `crce-core-reactor` in `/core` 5. `crce-modules-reactor` in `/modules` +On linux, step 3. can be perfomed via `.../third-party$ for d in * ; do cd $d ; mvn clean install ; cd .. ; done`. In case of maven error "Received fatal alert: protocol_version", use `mvn -Dhttps.protocols=TLSv1.2 ...` after https://stackoverflow.com/a/50924208/261891. + ## Start up -Run CRCE using Maven plugin for pax in `crce-modules-reactor` module (`/modules` directory); note the JDK 7 requirement above: +Run CRCE using Maven plugin for pax in `crce-modules-reactor` module (i.e. `/modules` directory): `mvn pax:provision` diff --git a/build/pom.xml b/build/pom.xml index 7d6a13d1..2dbeb449 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -6,8 +6,8 @@ cz.zcu.kiv.crce crce-parent - 2.1.1-SNAPSHOT + @@ -25,8 +25,8 @@ 2.13.3 0.8.1-incubator 4.3.1 - 6.0.7 + 1.0.0.Final 3.2.0 2.6.1 @@ -77,14 +77,13 @@ org.apache.servicemix.tooling depends-maven-plugin - - 1.4.0 + 1.2 org.apache.felix maven-bundle-plugin - 3.3.0 + true @@ -127,7 +126,7 @@ org.apache.maven.plugins maven-pmd-plugin - 3.8 + 3.8 @@ -153,8 +152,7 @@ org.apache.maven.plugins maven-dependency-plugin - - 3.0.2 + 2.9 org.apache.cxf @@ -207,14 +205,20 @@ - + + + javax.servlet + servlet-api + 2.5 + provided + - + org.ops4j.pax.web + pax-web-jsp + ${version.org.ops4j.pax.web} + provided + --> + org.ops4j.pax.web pax-web-jetty-bundle ${version.org.ops4j.pax.web} @@ -407,13 +411,13 @@ - + - + org.ow2.asm asm-all 5.2 @@ -574,17 +578,16 @@ org.apache.xbean xbean-finder - 4.5 + provided org.apache.xbean xbean-bundleutils - 4.5 - provided + @@ -633,6 +636,13 @@ ${version.com.fasterxml.jackson} compile + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + ${version.com.fasterxml.jackson} + compile + org.codehaus.jackson jackson-core-asl diff --git a/core/crce-metadata-api/.project b/core/crce-metadata-api/.project index 12b7d3a4..dcddf63f 100644 --- a/core/crce-metadata-api/.project +++ b/core/crce-metadata-api/.project @@ -16,27 +16,27 @@ - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder - org.jboss.tools.jst.web.kb.kbbuilder + org.fusesource.ide.project.RiderProjectBuilder - org.jboss.tools.cdi.core.cdibuilder + org.jboss.tools.jst.web.kb.kbbuilder - org.eclipse.wst.validation.validationbuilder + org.jboss.tools.cdi.core.cdibuilder - org.eclipse.m2e.core.maven2Builder + org.eclipse.wst.validation.validationbuilder diff --git a/core/crce-metadata-dao-api/.project b/core/crce-metadata-dao-api/.project index 7b6f96fd..0d413bc0 100644 --- a/core/crce-metadata-dao-api/.project +++ b/core/crce-metadata-dao-api/.project @@ -16,27 +16,27 @@ - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder - org.jboss.tools.jst.web.kb.kbbuilder + org.fusesource.ide.project.RiderProjectBuilder - org.jboss.tools.cdi.core.cdibuilder + org.jboss.tools.jst.web.kb.kbbuilder - org.eclipse.wst.validation.validationbuilder + org.jboss.tools.cdi.core.cdibuilder - org.eclipse.m2e.core.maven2Builder + org.eclipse.wst.validation.validationbuilder diff --git a/core/crce-metadata-dao-mongodb/.classpath b/core/crce-metadata-dao-mongodb/.classpath index a086d4a1..dfdb3d58 100644 --- a/core/crce-metadata-dao-mongodb/.classpath +++ b/core/crce-metadata-dao-mongodb/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-metadata-impl/.project b/core/crce-metadata-impl/.project index 851b7d39..98a8b9f1 100644 --- a/core/crce-metadata-impl/.project +++ b/core/crce-metadata-impl/.project @@ -16,27 +16,27 @@ - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder - org.jboss.tools.jst.web.kb.kbbuilder + org.fusesource.ide.project.RiderProjectBuilder - org.jboss.tools.cdi.core.cdibuilder + org.jboss.tools.jst.web.kb.kbbuilder - org.eclipse.wst.validation.validationbuilder + org.jboss.tools.cdi.core.cdibuilder - org.eclipse.m2e.core.maven2Builder + org.eclipse.wst.validation.validationbuilder diff --git a/core/crce-metadata-indexer-api/.classpath b/core/crce-metadata-indexer-api/.classpath index 0556be39..b8b4abe0 100644 --- a/core/crce-metadata-indexer-api/.classpath +++ b/core/crce-metadata-indexer-api/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-metadata-indexer-impl/.classpath b/core/crce-metadata-indexer-impl/.classpath index 0556be39..b8b4abe0 100644 --- a/core/crce-metadata-indexer-impl/.classpath +++ b/core/crce-metadata-indexer-impl/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-metadata-json-api/.classpath b/core/crce-metadata-json-api/.classpath index 0556be39..b8b4abe0 100644 --- a/core/crce-metadata-json-api/.classpath +++ b/core/crce-metadata-json-api/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-metadata-json-impl/.classpath b/core/crce-metadata-json-impl/.classpath index 0556be39..b8b4abe0 100644 --- a/core/crce-metadata-json-impl/.classpath +++ b/core/crce-metadata-json-impl/.classpath @@ -10,6 +10,7 @@ + diff --git a/core/crce-metadata-service-api/.project b/core/crce-metadata-service-api/.project index 70e77ad8..b10ca1c7 100644 --- a/core/crce-metadata-service-api/.project +++ b/core/crce-metadata-service-api/.project @@ -16,27 +16,27 @@ - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder - org.jboss.tools.jst.web.kb.kbbuilder + org.fusesource.ide.project.RiderProjectBuilder - org.jboss.tools.cdi.core.cdibuilder + org.jboss.tools.jst.web.kb.kbbuilder - org.eclipse.wst.validation.validationbuilder + org.jboss.tools.cdi.core.cdibuilder - org.eclipse.m2e.core.maven2Builder + org.eclipse.wst.validation.validationbuilder diff --git a/core/crce-metadata-service-impl/.project b/core/crce-metadata-service-impl/.project index a50b870e..16872220 100644 --- a/core/crce-metadata-service-impl/.project +++ b/core/crce-metadata-service-impl/.project @@ -16,27 +16,27 @@ - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder - org.jboss.tools.jst.web.kb.kbbuilder + org.fusesource.ide.project.RiderProjectBuilder - org.jboss.tools.cdi.core.cdibuilder + org.jboss.tools.jst.web.kb.kbbuilder - org.eclipse.wst.validation.validationbuilder + org.jboss.tools.cdi.core.cdibuilder - org.eclipse.m2e.core.maven2Builder + org.eclipse.wst.validation.validationbuilder diff --git a/core/crce-plugin-api/.project b/core/crce-plugin-api/.project index b8fae5ac..ec21180e 100644 --- a/core/crce-plugin-api/.project +++ b/core/crce-plugin-api/.project @@ -16,27 +16,27 @@ - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder - org.jboss.tools.jst.web.kb.kbbuilder + org.fusesource.ide.project.RiderProjectBuilder - org.jboss.tools.cdi.core.cdibuilder + org.jboss.tools.jst.web.kb.kbbuilder - org.eclipse.wst.validation.validationbuilder + org.jboss.tools.cdi.core.cdibuilder - org.eclipse.m2e.core.maven2Builder + org.eclipse.wst.validation.validationbuilder diff --git a/core/crce-repository-api/.project b/core/crce-repository-api/.project index dbe9c738..b42166de 100644 --- a/core/crce-repository-api/.project +++ b/core/crce-repository-api/.project @@ -16,27 +16,27 @@ - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder - org.jboss.tools.jst.web.kb.kbbuilder + org.fusesource.ide.project.RiderProjectBuilder - org.jboss.tools.cdi.core.cdibuilder + org.jboss.tools.jst.web.kb.kbbuilder - org.eclipse.wst.validation.validationbuilder + org.jboss.tools.cdi.core.cdibuilder - org.eclipse.m2e.core.maven2Builder + org.eclipse.wst.validation.validationbuilder diff --git a/core/crce-repository-impl/.project b/core/crce-repository-impl/.project index 823a8880..9bb71646 100644 --- a/core/crce-repository-impl/.project +++ b/core/crce-repository-impl/.project @@ -16,27 +16,27 @@ - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder - org.jboss.tools.jst.web.kb.kbbuilder + org.fusesource.ide.project.RiderProjectBuilder - org.jboss.tools.cdi.core.cdibuilder + org.jboss.tools.jst.web.kb.kbbuilder - org.eclipse.wst.validation.validationbuilder + org.jboss.tools.cdi.core.cdibuilder - org.eclipse.m2e.core.maven2Builder + org.eclipse.wst.validation.validationbuilder diff --git a/core/crce-resolver-api/.project b/core/crce-resolver-api/.project index 11cff5eb..33c424b1 100644 --- a/core/crce-resolver-api/.project +++ b/core/crce-resolver-api/.project @@ -16,27 +16,27 @@ - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder - org.jboss.tools.jst.web.kb.kbbuilder + org.fusesource.ide.project.RiderProjectBuilder - org.jboss.tools.cdi.core.cdibuilder + org.jboss.tools.jst.web.kb.kbbuilder - org.eclipse.wst.validation.validationbuilder + org.jboss.tools.cdi.core.cdibuilder - org.eclipse.m2e.core.maven2Builder + org.eclipse.wst.validation.validationbuilder diff --git a/core/crce-resolver-impl/.project b/core/crce-resolver-impl/.project index 4dec77e2..16bc7094 100644 --- a/core/crce-resolver-impl/.project +++ b/core/crce-resolver-impl/.project @@ -16,27 +16,27 @@ - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder - org.jboss.tools.jst.web.kb.kbbuilder + org.fusesource.ide.project.RiderProjectBuilder - org.jboss.tools.cdi.core.cdibuilder + org.jboss.tools.jst.web.kb.kbbuilder - org.eclipse.wst.validation.validationbuilder + org.jboss.tools.cdi.core.cdibuilder - org.eclipse.m2e.core.maven2Builder + org.eclipse.wst.validation.validationbuilder diff --git a/modules/crce-compatibility-dao-api/.classpath b/modules/crce-compatibility-dao-api/.classpath index 0556be39..b8b4abe0 100644 --- a/modules/crce-compatibility-dao-api/.classpath +++ b/modules/crce-compatibility-dao-api/.classpath @@ -10,6 +10,7 @@ + diff --git a/modules/crce-compatibility-dao-api/.project b/modules/crce-compatibility-dao-api/.project index 1b9b1709..3b79f417 100644 --- a/modules/crce-compatibility-dao-api/.project +++ b/modules/crce-compatibility-dao-api/.project @@ -11,12 +11,12 @@ - org.eclipse.m2e.core.maven2Builder + org.fusesource.ide.project.RiderProjectBuilder - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder diff --git a/modules/crce-concurrency/.project b/modules/crce-concurrency/.project index dd8ac919..bbee7626 100644 --- a/modules/crce-concurrency/.project +++ b/modules/crce-concurrency/.project @@ -11,12 +11,12 @@ - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder - org.eclipse.m2e.core.maven2Builder + org.fusesource.ide.project.RiderProjectBuilder diff --git a/modules/crce-external-repository/META-INF/MANIFEST.MF b/modules/crce-external-repository/META-INF/MANIFEST.MF index 2af200ea..efcc7627 100644 --- a/modules/crce-external-repository/META-INF/MANIFEST.MF +++ b/modules/crce-external-repository/META-INF/MANIFEST.MF @@ -1,5 +1,5 @@ Manifest-Version: 1.0 -Bnd-LastModified: 1534329969733 +Bnd-LastModified: 1534335826009 Build-Jdk: 1.8.0_181 Built-By: rpesek Bundle-Activator: cz.zcu.kiv.crce.crce_external_repository.internal.Acti diff --git a/modules/crce-handler-metrics/pom.xml b/modules/crce-handler-metrics/pom.xml index 0a550d89..c2858c75 100644 --- a/modules/crce-handler-metrics/pom.xml +++ b/modules/crce-handler-metrics/pom.xml @@ -38,8 +38,8 @@ ${project.groupId} crce-concurrency - 2.2.0-SNAPSHOT + diff --git a/modules/crce-integration-tests/.classpath b/modules/crce-integration-tests/.classpath deleted file mode 100644 index db82fad3..00000000 --- a/modules/crce-integration-tests/.classpath +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/modules/crce-integration-tests/.project b/modules/crce-integration-tests/.project index da2260e0..944831af 100644 --- a/modules/crce-integration-tests/.project +++ b/modules/crce-integration-tests/.project @@ -5,16 +5,6 @@ - - org.eclipse.jdt.core.javabuilder - - - - - org.fusesource.ide.project.RiderProjectBuilder - - - org.eclipse.m2e.core.maven2Builder @@ -22,8 +12,6 @@ - org.fusesource.ide.project.RiderProjectNature - org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/modules/crce-integration-tests/pom.xml b/modules/crce-integration-tests/pom.xml index cadf46e5..65ca7742 100644 --- a/modules/crce-integration-tests/pom.xml +++ b/modules/crce-integration-tests/pom.xml @@ -6,7 +6,7 @@ ../pom cz.zcu.kiv.crce crce-modules-parent - 2.1.1-SNAPSHOT + 2.1.0-SNAPSHOT crce-integration-tests diff --git a/modules/crce-restimpl-indexer/config/def/api/jaxrs_api.yml b/modules/crce-restimpl-indexer/config/def/api/jaxrs_api.yml new file mode 100644 index 00000000..8032bef2 --- /dev/null +++ b/modules/crce-restimpl-indexer/config/def/api/jaxrs_api.yml @@ -0,0 +1,302 @@ +### JAX-RS ### + +framework: jaxrs + +resource_annotations: + - javax/ws/rs/Path + +endpoint_annotations: + - javax/ws/rs/GET + - javax/ws/rs/POST + - javax/ws/rs/PUT + - javax/ws/rs/DELETE + - javax/ws/rs/HEAD + - javax/ws/rs/OPTIONS + - javax/ws/rs/PATCH + - javax/ws/rs/Path + +url: + - annotation: javax/ws/rs/Path + processing_way: from_value + valueKeys: + - value + +produces: + - annotation: javax/ws/rs/Produces + processing_way: from_value + valueKeys: + - value + +consumes: + - + annotation: javax/ws/rs/Consumes + processing_way: from_value + valueKeys: + - value + +default_http_methods: [] + +http_method: + - + annotation: javax/ws/rs/GET + processing_way: from_name + result: GET + - + annotation: javax/ws/rs/POST + processing_way: from_name + result: POST + - + annotation: javax/ws/rs/PUT + processing_way: from_name + result: PUT + - + annotation: javax/ws/rs/DELETE + processing_way: from_name + result: DELETE + - + annotation: javax/ws/rs/HEAD + processing_way: from_name + result: HEAD + - + annotation: javax/ws/rs/OPTIONS + processing_way: from_name + result: OPTIONS + +endpoint_parameters: + - + annotation: javax/ws/rs/QueryParam + processing_way: from_name + result: query + - + annotation: javax/ws/rs/PathParam + processing_way: from_name + result: path + - + annotation: javax/ws/rs/MatrixParam + processing_way: from_name + result: matrix + - + annotation: javax/ws/rs/FormParam + processing_way: from_name + result: form + - + annotation: javax/ws/rs/HeaderParam + processing_way: from_name + result: header + - + annotation: javax/ws/rs/CookieParam + processing_way: from_name + result: cookie + +parameter_name: + annotationProcessors: + - + annotation: javax/ws/rs/QueryParam + processing_way: from_value + valueKeys: + - value + - + annotation: javax/ws/rs/PathParam + processing_way: from_value + valueKeys: + - value + - + annotation: javax/ws/rs/MatrixParam + processing_way: from_value + valueKeys: + - value + - + annotation: javax/ws/rs/FormParam + processing_way: from_value + valueKeys: + - value + - + annotation: javax/ws/rs/HeaderParam + processing_way: from_value + valueKeys: + - value + - + annotation: javax/ws/rs/CookieParam + processing_way: from_value + valueKeys: + - value + from_name: false + +parameter_requirement: +# PathParam is always required + annotationProcessors: + - + annotation: javax/validation/constraints/NotNull + processing_way: from_name + result: true + parametersDefault: false # is not required + fieldsDefault: false # is not required + +#parameter_datetype: +# - ParameterConvertor: +# processing_way: from_datetype + +default_parameter_value: + - + annotation: javax/ws/rs/DefaultValue + processing_way: from_value + valueKeys: + - value + +cookie_name: + annotationProcessors: + - annotation: javax/ws/rs/CookieParam + processing_way: from_value + valueKeys: + - value + + from_name: false + +default_cookie_value: + - + annotation: javax/ws/rs/DefaultValue + processing_way: from_value + valueKeys: + - value + +header_name: + annotationProcessors: + - annotation: javax/ws/rs/HeaderParam + processing_way: from_value + valueKeys: + - value + + from_name: false + +default_header_value: + - + annotation: javax/ws/rs/DefaultValue + processing_way: from_value + valueKeys: + - value + + +parameter_bean_annotations: + - javax/ws/rs/BeanParam + +body: + withoutAnnotations: true + annotations: [] + excludingAnnotations: + - javax/ws/rs/BeanParam + - javax/ws/rs/core/Context + + +generic_response_classes: + - javax/ws/rs/core/Response + +subresources: + true + +status_setting_methods: + owner: javax/ws/rs/core/Response + mapping: + ok: 200 + badRequest: 400 + notFound: 404 + created: 201 + accepted: 202 + noContent: 204 + serverError: 500 + simpleName: status + +entity_setting_methods: + - owner: javax/ws/rs/core/Response$ResponseBuilder + simpleName: entity + returnType: javax/ws/rs/core/Response$ResponseBuilder + - owner: javax/ws/rs/core/Response + simpleName: ok + returnType: javax/ws/rs/core/Response + +status_fields: + owner: javax/ws/rs/core/Response$Status + mapping: + OK: 200 + CREATED: 201 + ACCEPTED: 202 + NO_CONTENT: 204 + RESET_CONTENT: 205 + PARTIAL_CONTENT: 206 + MOVED_PERMANENTLY: 301 + FOUND: 302 + SEE_OTHER: 303 + NOT_MODIFIED: 304 + USE_PROXY: 305 + TEMPORARY_REDIRECT: 307 + BAD_REQUEST: 400 + UNAUTHORIZED: 401 + PAYMENT_REQUIRED: 402 + FORBIDDEN: 403 + NOT_FOUND: 404 + METHOD_NOT_ALLOWED: 405 + NOT_ACCEPTABLE: 406 + PROXY_AUTHENTICATION_REQUIRED: 407 + REQUEST_TIMEOUT: 408 + CONFLICT: 409 + GONE: 410 + LENGTH_REQUIRED: 411 + PRECONDITION_FAILED: 412 + REQUEST_ENTITY_TOO_LARGE: 413 + REQUEST_URI_TOO_LONG: 414 + UNSUPPORTED_MEDIA_TYPE: 415 + REQUESTED_RANGE_NOT_SATISFIABLE: 416 + EXPECTATION_FAILED: 417 + PRECONDITION_REQUIRED: 428 + TOO_MANY_REQUESTS: 429 + REQUEST_HEADER_FIELDS_TOO_LARGE: 431 + INTERNAL_SERVER_ERROR: 500 + NOT_IMPLEMENTED: 501 + BAD_GATEWAY: 502 + SERVICE_UNAVAILABLE: 503 + GATEWAY_TIMEOUT: 504 + HTTP_VERSION_NOT_SUPPORTED: 505 + NETWORK_AUTHENTICATION_REQUIRED: 511 + +cookie_class: javax/ws/rs/core/NewCookie + +cookie_setting_method: + owner: javax/ws/rs/core/Response$ResponseBuilder + simpleName: cookie + returnType: javax/ws/rs/core/Response$ResponseBuilder + +header_setting_method: + owner: javax/ws/rs/core/Response$ResponseBuilder + simpleName: header + returnType: javax/ws/rs/core/Response$ResponseBuilder + +default_object_mime: application/xml +default_primitive_mime: text/plain + + +fieldParamAnnotations: true +fieldParamSetterRequired: false + +exception_handler: + annotations: + - javax/ws/rs/ext/Provider + interfaces: + - javax/ws/rs/ext/ExceptionMapper + method: toResponse + + + + +#request_filter: +# extends: [] +# implements: +# - javax/ws/rs/container/ContainerRequestFilter +# annotations: +# - javax/ws/rs/ext/Provider + +#special_method_inputs: +# annotations: +# - javax/ws/rs/Context +# classes: + #- javax/ws/rs/UriInfo + #- javax/ws/rs/HttpHeaders + diff --git a/modules/crce-restimpl-indexer/config/def/api/spring_api.yml b/modules/crce-restimpl-indexer/config/def/api/spring_api.yml new file mode 100644 index 00000000..68928ef2 --- /dev/null +++ b/modules/crce-restimpl-indexer/config/def/api/spring_api.yml @@ -0,0 +1,396 @@ + +framework: spring + +resource_annotations: + - org/springframework/web/bind/annotation/RestController +# - org/springframework/web/bind/annotation/Controller + +endpoint_annotations: + - org/springframework/web/bind/annotation/RequestMapping + - org/springframework/web/bind/annotation/GetMapping + - org/springframework/web/bind/annotation/PostMapping + - org/springframework/web/bind/annotation/PutMapping + - org/springframework/web/bind/annotation/DeleteMapping + - org/springframework/web/bind/annotation/PatchMapping + +url: + - + annotation: org/springframework/web/bind/annotation/RequestMapping + processing_way: from_value + valueKeys: + - value + - path + - + annotation: org/springframework/web/bind/annotation/GetMapping + processing_way: from_value + valueKeys: + - value + - path + - + annotation: org/springframework/web/bind/annotation/PostMapping + processing_way: from_value + valueKeys: + - value + - path + - + annotation: org/springframework/web/bind/annotation/PutMapping + processing_way: from_value + valueKeys: + - value + - path + - + annotation: org/springframework/web/bind/annotation/DeleteMapping + processing_way: from_value + valueKeys: + - value + - path + - + annotation: org/springframework/web/bind/annotation/PatchMapping + processing_way: from_value + valueKeys: + - value + - path + - + annotation: org/springframework/web/bind/annotation/HeadMapping + processing_way: from_value + valueKeys: + - value + - path + +produces: + - annotation: org/springframework/web/bind/annotation/RequestMapping + processing_way: from_value + valueKeys: + - produces + - annotation: org/springframework/web/bind/annotation/GetMapping + processing_way: from_value + valueKeys: + - produces + - annotation: org/springframework/web/bind/annotation/PostMapping + processing_way: from_value + valueKeys: + - produces + - annotation: org/springframework/web/bind/annotation/DeleteMapping + processing_way: from_value + valueKeys: + - produces + - annotation: org/springframework/web/bind/annotation/PutMapping + processing_way: from_value + valueKeys: + - produces + - annotation: org/springframework/web/bind/annotation/PatchMapping + processing_way: from_value + valueKeys: + - produces + +consumes: + - annotation: org/springframework/web/bind/annotation/RequestMapping + processing_way: from_value + valueKeys: + - consumes + - annotation: org/springframework/web/bind/annotation/GetMapping + processing_way: from_value + valueKeys: + - consumes + - annotation: org/springframework/web/bind/annotation/PostMapping + processing_way: from_value + valueKeys: + - consumes + - annotation: org/springframework/web/bind/annotation/DeleteMapping + processing_way: from_value + valueKeys: + - consumes + - annotation: org/springframework/web/bind/annotation/PutMapping + processing_way: from_value + valueKeys: + - consumes + - annotation: org/springframework/web/bind/annotation/PatchMapping + processing_way: from_value + valueKeys: + - consumes + +default_http_methods: + - GET + - POST + - PUT + - PATCH + - DELETE + - OPTIONS + - HEAD + +http_method: + - + annotation: org/springframework/web/bind/annotation/RequestMapping + processing_way: from_value + valueKeys: + - method + - + annotation: org/springframework/web/bind/annotation/GetMapping + processing_way: from_name + result: GET + - + annotation: org/springframework/web/bind/annotation/PostMapping + processing_way: from_name + result: POST + - + annotation: org/springframework/web/bind/annotation/PutMapping + processing_way: from_name + result: PUT + - + annotation: org/springframework/web/bind/annotation/PatchMapping + processing_way: from_name + result: DELETE + - + annotation: org/springframework/web/bind/annotation/PatchMapping + processing_way: from_name + result: PATCH + +endpoint_parameters: + - annotation: org/springframework/web/bind/annotation/RequestParam + processing_way: from_name + result: request # request can mean query or form + - annotation: org/springframework/web/bind/annotation/PathVariable + processing_way: from_name + result: path + - annotation: org/springframework/web/bind/annotation/MatrixParam + processing_way: from_name + result: matrix + - annotation: org/springframework/web/bind/annotation/RequestHeader + processing_way: from_name + result: header + - annotation: org/springframework/web/bind/annotation/CookieValue + processing_way: from_name + result: cookie + +parameter_name: + annotationProcessors: + - + annotation: org/springframework/web/bind/annotation/RequestParam + processing_way: from_value + valueKeys: + - value + - + annotation: org/springframework/web/bind/annotation/PathVariable + processing_way: from_value + valueKeys: + - value + - + annotation: org/springframework/web/bind/annotation/MatrixParam + processing_way: from_value + valueKeys: + - value + - + annotation: org/springframework/web/bind/annotation/RequestHeader + processing_way: from_value + valueKeys: + - value + - + annotation: org/springframework/web/bind/annotation/CookieValue + processing_way: from_value + valueKeys: + - value + from_name: true + +parameter_requirement: +# PathVariable is always required + annotationProcessors: + - + annotation: org/springframework/web/bind/annotation/RequestParam + processing_way: from_value + valueKeys: + - required + + - + annotation: org/springframework/web/bind/annotation/MatrixParam + processing_way: from_value + valueKeys: + - required + - + annotation: org/springframework/web/bind/annotation/RequestHeader + processing_way: from_value + valueKeys: + - required + - + annotation: org/springframework/web/bind/annotation/CookieValue + processing_way: from_value + valueKeys: + - required + parametersDefault: true + fieldsDefault: false + + +default_parameter_value: + - + annotation: org/springframework/web/bind/annotation/RequestParam + processing_way: from_value + valueKeys: + - defaultValue + - + annotation: org/springframework/web/bind/annotation/PathVariable + processing_way: from_value + valueKeys: + - defaultValue + - + annotation: org/springframework/web/bind/annotation/MatrixParam + processing_way: from_value + valueKeys: + - defaultValue + + + + +cookie_name: + annotationProcessors: + - annotation: org/springframework/web/bind/annotation/CookieValue + processing_way: from_value + valueKeys: + - value + + from_name: true + +default_cookie_value: + - + annotation: org/springframework/web/bind/annotation/CookieValue + processing_way: from_value + valueKeys: + - defaultValue + +header_name: + annotationProcessors: + - annotation: org/springframework/web/bind/annotation/RequestHeader + processing_way: from_value + valueKeys: + - value + + from_name: false + +default_header_value: + - annotation: org/springframework/web/bind/annotation/RequestHeader + processing_way: from_value + valueKeys: + - defaultValue + +parameter_bean_annotations: [] + +body: + withoutAnnotations: false + annotations: + - org/springframework/web/bind/annotation/RequestBody + excludingAnnotations: [] + +subresources: + true + +generic_response_classes: + - org/springframework/http/ResponseEntity + +status_setting_methods: + owner: org/springframework/http/ResponseEntity + mapping: + ok: 200 + created: 201 + accepted: 202 + noContent: 204 + serverError: 500 + simpleName: status + returnType: org/springframework/http/ResponseEntity + +entity_setting_methods: + - owner: org/springframework/http/ResponseEntity + simpleName: ok + returnType: org/springframework/http/ResponseEntity + - owner: org/springframework/http/ResponseEntity$BodyBuilder + simpleName: body + returnType: org/springframework/http/ResponseEntity + +status_fields: + owner: org/springframework/http/HttpStatus + mapping: + CONTINUE: 100 + SWITCHING_PROTOCOLS: 101 + PROCESSING: 102 + CHECKPOINT: 103 + OK: 200 + CREATED: 201 + ACCEPTED: 202 + NON_AUTHORITATIVE_INFORMATION: 203 + NO_CONTENT: 204 + RESET_CONTENT: 205 + PARTIAL_CONTENT: 206 + MULTI_STATUS: 207 + ALREADY_REPORTED: 208 + IM_USED: 226 + MULTIPLE_CHOICES: 300 + MOVED_PERMANENTLY: 301 + FOUND: 302 + + SEE_OTHER: 303 + NOT_MODIFIED: 304 + + TEMPORARY_REDIRECT: 307 + PERMANENT_REDIRECT: 308 + BAD_REQUEST: 400 + UNAUTHORIZED: 401 + PAYMENT_REQUIRED: 402 + FORBIDDEN: 403 + NOT_FOUND: 404 + METHOD_NOT_ALLOWED: 405 + NOT_ACCEPTABLE: 406 + PROXY_AUTHENTICATION_REQUIRED: 407 + REQUEST_TIMEOUT: 408 + CONFLICT: 409 + GONE: 410 + LENGTH_REQUIRED: 411 + PRECONDITION_FAILED: 412 + PAYLOAD_TOO_LARGE: 413 + + URI_TOO_LONG: 414 + + UNSUPPORTED_MEDIA_TYPE: 415 + REQUESTED_RANGE_NOT_SATISFIABLE: 416 + EXPECTATION_FAILED: 417 + I_AM_A_TEAPOT: 418 + UNPROCESSABLE_ENTITY: 422 + LOCKED: 423 + FAILED_DEPENDENCY: 424 + UPGRADE_REQUIRED: 426 + PRECONDITION_REQUIRED: 428 + TOO_MANY_REQUESTS: 429 + REQUEST_HEADER_FIELDS_TOO_LARGE: 431 + UNAVAILABLE_FOR_LEGAL_REASONS: 451 + INTERNAL_SERVER_ERROR: 500 + NOT_IMPLEMENTED: 501 + BAD_GATEWAY: 502 + SERVICE_UNAVAILABLE: 503 + GATEWAY_TIMEOUT: 504 + HTTP_VERSION_NOT_SUPPORTED: 505 + VARIANT_ALSO_NEGOTIATES: 506 + INSUFFICIENT_STORAGE: 507 + LOOP_DETECTED: 508 + BANDWIDTH_LIMIT_EXCEEDED: 509 + NOT_EXTENDED: 510 + NETWORK_AUTHENTICATION_REQUIRED: 511 + +cookie_class: javax/servlet/http/Cookie + +cookie_setting_method: + owner: javax/servlet/http/HttpServletResponse + simpleName: addCookie + returnType: V + +header_setting_method: + owner: org/springframework/http/ResponseEntity$BodyBuilder + simpleName: header + returnType: org/springframework/http/ResponseEntity$BodyBuilder + +#special_method_inputs: +# annotations: +# classes: +# - javax.servlet.http.HttpServletRequest; +# - javax.servlet.http.HttpServletResponse; + +default_object_mime: application/json +default_primitive_mime: application/json + +fieldParamAnnotations: false +fieldParamSetterRequired: true \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/config/def/dispatcher.yml b/modules/crce-restimpl-indexer/config/def/dispatcher.yml new file mode 100644 index 00000000..dad1c0d1 --- /dev/null +++ b/modules/crce-restimpl-indexer/config/def/dispatcher.yml @@ -0,0 +1,9 @@ +dispatchers: + jersey_sun: + dispatcher: org.glassfish.jersey.servlet.ServletContainer + providers: jersey.config.server.provider.packages + jersey_glassfish: + dispatcher: com.sun.jersey.spi.container.servlet.ServletContainer + providers: com.sun.jersey.config.property.packages + resteasy: + dispatcher: org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher diff --git a/modules/crce-restimpl-indexer/osgi.bnd b/modules/crce-restimpl-indexer/osgi.bnd new file mode 100644 index 00000000..d37ff243 --- /dev/null +++ b/modules/crce-restimpl-indexer/osgi.bnd @@ -0,0 +1,8 @@ +#----------------------------------------------------------------- +# Use this file to add customized Bnd instructions for the bundle +#----------------------------------------------------------------- + +Bundle-Activator: ${bundle.namespace}.internal.Activator + +Private-Package: ${bundle.namespace}.internal, ${bundle.namespace}.classmodel.structures, ${bundle.namespace}.classmodel.extracting, ${bundle.namespace}.util, ${bundle.namespace}.restmodel.structures, ${bundle.namespace}.restmodel.extracting, ${bundle.namespace}.definition +Export-Package: ${bundle.namespace} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/pom.xml b/modules/crce-restimpl-indexer/pom.xml new file mode 100644 index 00000000..6dcfe5c3 --- /dev/null +++ b/modules/crce-restimpl-indexer/pom.xml @@ -0,0 +1,94 @@ + + + + + + + ../pom + cz.zcu.kiv.crce + crce-modules-parent + 2.1.1-SNAPSHOT + + + 4.0.0 + + crce-restimpl-indexer + bundle + CRCE - Rest Implementation Indexer + + + + UTF-8 + ${namespace}.restimpl.indexer + ${namespace}.restimpl.indexer + true + + + + + + config + + api_definitions/*.yaml + + + + + + + + + junit + junit + test + + + org.apache.felix + org.apache.felix.dependencymanager + + + org.apache.felix + org.apache.felix.bundlerepository + + + ${project.groupId} + crce-core + pom + + + ${project.groupId} + crce-concurrency + 2.1.0-SNAPSHOT + jar + + + + + org.ow2.asm + asm-all + 5.0.3 + + + + + com.fasterxml.jackson.core + jackson-databind + provided + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + provided + + + + + + \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/BytecodeDescriptorsProcessor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/BytecodeDescriptorsProcessor.java new file mode 100644 index 00000000..9a6a74c7 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/BytecodeDescriptorsProcessor.java @@ -0,0 +1,256 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting; + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.DataType; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Method; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.MethodSignature; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Variable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created by ghessova on 24.04.2018. + * + * Class for extracting information from bytecode descriptors and signatures + * (for methods, classes, fields). + * + * A descriptor is a string representing the type of a field or method. + * Descriptors are represented in the class file format using modified UTF-8 strings. + * + * https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.2 + */ +public class BytecodeDescriptorsProcessor { + + private static String baseTypeRegex ="[BCDFIJSZ]"; + private static Pattern baseTypePattern = Pattern.compile(baseTypeRegex); + + private static String objectTypeRegex = "^L[^;<>]+(<.*>)*;"; + private static Pattern objectTypePattern = Pattern.compile(objectTypeRegex); + + private static Pattern voidPattern = Pattern.compile("V"); + + private static final Logger logger = LoggerFactory.getLogger(BytecodeDescriptorsProcessor.class); + + + private static boolean isPrimitive(String dataType) { + return dataType.matches(baseTypeRegex); + } + + public static boolean isPrimitiveOrString(String dataType) { + return "java/lang/String".equals(dataType) || isPrimitive(dataType); + } + + /** + * + * Method processes method descriptor and sets parameter data types and return type to the given method. + * @param desc MethodDescriptor: ( ParameterDescriptor* ) ReturnDescriptor + * @param method method object the values are set fto + */ + public static void processMethodDescriptor(String desc, Method method) { + if (desc.contains("T;") || desc.contains(":")) return; + try { + MethodSignature methodSignature = processMethodDescriptor(desc); + List paramDataTypes = methodSignature.getParameterTypes(); + + // set parameters and return type + List parameters = new ArrayList<>(paramDataTypes.size()); + for (DataType paramDataType : paramDataTypes) { + parameters.add(new Variable(paramDataType)); + } + method.setParameters(parameters); + method.setReturnType(methodSignature.getReturnType()); + } catch (Exception e) { + logger.error("Error when processing method with desc: " + desc, e); + } + + } + + + /** + * Processes method descriptor (or method signature) and retrieves information + * about method return type and parameter types. + * @param desc method descriptor or method signature + * @return method signature - information about return type and parameter types + */ + public static MethodSignature processMethodDescriptor(String desc) { + + String[] parts = desc.split("\\)"); + String parametersDescriptor = parts[0].substring(parts[0].indexOf("(") + 1); + String returnDescriptor = parts[1]; // todo throws part + // retrieve data types + List paramDataTypes = processParametersDescriptor(parametersDescriptor); + DataType returnDataType = processReturnDescriptor(returnDescriptor); + + return new MethodSignature(returnDataType, paramDataTypes); + } + + /** + * Retrieves the name of generic class from class type signature. + * @param classTypeSign class type signature + * @return name of generic class + */ + private static String getOuterGenericType(String classTypeSign) { + String outerType = classTypeSign.replaceAll("<.*>", ""); + outerType = outerType.replaceFirst("L", ""); + outerType = outerType.substring(0, outerType.length() - 1); + return outerType; + } + + /** + * Gets type parameter from class type signature. + * @param classTypeSign + * @return + */ + private static String getInnerGenericType(String classTypeSign) { + String inner = classTypeSign.substring(classTypeSign.indexOf("<") + 1, classTypeSign.lastIndexOf(">" )); + if (inner.startsWith("L")) { + return getFullClassName(inner); + } + else { + return inner; + } + + } + + /** + * Processes parameters descriptor and returns list of parameters data types. + * @param desc parameters descriptor + * @return list of parameters data types + */ + private static List processParametersDescriptor(String desc) { + List dataTypes = new ArrayList<>(); + DateTypeWrapper wrapper; + for (int i = 0; i < desc.length(); i = wrapper.end) { + try { + wrapper = processFieldDescriptor(desc, i); + dataTypes.add(wrapper.dataType); + } catch (Exception e) { + logger.error("Error when processing parameters descriptor", e); + break; + } + } + return dataTypes; + } + + /** + * Processes return type descriptor and returns method return type. + * @param desc method return type descriptor + * @return method return type - data type or void + */ + private static DataType processReturnDescriptor(String desc) { + Matcher matcher = voidPattern.matcher(desc); + if (matcher.find() && matcher.start() == 0) { + return new DataType("void"); + } + return processFieldDescriptor(desc); + } + + + /* + FieldDescriptor: FieldType + FieldType: BaseType | ObjectType | ArrayType + BaseType: B C D F I J S Z + ObjectType: L ClassName ; + ArrayType: [ FieldType + */ + public static DataType processFieldDescriptor(String desc) { + return processFieldDescriptor(desc, 0).dataType; + } + + /** + * Processes parameters descriptor and extracts one a data type for field on current position. + * @param desc parameters descriptor + * @param start current position in descriptor + * @return data type wrapper containing the last position of field descriptor in parameters descriptor + */ + private static DateTypeWrapper processFieldDescriptor(String desc, int start) { + try { + String part = desc.substring(start); + Matcher matcher = baseTypePattern.matcher(part); + String datetype; + if (matcher.find() && matcher.start() == 0) { + datetype = part.substring(0, matcher.end()); + return new DateTypeWrapper(start + matcher.end(), new DataType(datetype)); + } + matcher = objectTypePattern.matcher(part); + if (matcher.find() && matcher.start() == 0) { + part = part.substring(0, matcher.end()); + DataType dateType; + if (!part.contains("<")) { + dateType = new DataType(getFullClassName(part)); + } + else { + dateType = new DataType(BytecodeDescriptorsProcessor.getOuterGenericType(part)); + DataType innerType = new DataType(BytecodeDescriptorsProcessor.getInnerGenericType(part)); + dateType.setInnerType(innerType); + + } + return new DateTypeWrapper(start + matcher.end(), dateType); + } + DataType outerType = new DataType("["); // array + DateTypeWrapper outerWrapper = new DateTypeWrapper(0, outerType); + DateTypeWrapper innerWrapper = processFieldDescriptor(desc, start + 1); + outerType.setInnerType(innerWrapper.dataType); + outerWrapper.end = innerWrapper.end; + return outerWrapper; + } catch (Exception e) { + logger.error("Error in field descriptor processing", e); + return null; + } + + } + + /** + * Class representing data type wrapper. + */ + private static class DateTypeWrapper { + int end; // last index of current field descriptor in parameters descriptor string + DataType dataType; // extracted data type from current field descriptor + + DateTypeWrapper(int end, DataType dataType) { + this.end = end; + this.dataType = dataType; + } + } + + /** + * Returns true if data type is array or collection. + * @param type data type as string + * @return true if data type is array or collection + */ + public static boolean isArrayOrCollection(String type) { + if ("[".equals(type)) { // array + return true; + } + type = type.replaceAll("/", "\\."); + if ("java.util.Collection".equals(type)) return true; + try { + Class c = Class.forName(type); + Class[] interfaces = c.getInterfaces(); + for (Class anInterface : interfaces) { + if ("java.util.Collection".equals(anInterface.getName())) { + return true; + } + } + } catch (ClassNotFoundException e) { + return false; + } + return false; + } + + + /** + * Retrieves full class name from object descriptor. + * @param desc object descriptor + * @return full class name + */ + public static String getFullClassName(String desc) { + return desc.replaceFirst("L", "").replace(";", ""); + } + +} + diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyAnnotationVisitor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyAnnotationVisitor.java new file mode 100644 index 00000000..6aa8e251 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyAnnotationVisitor.java @@ -0,0 +1,78 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting; + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Annotated; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Annotation; +import org.objectweb.asm.AnnotationVisitor; + +import java.util.HashSet; +import java.util.Set; + +/** + * Created by ghessova on 22.01.2018. + */ +public class MyAnnotationVisitor extends AnnotationVisitor { + + private State state; + private Annotated target; + private String keyForArrayValue; + + MyAnnotationVisitor(int opcodes, Annotated target) { + super(opcodes); + state = State.getInstance(); + this.target = target; + } + + @Override + public AnnotationVisitor visitAnnotation(String s, String s1) { + + return super.visitAnnotation(s, s1); + } + + @Override + public AnnotationVisitor visitArray(String key) { + keyForArrayValue = key; + return this; // must not return null (null means that we are not interested in array values) + } + + + + @Override + public void visit(String key, Object value) { + Annotation annotation = state.getAnnotation(); + if (key != null) { + state.getAnnotation().setValue(key, value); + } + else { // key is null when processing array value + Set values = (Set)annotation.getValues().get(keyForArrayValue); + if (values == null) { + values = new HashSet<>(); + annotation.getValues().put(keyForArrayValue, values); + } + values.add(value); + + } + } + + @Override + public void visitEnum(String s, String enumClass, String enumValue) { + Annotation annotation = state.getAnnotation(); + + Set values = (Set)annotation.getValues().get(keyForArrayValue); + if (values == null) { + values = new HashSet<>(); + annotation.getValues().put(keyForArrayValue, values); + } + values.add(enumValue); + } + + + + @Override + public void visitEnd() { + target.addAnnotation(state.getAnnotation()); + super.visitEnd(); + + } + + +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyClassVisitor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyClassVisitor.java new file mode 100644 index 00000000..e58bf9db --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyClassVisitor.java @@ -0,0 +1,76 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting; + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Annotation; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.ClassStruct; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.DataType; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Field; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Method; +import org.objectweb.asm.*; + +/** + * Created by ghessova on 22.01.2018. + */ +public class MyClassVisitor extends ClassVisitor { + + private State state = State.getInstance(); + + public MyClassVisitor(int i) { + super(i); + } + + @Override + public void visit(int version, int access, String name, + String signature, String superName, String[] interfaces) { + ClassStruct clazz = new ClassStruct(name, superName); + clazz.setInterfaces(interfaces); + state.setClassType(clazz); + super.visit(version, access, name, signature, superName, interfaces); + } + + + @Override + public void visitOuterClass(String owner, String name, String desc) { + super.visitOuterClass(owner, name, desc); + } + + @Override + public AnnotationVisitor visitAnnotation(String desc, + boolean visible) { + + desc = BytecodeDescriptorsProcessor.getFullClassName(desc); + state.setAnnotation(new Annotation(desc)); + + return new MyAnnotationVisitor(Opcodes.ASM5, state.getPathPart()); + } + + + @Override + public FieldVisitor visitField(int access, String name, + String desc, String signature, Object value) { + + DataType dataType = BytecodeDescriptorsProcessor.processFieldDescriptor(desc); + Field field = new Field(dataType); + field.setName(name); + field.setAccess(access); + return new MyFieldVisitor(field); + } + + @Override + public void visitEnd() { + ResultCollector.getInstance().addClass(State.getInstance().getClassType()); + super.visitEnd(); + } + + @Override + public MethodVisitor visitMethod(int access, String name, + String desc, String signature, String[] exceptions) { + Method method = new Method(access, name, desc); + method.setExceptions(exceptions); + String descriptor = signature == null ? desc : signature; + BytecodeDescriptorsProcessor.processMethodDescriptor(descriptor, method); + state.getClassType().addMethod(method); + state.setPathPart(method); + return new MyMethodVisitor(method); + } + +} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyFieldVisitor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyFieldVisitor.java new file mode 100644 index 00000000..9b981d06 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyFieldVisitor.java @@ -0,0 +1,35 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting; + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Annotation; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Field; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.Opcodes; + +/** + * Created by ghessova on 31.03.2018. + */ +public class MyFieldVisitor extends FieldVisitor { + + private State state = State.getInstance(); + + private Field field; + + MyFieldVisitor(Field field) { + super(Opcodes.ASM5); + this.field = field; + } + + @Override + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + desc = BytecodeDescriptorsProcessor.getFullClassName(desc); + state.setAnnotation(new Annotation(desc)); + return new MyAnnotationVisitor(Opcodes.ASM5, field); + } + + @Override + public void visitEnd() { + state.getClassType().addField(field); + super.visitEnd(); + } +} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyMethodVisitor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyMethodVisitor.java new file mode 100644 index 00000000..b84b574d --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/MyMethodVisitor.java @@ -0,0 +1,254 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting; + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Annotation; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Method; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Operation; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Variable; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by ghessova on 22.01.2018. + * + * Method visitor. + * + * Extracts local variable names (formal parameters) and method body instructions. + * + * see: + * http://asm.ow2.org/doc/tutorial-asm-2.0.html + * https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings + * http://asm.ow2.org/asm50/javadoc/user/org/objectweb/asm/MethodVisitor.html + */ +public class MyMethodVisitor extends MethodVisitor { + + private State state = State.getInstance(); + private Method method; + private List log = new ArrayList<>(); + + //private static final Logger logger = LoggerFactory.getLogger(MyMethodVisitor.class); + + + MyMethodVisitor(Method method) { + super(Opcodes.ASM5); + this.method = method; + } + + @Override + public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + + desc = BytecodeDescriptorsProcessor.getFullClassName(desc); + state.setAnnotation(new Annotation(desc)); + return new MyAnnotationVisitor(Opcodes.ASM5, method); + } + + /* + * Visits a local variable declaration. + * + * @param name the name of a local variable + * @param desc the type descriptor of this local variable + * @param signature the type signature of this local variable. May be null if the local variable type does not use generic types. + * @param start the first instruction corresponding to the scope of this local variable (inclusive). + * @param end the last instruction corresponding to the scope of this local variable (exclusive). + * @param index the local variable's index. + */ + @Override + public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { + // method parameters are first local variables (except for this) - the names can be get here + if ("this".equals(name)) { + state.setParametersProcessed(0); + return; + } + List parameters = method.getParameters(); + if (parameters != null) { + int paramIndex = state.getParametersProcessed(); + if (paramIndex < parameters.size()) { + parameters.get(paramIndex).setName(name); + state.setParametersProcessed(paramIndex + 1); + } + else if (paramIndex == parameters.size()) { // parameter processing is finished + //log.add(name + "-" + dataType + "-" + s2 + "-" + label + "-" + label1 + "-" + i); + state.setParametersProcessed(0); + } + log.add(name + "-" + desc + "-" + signature + "-" + start + "-" + end + "-" + index); + } + + + super.visitLocalVariable(name, desc, signature , start, end, index); + } + + + + @Override + public void visitLineNumber(int i, Label label) { + super.visitLineNumber(i, label); + } + + // 178 (0xB2) - getstatic + // 180 (0xB4) - getfield + @Override // status value + public void visitFieldInsn(int opcode, String owner, String name, String desc) { + log.add(opcode + "-" + owner + "-" + name + "-" + desc); // todo operation + Operation operation = new Operation(Operation.OperationType.FIELD); + operation.setOwner(owner); + operation.setName(name); + operation.setDesc(desc); + method.addOperation(operation); + + super.visitFieldInsn(opcode, owner, name, desc); + } + + + /* + * Visits a method instruction. A method instruction is an instruction that invokes a method. + * + * @param opcode - the opcode of the type instruction to be visited. This opcode is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. + * @param owner - the internal name of the method's owner class + * @param name - the method's name + * @param desc - the method's descriptor + * @param itf - if the method's owner class is an interface + */ + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { + log.add(owner + "." + name + "-" + desc + "-" + itf); + Operation operation = new Operation(opcode, Operation.OperationType.CALL); + operation.setOwner(owner); + operation.setName(name); + operation.setDesc(desc); + /*if (opcode == Opcodes.INVOKESTATIC) { + }*/ + method.addOperation(operation); + operation.setDescription(owner + "." + name + "-" + desc + "-" + itf); + super.visitMethodInsn(opcode, owner, name, desc, itf); + } + + /** + * Visits a type instruction. A type instruction is an instruction that takes the internal name of a class as parameter. + * @param opcode - the opcode of the type instruction to be visited. This opcode is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF + * @param type - the operand of the instruction to be visited. This operand must be the internal name of an object or array class + */ + @Override + public void visitTypeInsn(int opcode, String type) { + if (opcode == Opcodes.ANEWARRAY) { + log.add("new array of " + type); + } + } + + @Override + public AnnotationVisitor visitParameterAnnotation(int paramIndex, String desc, boolean b) { + List parameters = method.getParameters(); + desc = BytecodeDescriptorsProcessor.getFullClassName(desc); + state.setAnnotation(new Annotation(desc)); + return new MyAnnotationVisitor(Opcodes.ASM5, parameters.get(paramIndex)); + } + + /** + * LDC - push a constant #index from a constant pool (String, int, float, Class, java.lang.invoke.MethodType, or java.lang.invoke.MethodHandle) onto the stack + * @param o constant from pool + */ + @Override + public void visitLdcInsn(Object o) { + log.add("constant from pool: " + String.valueOf(o)); + Operation operation = new Operation(Operation.OperationType.STRING_CONSTANT); + operation.setValue("" + o); + operation.setDescription("constant from pool: " + String.valueOf(o)); + method.addOperation(operation); + super.visitLdcInsn(o); + } + + + /* + * Visits an instruction with a single int operand: . + * + * 16 (0x10) - bipush - push a byte onto the stack as an integer value + * 17 (0x11) - sipush - push a short onto the stack as an integer value + * @param opcode BIPUSH, SIPUSH, or NEWARRAY + * @param operand operand + */ + @Override + public void visitIntInsn(int opcode, int operand) { + log.add("int: " + String.valueOf(operand)); + Operation operation = new Operation(opcode, Operation.OperationType.INT_CONSTANT); + operation.setDataType("I"); + operation.setValue("" + operand); + operation.setDescription("int: " + String.valueOf(operand)); + method.addOperation(operation); + super.visitIntInsn(opcode, operand); + } + + /** + * Visits a local variable instruction: ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE, or RET. + * + * 21 (0x15) - iload - oad an int value from a local variable #index + * 25 (0x19) - aload - load a reference onto the stack from a local variable #index + * 58 (0x3A) - astore - store a reference into a local variable #index + * + * 21 - 53 .. load + * 54 - 86 .. store + * + * see the org.objectweb.asm.Opcode interface for constants definitions + * + * @param opcode instruction code (decimal) + * @param var operand + */ + @Override + public void visitVarInsn(int opcode, int var) { + Operation operation; + if (opcode > 20 && opcode < 54) { // load + log.add("load(" + opcode + "): " + var); + operation = new Operation(opcode, Operation.OperationType.LOAD); + operation.setDescription("load(" + opcode + "): " + var); + + operation.setIndex(var); + } + else if (opcode > 53 && opcode < 87) { // store + operation = new Operation(opcode, Operation.OperationType.STORE); + operation.setIndex(var); + operation.setDescription("store(" + opcode + "): " + var); + + log.add("store(" + opcode + "): " + var); + } + else { + operation = new Operation(opcode, Operation.OperationType.OTHER); + operation.setIndex(var); + operation.setDescription("operation(" + opcode + "): " + var); + log.add("operation(" + opcode + "): " + var); + } + method.addOperation(operation); + } + + @Override + public void visitJumpInsn(int opcode, Label label) { + log.add("jump(" + opcode + "): " + label); + method.addOperation(new Operation(opcode, Operation.OperationType.JUMP)); + + super.visitJumpInsn(opcode, label); + } + + /* + * 172 (0xAC) - ireturn + * 176 (0xB0) - areturn + * 177 (0xB1) - return (return void from method) + * + * Visits a zero operand instruction. + * + * @param instrCode + */ + @Override + public void visitInsn(int opcode) { // opcode 176 is return + if (opcode == 176) { + log.add(opcode + "(return)"); + method.addLog(log); + log = new ArrayList<>(); + method.addOperation(new Operation(Operation.OperationType.RETURN)); + } + + super.visitInsn(opcode); + } +} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/ResultCollector.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/ResultCollector.java new file mode 100644 index 00000000..57d44ee7 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/ResultCollector.java @@ -0,0 +1,31 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting; + + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.ClassStruct; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by ghessova on 05.03.2018. + */ +public class ResultCollector { + + private Map resources; + + private static ResultCollector ourInstance = new ResultCollector(); + public static ResultCollector getInstance() { + return ourInstance; + } + private ResultCollector() { + this.resources = new HashMap<>(); + } + + public Map getClasses() { + return resources; + } + + public void addClass(ClassStruct resource) { + resources.put(resource.getName(), resource); + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/State.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/State.java new file mode 100644 index 00000000..62c1f3e9 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/extracting/State.java @@ -0,0 +1,60 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting; + + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Annotation; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.ClassStruct; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.PathPart; + +/** + * Created by ghessova on 02.03.2018. + */ +public class State { + + private static final State state = new State(); + + public static State getInstance() { + return state; + } + + private int parametersProcessed = 0; + + private ClassStruct classType; + + private Annotation annotation; + + private PathPart pathPart; + + public Annotation getAnnotation() { + return annotation; + } + + public void setAnnotation(Annotation annotation) { + this.annotation = annotation; + } + + public ClassStruct getClassType() { + return classType; + } + + public void setClassType(ClassStruct classType) { + this.classType = classType; + this.pathPart = classType; + } + + public int getParametersProcessed() { + return parametersProcessed; + } + + public void setParametersProcessed(int parametersProcessed) { + this.parametersProcessed = parametersProcessed; + } + + public PathPart getPathPart() { + return pathPart; + } + + public void setPathPart(PathPart pathPart) { + this.pathPart = pathPart; + } + +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Annotated.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Annotated.java new file mode 100644 index 00000000..205a8041 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Annotated.java @@ -0,0 +1,12 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures; + +import java.util.Map; + +/** + * Created by ghessova on 10.03.2018. + */ +public interface Annotated { + + void addAnnotation(Annotation annotation); + Map getAnnotations(); +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Annotation.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Annotation.java new file mode 100644 index 00000000..d630483b --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Annotation.java @@ -0,0 +1,46 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by ghessova on 05.03.2018. + */ +public class Annotation { + + private String name; + private Map values; + + public Annotation() { + values = new HashMap<>(); + } + + public Annotation(String name) { + this(); + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Map getValues() { + return values; + } + + public void setValue(String key, Object value) { + values.put(key, value); + } + + @Override + public String toString() { + return "Annotation{" + + "name='" + name + '\'' + + ", values=" + values + + '}'; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/ClassStruct.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/ClassStruct.java new file mode 100644 index 00000000..909b1093 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/ClassStruct.java @@ -0,0 +1,68 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Created by ghessova on 05.03.2018. + */ +public class ClassStruct extends PathPart { + + private String parent; + private List methods = new ArrayList<>(); + private Set fields = new HashSet<>(); + private String[] interfaces; + + public ClassStruct() { + } + + public ClassStruct(String name, String parent) { + this.name = name; + this.parent = parent; + } + + public void addMethod(Method method) { + methods.add(method); + } + + public List getMethods() { + return methods; + } + + public Set getFields() { + return fields; + } + + public void addField(Field field) { + fields.add(field); + } + + public String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } + + public String[] getInterfaces() { + return interfaces; + } + + public void setInterfaces(String[] interfaces) { + this.interfaces = interfaces; + } + + @Override + public String toString() { + return "ClassStruct{" + + "name=" + name + + ", methods=" + methods + + ", fields=" + fields + + ", parent=" + parent + + ", interfaces=" + interfaces + + '}'; + } +} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/DataType.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/DataType.java new file mode 100644 index 00000000..493cd0ef --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/DataType.java @@ -0,0 +1,59 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures; + +import java.util.Objects; + +/** + * Created by ghessova on 24.04.2018. + */ +public class DataType { + + private String basicType; + private DataType innerType; + + public DataType(String basicType) { + this.basicType = basicType; + } + + public String getBasicType() { + return basicType; + } + + public void setBasicType(String basicType) { + this.basicType = basicType; + } + + public DataType getInnerType() { + return innerType; + } + + public void setInnerType(DataType innerType) { + this.innerType = innerType; + } + + public boolean isStructured() { + return innerType != null; + } + + @Override + public String toString() { + return "DataType{" + + ", basicType='" + basicType + '\'' + + ", innerType=" + innerType + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DataType dataType = (DataType) o; + return Objects.equals(basicType, dataType.basicType) && + Objects.equals(innerType, dataType.innerType); + } + + @Override + public int hashCode() { + + return Objects.hash(basicType, innerType); + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Field.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Field.java new file mode 100644 index 00000000..309605ef --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Field.java @@ -0,0 +1,28 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures; + +/** + * Created by ghessova on 01.05.2018. + */ +public class Field extends Variable { + + private int access; + + public Field(DataType dataType) { + super(dataType); + } + + public int getAccess() { + return access; + } + + public void setAccess(int access) { + this.access = access; + } + + @Override + public String toString() { + return super.toString() +", Field{" + + "access=" + access + + '}'; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Method.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Method.java new file mode 100644 index 00000000..ef2a3397 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Method.java @@ -0,0 +1,88 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by ghessova on 05.03.2018. + */ +public class Method extends PathPart { + + private int access; + private String desc; + private DataType returnType; + private String[] exceptions; + private List parameters; + private List> responsesLog = new ArrayList<>(); + private List bodyLog = new ArrayList<>(); + + public Method(int access, String name, String desc) { + this.access = access; + this.name = name; + this.desc = desc; + } + + public DataType getReturnType() { + return returnType; + } + + public void setReturnType(DataType returnType) { + this.returnType = returnType; + } + + public List getParameters() { + return parameters; + } + + public void setParameters(List parameters) { + this.parameters = parameters; + } + + public void addLog(List log) { + responsesLog.add(log); + } + + public List> getResponsesLog() { + return responsesLog; + } + + public List getBodyLog() { + return bodyLog; + } + + public void addOperation(Operation operation) { + bodyLog.add(operation); + } + + public void setAccess(int access) { + this.access = access; + } + + public int getAccess() { + return access; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String[] getExceptions() { + return exceptions; + } + + public void setExceptions(String[] exceptions) { + this.exceptions = exceptions; + } + + @Override + public String toString() { + return "Method{" + + "name='" + name + '\'' + + ", returnType='" + returnType + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/MethodSignature.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/MethodSignature.java new file mode 100644 index 00000000..a3d4191e --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/MethodSignature.java @@ -0,0 +1,33 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures; + +import java.util.List; + +/** + * Created by ghessova on 25.04.2018. + */ +public class MethodSignature { + + private DataType returnType; + private List parameterTypes; + + public MethodSignature(DataType returnType, List parameterTypes) { + this.returnType = returnType; + this.parameterTypes = parameterTypes; + } + + public DataType getReturnType() { + return returnType; + } + + public void setReturnType(DataType returnType) { + this.returnType = returnType; + } + + public List getParameterTypes() { + return parameterTypes; + } + + public void setParameterTypes(List parameterTypes) { + this.parameterTypes = parameterTypes; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Operation.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Operation.java new file mode 100644 index 00000000..6c0a925b --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Operation.java @@ -0,0 +1,116 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures; + + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting.BytecodeDescriptorsProcessor; + +/** + * Created by ghessova on 08.04.2018. + */ +public class Operation { + + private int opcode; + private OperationType type; + private Object value; + private String dataType; + private int index; + private String owner; + private String name; + private String desc; + + private String description; + + public Operation(int opcode, OperationType type) { + this.opcode = opcode; + this.type = type; + } + + public Operation(OperationType type) { + this.type = type; + } + + public OperationType getType() { + return type; + } + + public void setType(OperationType type) { + this.type = type; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + public String getDataType() { + return dataType; + } + + public void setDataType(String dataType) { + this.dataType = dataType; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + if (type == OperationType.CALL) { + this.setDataType(BytecodeDescriptorsProcessor.processMethodDescriptor(desc).getReturnType().getBasicType()); + } + this.desc = desc; + } + + public enum OperationType { + + STORE, LOAD, STRING_CONSTANT, INT_CONSTANT, JUMP, RETURN, CALL, OTHER, FIELD; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + + this.description = description; + } + + @Override + public String toString() { + return description + ": " + type + "(opcode=" + opcode + "), " + (desc == null ? "" : desc); + } + + public int getOpcode() { + return opcode; + } + + public void setOpcode(int opcode) { + this.opcode = opcode; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/PathPart.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/PathPart.java new file mode 100644 index 00000000..11935584 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/PathPart.java @@ -0,0 +1,60 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by ghessova on 05.03.2018. + * Path part - class or method + */ +public class PathPart implements Annotated { + + protected String name; // class or method name +// protected String path; // hierarchical path of URL +// protected Set produces; // MIME types +// protected Set consumes; // MIME types + + protected Map annotations = new HashMap<>(); + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /* public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public Set getProduces() { + return produces; + } + + public void setProduces(Set produces) { + this.produces = produces; + } + + public Set getConsumes() { + return consumes; + } + + public void setConsumes(Set consumes) { + this.consumes = consumes; + } + */ + public void addAnnotation(Annotation annotation) { + this.annotations.put(annotation.getName(), annotation); + } + + public Map getAnnotations() { + return annotations; + } +} + diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/PathPartAttributes.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/PathPartAttributes.java new file mode 100644 index 00000000..0cfb172f --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/PathPartAttributes.java @@ -0,0 +1,74 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by ghessova on 27.03.2018. + */ +public class PathPartAttributes { + + private String name; + private List methods; // Spring resource can also contain information about http methods + private List paths; // hierarchical path of URL + private List produces; // MIME types + private List consumes; + + public PathPartAttributes() { + this.paths = new ArrayList<>(); + this.produces = new ArrayList<>(); + this.consumes = new ArrayList<>(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void addPath(String path) { + paths.add(path); + } + + public void addConsumes(String consumes) { + this.consumes.add(consumes); + } + + public void addProduces(String produces) { + this.produces.add(produces); + } + + public List getPaths() { + return paths; + } + + public void setPaths(List paths) { + this.paths = paths; + } + + public List getProduces() { + return produces; + } + + public void setProduces(List produces) { + this.produces = produces; + } + + public List getConsumes() { + return consumes; + } + + public void setConsumes(List consumes) { + this.consumes = consumes; + } + + public List getMethods() { + return methods; + } + + public void setMethods(List methods) { + this.methods = methods; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Variable.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Variable.java new file mode 100644 index 00000000..f7bc4c07 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/classmodel/structures/Variable.java @@ -0,0 +1,52 @@ +package cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by ghessova on 10.03.2018. + * Field or method parameter + */ +public class Variable implements Annotated { + + private String name; + private DataType dataType; + private Map annotations = new HashMap<>(); + + public Variable(DataType dataType) { + this.dataType = dataType; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public DataType getDataType() { + return dataType; + } + + public void setDataType(DataType dataType) { + this.dataType = dataType; + } + + public Map getAnnotations() { + return annotations; + } + + public void addAnnotation(Annotation annotation) { + annotations.put(annotation.getName(), annotation); + } + + @Override + public String toString() { + return "Variable{" + + "name='" + name + '\'' + + ", dataType='" + dataType + '\'' + + ", annotations=" + annotations + + '}'; + } +} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/definition/DispatcherDefinition.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/definition/DispatcherDefinition.java new file mode 100644 index 00000000..54c56953 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/definition/DispatcherDefinition.java @@ -0,0 +1,40 @@ +package cz.zcu.kiv.crce.restimpl.indexer.definition; + +import java.util.Map; + +/** + * Created by ghessova on 08.05.2018. + */ +public class DispatcherDefinition { + + private Map dispatchers; + + public Map getDispatchers() { + return dispatchers; + } + + public void setDispatchers(Map dispatchers) { + this.dispatchers = dispatchers; + } + + public static class Dispatcher { + private String dispatcher; + private String providers; + + public String getDispatcher() { + return dispatcher; + } + + public void setDispatcher(String dispatcher) { + this.dispatcher = dispatcher; + } + + public String getProviders() { + return providers; + } + + public void setProviders(String providers) { + this.providers = providers; + } + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/definition/RestApiDefinition.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/definition/RestApiDefinition.java new file mode 100644 index 00000000..b5d72b35 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/definition/RestApiDefinition.java @@ -0,0 +1,365 @@ +package cz.zcu.kiv.crce.restimpl.indexer.definition; + +import com.fasterxml.jackson.annotation.JsonProperty; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting.AnnotationProcessor; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting.BodyProcessor; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting.ExceptionHandler; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting.MemberProcessor; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting.ParameterNameProcessor; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting.ParameterRequirementProcessor; + + +import java.util.Set; + +/** + * Created by ghessova on 28.03.2018. + */ +public class RestApiDefinition { + + @JsonProperty + private String framework; + + @JsonProperty("resource_annotations") + private Set resourceAnnotations; + + @JsonProperty("endpoint_annotations") + private Set endpointAnnotations; + + @JsonProperty("url") + private Set urlProcessors; + + @JsonProperty("produces") + private Set producesProcessors; + + @JsonProperty("consumes") + private Set consumesProcessors; + + @JsonProperty("http_method") + private Set httpMethodProcessors; + + @JsonProperty("endpoint_parameters") + private Set endpointParametersProcessors; + + @JsonProperty("default_parameter_value") + private Set defaultParamValuesProcessors; + + @JsonProperty("parameter_name") + private ParameterNameProcessor parameterNameProcessor; + + @JsonProperty("parameter_requirement") + private ParameterRequirementProcessor parameterRequirementProcessor; + + @JsonProperty("default_cookie_value") + private Set defaultCookieValuesProcessors; + + @JsonProperty("cookie_name") + private ParameterNameProcessor cookieNameProcessor; + + @JsonProperty("default_header_value") + private Set defaultHeaderValuesProcessors; + + @JsonProperty("header_name") + private ParameterNameProcessor headerNameProcessor; + + @JsonProperty("body") + private BodyProcessor bodyProcessor; + + @JsonProperty("parameter_bean_annotations") + private Set parameterBeanAnnotations; + + @JsonProperty("generic_response_classes") + private Set genericResponseClasses; + + @JsonProperty("status_setting_methods") + private MemberProcessor statusSettingMethods; + + @JsonProperty("entity_setting_methods") + private Set entitySettingMethods; + + @JsonProperty("status_fields") + private MemberProcessor statusFields; + + @JsonProperty("cookie_class") + private String cookieClass; + + @JsonProperty("cookie_setting_method") + private MemberProcessor cookieSettingMethod; + + @JsonProperty("header_setting_method") + private MemberProcessor headerSettingMethod; + + @JsonProperty("default_object_mime") + private String defaultObjectMime; + + @JsonProperty("default_primitive_mime") + private String defaultPrimitiveMime; + + private boolean subresources; + + private boolean fieldParamAnnotations; + private boolean fieldParamSetterRequired; + + private String notNullAnnotation = "javax/validation/constraints/NotNull"; + + @JsonProperty("exception_handler") + private ExceptionHandler exceptionHandler; + + @JsonProperty("default_http_methods") + private Set defaultHttpMethods; + + public boolean supportSubresources() { + return subresources; + } + + public void setSubresources(boolean subresources) { + this.subresources = subresources; + } + + public Set getGenericResponseClasses() { + return genericResponseClasses; + } + + public void setGenericResponseClasses(Set genericResponseClasses) { + this.genericResponseClasses = genericResponseClasses; + } + + public Set getParameterBeanAnnotations() { + return parameterBeanAnnotations; + } + + public void setParameterBeanAnnotations(Set parameterBeanAnnotations) { + this.parameterBeanAnnotations = parameterBeanAnnotations; + } + + public String getFramework() { + return framework; + } + + public void setFramework(String framework) { + this.framework = framework; + } + + public Set getResourceAnnotations() { + return resourceAnnotations; + } + + public void setResourceAnnotations(Set resourceAnnotations) { + this.resourceAnnotations = resourceAnnotations; + } + + public Set getEndpointAnnotations() { + return endpointAnnotations; + } + + public void setEndpointAnnotations(Set endpointAnnotations) { + this.endpointAnnotations = endpointAnnotations; + } + + public Set getUrlProcessors() { + return urlProcessors; + } + + public void setUrlProcessors(Set urlProcessors) { + this.urlProcessors = urlProcessors; + } + + public Set getProducesProcessors() { + return producesProcessors; + } + + public void setProducesProcessors(Set producesProcessors) { + this.producesProcessors = producesProcessors; + } + + public Set getConsumesProcessors() { + return consumesProcessors; + } + + public void setConsumesProcessors(Set consumesProcessors) { + this.consumesProcessors = consumesProcessors; + } + + public Set getHttpMethodProcessors() { + return httpMethodProcessors; + } + + public void setHttpMethodProcessors(Set httpMethodProcessors) { + this.httpMethodProcessors = httpMethodProcessors; + } + + public Set getEndpointParametersProcessors() { + return endpointParametersProcessors; + } + + public void setEndpointParametersProcessors(Set endpointParametersProcessors) { + this.endpointParametersProcessors = endpointParametersProcessors; + } + + public ParameterNameProcessor getParameterNameProcessor() { + return parameterNameProcessor; + } + + public void setParameterNameProcessor(ParameterNameProcessor parameterNameProcessor) { + this.parameterNameProcessor = parameterNameProcessor; + } + + public Set getDefaultParamValuesProcessors() { + return defaultParamValuesProcessors; + } + + public void setDefaultParamValuesProcessors(Set defaultParamValuesProcessors) { + this.defaultParamValuesProcessors = defaultParamValuesProcessors; + } + + public Set getDefaultCookieValuesProcessors() { + return defaultCookieValuesProcessors; + } + + public void setDefaultCookieValuesProcessors(Set defaultCookieValuesProcessors) { + this.defaultCookieValuesProcessors = defaultCookieValuesProcessors; + } + + public ParameterNameProcessor getCookieNameProcessor() { + return cookieNameProcessor; + } + + public void setCookieNameProcessor(ParameterNameProcessor cookieNameProcessor) { + this.cookieNameProcessor = cookieNameProcessor; + } + + public Set getDefaultHeaderValuesProcessors() { + return defaultHeaderValuesProcessors; + } + + public void setDefaultHeaderValuesProcessors(Set defaultHeaderValuesProcessors) { + this.defaultHeaderValuesProcessors = defaultHeaderValuesProcessors; + } + + public ParameterNameProcessor getHeaderNameProcessor() { + return headerNameProcessor; + } + + public void setHeaderNameProcessor(ParameterNameProcessor headerNameProcessor) { + this.headerNameProcessor = headerNameProcessor; + } + + public BodyProcessor getBodyProcessor() { + return bodyProcessor; + } + + public void setBodyProcessor(BodyProcessor bodyProcessor) { + this.bodyProcessor = bodyProcessor; + } + + public MemberProcessor getStatusSettingMethods() { + return statusSettingMethods; + } + + public void setStatusSettingMethods(MemberProcessor statusSettingMethods) { + this.statusSettingMethods = statusSettingMethods; + } + + public Set getEntitySettingMethods() { + return entitySettingMethods; + } + + public void setEntitySettingMethods(Set entitySettingMethods) { + this.entitySettingMethods = entitySettingMethods; + } + + public MemberProcessor getStatusFields() { + return statusFields; + } + + public void setStatusFields(MemberProcessor statusFields) { + this.statusFields = statusFields; + } + + public String getCookieClass() { + return cookieClass; + } + + public void setCookieClass(String cookieClass) { + this.cookieClass = cookieClass; + } + + public MemberProcessor getCookieSettingMethod() { + return cookieSettingMethod; + } + + public void setCookieSettingMethod(MemberProcessor cookieSettingMethod) { + this.cookieSettingMethod = cookieSettingMethod; + } + + public MemberProcessor getHeaderSettingMethod() { + return headerSettingMethod; + } + + public void setHeaderSettingMethod(MemberProcessor headerSettingMethod) { + this.headerSettingMethod = headerSettingMethod; + } + + public String getNotNullAnnotation() { + return notNullAnnotation; + } + + public void setNotNullAnnotation(String notNullAnnotation) { + this.notNullAnnotation = notNullAnnotation; + } + + public String getDefaultObjectMime() { + return defaultObjectMime; + } + + public void setDefaultObjectMime(String defaultObjectMime) { + this.defaultObjectMime = defaultObjectMime; + } + + public String getDefaultPrimitiveMime() { + return defaultPrimitiveMime; + } + + public void setDefaultPrimitiveMime(String defaultPrimitiveMime) { + this.defaultPrimitiveMime = defaultPrimitiveMime; + } + + public ParameterRequirementProcessor getParameterRequirementProcessor() { + return parameterRequirementProcessor; + } + + public void setParameterRequirementProcessor(ParameterRequirementProcessor parameterRequirementProcessor) { + this.parameterRequirementProcessor = parameterRequirementProcessor; + } + + public boolean isFieldParamAnnotations() { + return fieldParamAnnotations; + } + + public void setFieldParamAnnotations(boolean fieldParamAnnotations) { + this.fieldParamAnnotations = fieldParamAnnotations; + } + + public boolean isFieldParamSetterRequired() { + return fieldParamSetterRequired; + } + + public void setFieldParamSetterRequired(boolean fieldParamSetterRequired) { + this.fieldParamSetterRequired = fieldParamSetterRequired; + } + + public ExceptionHandler getExceptionHandler() { + return exceptionHandler; + } + + public void setExceptionHandler(ExceptionHandler exceptionHandler) { + this.exceptionHandler = exceptionHandler; + } + + public Set getDefaultHttpMethods() { + return defaultHttpMethods; + } + + public void setDefaultHttpMethods(Set defaultHttpMethods) { + this.defaultHttpMethods = defaultHttpMethods; + } +} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/Activator.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/Activator.java new file mode 100644 index 00000000..b14ead6e --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/Activator.java @@ -0,0 +1,30 @@ +package cz.zcu.kiv.crce.restimpl.indexer.internal; + + +import cz.zcu.kiv.crce.metadata.MetadataFactory; +import cz.zcu.kiv.crce.metadata.service.MetadataService; +import cz.zcu.kiv.crce.plugin.Plugin; +import cz.zcu.kiv.crce.plugin.PluginManager; +import org.apache.felix.dm.DependencyActivatorBase; +import org.apache.felix.dm.DependencyManager; +import org.osgi.framework.BundleContext; + + + +/** + * Created by ghessova on 23.03.2018. + */ +public class Activator extends DependencyActivatorBase { + + + @Override + public void init(BundleContext bundleContext, DependencyManager dependencyManager) throws Exception { + dependencyManager.add(createComponent() + .setInterface(Plugin.class.getName(), null) + .setImplementation(RestimplResourceIndexer.class) + .add(createServiceDependency().setRequired(true).setService(MetadataFactory.class)) + .add(createServiceDependency().setRequired(true).setService(MetadataService.class)) + .add(createServiceDependency().setRequired(true).setService(PluginManager.class))); + + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplMetadataConstants.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplMetadataConstants.java new file mode 100644 index 00000000..23874370 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplMetadataConstants.java @@ -0,0 +1,55 @@ +package cz.zcu.kiv.crce.restimpl.indexer.internal; + +import cz.zcu.kiv.crce.metadata.AttributeType; +import cz.zcu.kiv.crce.metadata.impl.ListAttributeType; +import cz.zcu.kiv.crce.metadata.impl.SimpleAttributeType; +import cz.zcu.kiv.crce.metadata.namespace.NsCrceIdentity; + +/** + * Created by ghessova on 18.04.2018. + * + * Constants for rest implementation representation in CRCE metada (namespaces, attributes). + * + */ +public interface RestimplMetadataConstants { + + String MAIN_CATEGORY = "restimpl"; + + // capabilities namespaces + String NS__CRCE_IDENTITY = NsCrceIdentity.NAMESPACE__CRCE_IDENTITY; + String NS__RESTIMPL_IDENTITY = MAIN_CATEGORY + ".identity"; + String NS__RESTIMPL_ENDPOINT = MAIN_CATEGORY + ".endpoint"; + + // properties namespaces + String NS_RESTIMPL_REQUEST_BODY = NS__RESTIMPL_ENDPOINT + ".requestbody"; + String NS_RESTIMPL_REQUESTPARAMETER = NS__RESTIMPL_ENDPOINT + ".requestparameter"; + String NS_RESTIMPL_RESPONSEPARAMETER = NS__RESTIMPL_ENDPOINT + ".responseparameter"; + String NS_RESTIMPL_RESPONSE = NS__RESTIMPL_ENDPOINT + ".response"; + + // attributes for NS__RESTIMPL_IDENTITY capability + AttributeType ATTR__RESTIMPL_FRAMEWORK = new SimpleAttributeType<>("framework", String.class); + + // attributes for NS__RESTIMPL_ENDPOINT capability + AttributeType ATTR__RESTIMPL_NAME = new SimpleAttributeType<>("name", String.class); + ListAttributeType ATTR__RESTIMPL_ENDPOINT_PATH = new ListAttributeType("path"); + ListAttributeType ATTR__RESTIMPL_ENDPOINT_METHOD = new ListAttributeType("method"); + ListAttributeType ATTR__RESTIMPL_ENDPOINT_CONSUMES = new ListAttributeType("consumes"); + ListAttributeType ATTR__RESTIMPL_ENDPOINT_PRODUCES = new ListAttributeType("produces"); + + // attributes for NS_RESTIMPL_PARAMETER capability + //AttributeType ATTR__RESTIMPL_PARAMETER_NAME = new SimpleAttributeType<>("name", String.class); + AttributeType ATTR__RESTIMPL_DATETYPE = new SimpleAttributeType<>("datetype", String.class); + AttributeType ATTR__RESTIMPL_DEFAULT_VALUE = new SimpleAttributeType<>("defaultValue", String.class); + AttributeType ATTR__RESTIMPL_PARAMETER_CATEGEORY = new SimpleAttributeType<>("category", String.class); + AttributeType ATTR__RESTIMPL_ARRAY = new SimpleAttributeType<>("isArray", Long.class); + AttributeType ATTR__RESTIMPL_OPTIONAL = new SimpleAttributeType<>("isOptional", Long.class); + + AttributeType ATTR__RESTIMPL_RESPONSE_STATUS = new SimpleAttributeType<>("status", Long.class); + AttributeType ATTR__RESTIMPL_RESPONSE_ID = new SimpleAttributeType<>("id", String.class); + + + + + + +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplMetadataManager.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplMetadataManager.java new file mode 100644 index 00000000..d38bdd2c --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplMetadataManager.java @@ -0,0 +1,196 @@ +package cz.zcu.kiv.crce.restimpl.indexer.internal; + +import cz.zcu.kiv.crce.metadata.*; +import cz.zcu.kiv.crce.metadata.impl.ListAttributeType; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.Endpoint; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.EndpointParameter; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.EndpointRequestBody; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.EndpointResponse; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.RequestParameter; + +import java.util.*; + +/** + * Created by ghessova on 18.04.2018. + */ +public class RestimplMetadataManager { + + private volatile MetadataFactory metadataFactory; + + /** + * Constructor for metadataFactory injection. + * @param metadataFactory metadata factory + */ + RestimplMetadataManager(MetadataFactory metadataFactory) { + this.metadataFactory = metadataFactory; + } + + /** + * Convert REST API model represented by a set of endpoint into CRCE metadata and sets them to the resource. + * @param resource CRCE resource representing the input component + * @param endpoints set of REST API endpoint + * @param framework REST API framework od specification name + */ + public void setMetadata(Resource resource, Collection endpoints, String framework) { + // Capability - restimpl identity + Capability restimplIdentityCapability = metadataFactory.createCapability(RestimplMetadataConstants.NS__RESTIMPL_IDENTITY); + restimplIdentityCapability.setAttribute(RestimplMetadataConstants.ATTR__RESTIMPL_FRAMEWORK, framework); + resource.addCapability(restimplIdentityCapability); + resource.addRootCapability(restimplIdentityCapability); + Set endpointCapabilities = convertToMetadata(endpoints); + for (Capability endpointCapability : endpointCapabilities) { + resource.addCapability(endpointCapability); + restimplIdentityCapability.addChild(endpointCapability); + + } + } + + private Set convertToMetadata(Collection endpoints) { + Set capabilities = new HashSet<>(); + for (Endpoint endpoint : endpoints) { + capabilities.add(createEndpointCapability(endpoint)); + } + return capabilities; + + } + + private Capability createEndpointCapability(Endpoint endpoint) { + Capability endpointCapability = metadataFactory.createCapability(RestimplMetadataConstants.NS__RESTIMPL_ENDPOINT); + + // set attributes (name, paths, methods, consumes, produces) + setIfSet(endpointCapability, RestimplMetadataConstants.ATTR__RESTIMPL_NAME, endpoint.getName()); + setIfSet(endpointCapability, RestimplMetadataConstants.ATTR__RESTIMPL_ENDPOINT_PATH, endpoint.getPaths()); + setIfSet(endpointCapability, RestimplMetadataConstants.ATTR__RESTIMPL_ENDPOINT_METHOD, new ArrayList<>(endpoint.getHttpMethods())); + setIfSet(endpointCapability, RestimplMetadataConstants.ATTR__RESTIMPL_ENDPOINT_CONSUMES, new ArrayList<>(endpoint.getConsumes())); + setIfSet(endpointCapability, RestimplMetadataConstants.ATTR__RESTIMPL_ENDPOINT_PRODUCES, new ArrayList<>(endpoint.getProduces())); + + // add corresponding properties - body, parameters, responses, cookies, headers + addPropertyIfSet(endpointCapability, createBodyProperty(endpoint.getBody())); + + // request parameters + for (RequestParameter parameter : endpoint.getParameters()) { + addPropertyIfSet(endpointCapability, createRequestParamProperty(parameter)); + } + + // responses + int i = 0; + for (EndpointResponse response : endpoint.getResponses()) { + String responseId = endpoint.getName() + i++; // todo not unique + addPropertyIfSet(endpointCapability, createResponseProperty(response, responseId)); + // response cookies and headers + for (EndpointParameter parameter : response.getParameters()) { + addPropertyIfSet(endpointCapability, createResponseParamProperty(parameter, responseId)); + } + } + + return endpointCapability; + } + + private Property createBodyProperty(EndpointRequestBody body) { + if (body == null) { + return null; + } + Property bodyProperty = metadataFactory.createProperty(RestimplMetadataConstants.NS_RESTIMPL_REQUEST_BODY); + setIfSet(bodyProperty, RestimplMetadataConstants.ATTR__RESTIMPL_DATETYPE, body.getStructure()); + setIfSet(bodyProperty, RestimplMetadataConstants.ATTR__RESTIMPL_ARRAY, body.isArray() ? (long)1 : 0); + setIfSet(bodyProperty, RestimplMetadataConstants.ATTR__RESTIMPL_OPTIONAL, body.isOptional() ? (long)1 : 0); + return bodyProperty; + } + + private Property createRequestParamProperty(RequestParameter parameter) { + Property property = createParamProperty(parameter, RestimplMetadataConstants.NS_RESTIMPL_REQUESTPARAMETER); + if (parameter == null) { + return null; + } + setIfSet(property, RestimplMetadataConstants.ATTR__RESTIMPL_DEFAULT_VALUE, parameter.getDefaultValue()); + setIfSet(property, RestimplMetadataConstants.ATTR__RESTIMPL_OPTIONAL, parameter.isOptional() ? (long)1 : 0); + return property; + } + + private Property createResponseParamProperty(EndpointParameter parameter, String responseId) { + Property property = createParamProperty(parameter, RestimplMetadataConstants.NS_RESTIMPL_RESPONSEPARAMETER); + if (parameter == null) { + return null; + } + setIfSet(property, RestimplMetadataConstants.ATTR__RESTIMPL_RESPONSE_ID, responseId); + + return property; + } + + private Property createParamProperty(EndpointParameter parameter, String propertyNamespace) { + if (parameter == null) { + return null; + } + Property paramProperty = metadataFactory.createProperty(propertyNamespace); + setIfSet(paramProperty, RestimplMetadataConstants.ATTR__RESTIMPL_NAME, parameter.getName()); + setIfSet(paramProperty, RestimplMetadataConstants.ATTR__RESTIMPL_DATETYPE, parameter.getDataType()); + setIfSet(paramProperty, RestimplMetadataConstants.ATTR__RESTIMPL_PARAMETER_CATEGEORY, parameter.getCategory().toString()); + setIfSet(paramProperty, RestimplMetadataConstants.ATTR__RESTIMPL_ARRAY, parameter.isArray() ? (long)1 : 0); + return paramProperty; + } + + private Property createResponseProperty(EndpointResponse response, String id) { + if (response == null) { + return null; + } + Property responseProperty = metadataFactory.createProperty(RestimplMetadataConstants.NS_RESTIMPL_RESPONSE); + setIfSet(responseProperty, RestimplMetadataConstants.ATTR__RESTIMPL_RESPONSE_ID, id); + setIfSet(responseProperty, RestimplMetadataConstants.ATTR__RESTIMPL_DATETYPE, response.getStructure()); + setIfSet(responseProperty, RestimplMetadataConstants.ATTR__RESTIMPL_RESPONSE_STATUS, (long)response.getStatus()); + setIfSet(responseProperty, RestimplMetadataConstants.ATTR__RESTIMPL_ARRAY, response.isArray() ? (long)1 : 0); + return responseProperty; + } + + /** + * This function sets attribute of {@link cz.zcu.kiv.crce.metadata.Capability} to a value provided that passed value + * is not null. + * + * @param Datatype of attribute-value pair. + * @param capability {@link cz.zcu.kiv.crce.metadata.Capability} for which attribute will be set. + * @param attribute attribute to set. + * @param value value to set. + * @return Returns true if value was set. Returns false otherwise. + */ + protected boolean setIfSet(Capability capability, AttributeType attribute, T value) { + if (capability != null && value != null) { + capability.setAttribute(attribute, value); + return true; + } + return false; + } + + protected boolean setIfSet(Capability capability, ListAttributeType attribute, List values) { + if (capability != null && values != null) { + capability.setAttribute(attribute, values); + return true; + } + return false; + } + + /** + * This function sets attribute of {@link cz.zcu.kiv.crce.metadata.Property} to a value provided that passed value + * is not null. + * + * @param Datatype of attribute-value pair. + * @param property {@link cz.zcu.kiv.crce.metadata.Property} for which attribute will be set. + * @param attribute attribute to set. + * @param value value to set. + * @return Returns true if value was set. Returns false otherwise. + */ + protected boolean setIfSet(Property property, AttributeType attribute, T value) { + if (property != null && value != null) { + property.setAttribute(attribute, value); + return true; + } + return false; + } + + private boolean addPropertyIfSet(Capability capability, Property property) { + if (capability != null && property != null) { + capability.addProperty(property); + return true; + } + return false; + } + +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplResourceIndexer.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplResourceIndexer.java new file mode 100644 index 00000000..cbfb07c8 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/internal/RestimplResourceIndexer.java @@ -0,0 +1,137 @@ +package cz.zcu.kiv.crce.restimpl.indexer.internal; + +import cz.zcu.kiv.crce.metadata.MetadataFactory; +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.metadata.indexer.AbstractResourceIndexer; +import cz.zcu.kiv.crce.metadata.service.MetadataService; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting.MyClassVisitor; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting.ResultCollector; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.ClassStruct; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting.RestApiReconstructor; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.Endpoint; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting.RestApiReconstructorImpl; +import cz.zcu.kiv.crce.restimpl.indexer.util.WebXmlParser; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Opcodes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * Created by ghessova on 23.03.2018. + * + * @author Gabriela Hessova + * + * Indexer for REST model extraction from input archive. + */ +public class RestimplResourceIndexer extends AbstractResourceIndexer { + + // injected by dependency manager (in Activator) + private volatile MetadataFactory metadataFactory; + private volatile MetadataService metadataService; + + private static final Logger logger = LoggerFactory.getLogger(RestimplResourceIndexer.class); + + /** + * Indexer's entry point. + * + * Indexing consists of three steps: + * 1. Class model representation is created from the archive. + * 2. REST API model is created based on analysis of the class model. + * 3. REST model is converted to metadata, which are added to the resource. + * + * @param input archive input stream + * @param resource CRCE resource the metadata are set to + * @return list of categories assigned by this indexer ('restimpl' or empty list) + */ + @Override + public List index(InputStream input, Resource resource) { + + // ARCHIVE PROCESSING + WebXmlParser.Result webXmlResult = null; + try { // borrowed code.. - parsing input stream and collecting class entry information + ZipInputStream jis = new ZipInputStream(input); + ClassVisitor classVisitor = new MyClassVisitor(Opcodes.ASM5); + for (ZipEntry e = jis.getNextEntry(); e != null; e = jis.getNextEntry()) { + if (e.getName().endsWith(".class")) { + parseClass(new ClassReader(getEntryInputStream(jis)), classVisitor); + } + else if (e.getName().endsWith("web.xml") && webXmlResult == null) { + WebXmlParser webXmlParser = new WebXmlParser(); + webXmlResult = webXmlParser.parseWebXml(getEntryInputStream(jis)); + } + } + } catch (IOException e) { + logger.error("Could not create class model.", e); + } + Map classes = ResultCollector.getInstance().getClasses(); + logger.debug("Class model extracted"); + + // REST API RECONSTRUCTION + RestApiReconstructor restApiReconstructor = new RestApiReconstructorImpl(classes, webXmlResult); + Collection endpoints = null; + try { + endpoints = restApiReconstructor.extractEndpoints(); + } catch (Exception e) { + logger.error("Could not extract endpoints", e); + } + String framework = restApiReconstructor.getFramework(); // 'undefined' when no framework was identified + + // CONVERTING REST API MODEL TO METADATA + if (endpoints == null || endpoints.isEmpty()) { + return Collections.emptyList(); + } + else { + logger.debug("REST API model extracted"); + // save endpoints and metadata + RestimplMetadataManager metadataManager = new RestimplMetadataManager(metadataFactory); + metadataManager.setMetadata(resource, endpoints, framework); + + // label the resource with categories and other common attributes + metadataService.addCategory(resource, RestimplMetadataConstants.MAIN_CATEGORY); // assign main category tag + logger.debug("Restimpl indexing finished"); + + return Collections.singletonList(RestimplMetadataConstants.MAIN_CATEGORY); + } + } + + // borrowed code + private static InputStream getEntryInputStream(ZipInputStream jis) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buf = new byte[1024]; + int n; + while ((n = jis.read(buf, 0, buf.length)) > 0) { + baos.write(buf, 0, n); + } + return new ByteArrayInputStream(baos.toByteArray()); + } + + private static void parseClass(ClassReader classReader, ClassVisitor visitor) { + classReader.accept(visitor, ClassReader.SKIP_DEBUG); + + } + + public MetadataFactory getMetadataFactory() { + return metadataFactory; + } + + public void setMetadataFactory(MetadataFactory metadataFactory) { + this.metadataFactory = metadataFactory; + } + + public MetadataService getMetadataService() { + return metadataService; + } + + public void setMetadataService(MetadataService metadataService) { + this.metadataService = metadataService; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/AnnotationProcessor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/AnnotationProcessor.java new file mode 100644 index 00000000..3f7e272a --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/AnnotationProcessor.java @@ -0,0 +1,112 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + +import com.fasterxml.jackson.annotation.JsonProperty; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Annotation; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Created by ghessova on 27.03.2018. + */ +public class AnnotationProcessor { + + @JsonProperty("annotation") + private String annotationName; + @JsonProperty("processing_way") + private AnnotationProcessingWay processingWay; + @JsonProperty + private Map mapping; // needed for FROM_NAME processing + @JsonProperty + private Set valueKeys; + @JsonProperty + private String result; + + public Set processAnnotation(Annotation annotation) { + if (!annotationName.equals(annotation.getName())) return null; + if (processingWay == AnnotationProcessingWay.FROM_NAME) { + Set results = new HashSet<>(); + if (mapping != null) { + results.add(mapping.get(annotationName)); + } + else { + results.add(result); + } + return results; + } + else { + Set results = new HashSet<>(); + for (String valueKey : valueKeys) { + + Object result = annotation.getValues().get(valueKey); + if (result != null) { + if (mapping != null) { // else throw IllegalArgumentException + results.add(mapping.get(annotationName)); + } + else { // return result directly if there is no mapping defined + if (result instanceof Set) { + for (Object s : (Set)result) { + results.add(String.valueOf(s)); + } + } + else { + results.add(String.valueOf(result)); + } + } + } + } + return results; + } + } + + + enum AnnotationProcessingWay { + FROM_NAME, // result is determined by annotation name + FROM_VALUE; // result is determined by one of the annotation values + } + + public String getAnnotationName() { + return annotationName; + } + + public void setAnnotationName(String annotationName) { + this.annotationName = annotationName; + } + + public AnnotationProcessingWay getProcessingWay() { + return processingWay; + } + +// public void setProcessingWay(AnnotationProcessingWay processingWay) { +// this.processingWay = processingWay; +// } + + public void setProcessingWay(String processingWay) { + this.processingWay = AnnotationProcessingWay.valueOf(processingWay.toUpperCase()); + } + + public Map getMapping() { + return mapping; + } + + public void setMapping(Map mapping) { + this.mapping = mapping; + } + + public Set getValueKeys() { + return valueKeys; + } + + public void setValueKeys(Set valueKeys) { + this.valueKeys = valueKeys; + } + + public Object getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/BasicParameterConverter.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/BasicParameterConverter.java new file mode 100644 index 00000000..c6ff2d69 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/BasicParameterConverter.java @@ -0,0 +1,66 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + +import cz.zcu.kiv.crce.restimpl.indexer.definition.RestApiDefinition; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Variable; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.ParameterCategory; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.RequestParameter; +import cz.zcu.kiv.crce.restimpl.indexer.util.Util; + +/** + * Created by ghessova on 30.03.2018. + */ +public class BasicParameterConverter { + + private RestApiDefinition restApiDefinition; + + public BasicParameterConverter(RestApiDefinition restApiDefinition) { + this.restApiDefinition = restApiDefinition; + } + + public RequestParameter processParameter(Variable variable, boolean determineCategory) { + RequestParameter parameter = new RequestParameter(); + parameter.setName(getParameterName(variable)); + if (determineCategory) { + parameter.setCategory(getParameterCategory(variable)); + } + parameter.setDataType(getParameterDataType(variable)); + parameter.setDefaultValue(getParameterDefaultValue(variable)); + parameter.setOptional(isOptional(variable)); + return parameter; + } + + /** + * Returns true if the variable is optional. + * @param variable + * @return + */ + public boolean isOptional(Variable variable) { + // isOptional == !required + return !restApiDefinition.getParameterRequirementProcessor().process(variable); + } + + private ParameterCategory getParameterCategory(Variable variable) { + String paramCategory = Util.getResultFromAnnotations(restApiDefinition.getEndpointParametersProcessors(), variable.getAnnotations()); + if (paramCategory == null) { + // todo log + return null; + } + if ("request".equals(paramCategory)) { + return null; // category (query or form) is determined by consumes + } + return ParameterCategory.valueOf(paramCategory.toUpperCase()); + } + + public String getParameterName(Variable variable) { + ParameterNameProcessor processor = restApiDefinition.getParameterNameProcessor(); + return processor.process(variable); + } + + public String getParameterDataType(Variable variable) { + return variable.getDataType().getBasicType(); + } + + public String getParameterDefaultValue(Variable variable) { + return Util.getResultFromAnnotations(restApiDefinition.getDefaultParamValuesProcessors(), variable.getAnnotations()); + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/BodyProcessor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/BodyProcessor.java new file mode 100644 index 00000000..221052df --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/BodyProcessor.java @@ -0,0 +1,38 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + +import java.util.Set; + +/** + * Created by ghessova on 02.04.2018. + */ +public class BodyProcessor { + + private boolean withoutAnnotations; + + private Set annotations; + private Set excludingAnnotations; + + public boolean isWithoutAnnotations() { + return withoutAnnotations; + } + + public Set getExcludingAnnotations() { + return excludingAnnotations; + } + + public void setExcludingAnnotations(Set excludingAnnotations) { + this.excludingAnnotations = excludingAnnotations; + } + + public void setWithoutAnnotations(boolean withoutAnnotations) { + this.withoutAnnotations = withoutAnnotations; + } + + public Set getAnnotations() { + return annotations; + } + + public void setAnnotations(Set annotations) { + this.annotations = annotations; + } +} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ClassModelProcessor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ClassModelProcessor.java new file mode 100644 index 00000000..74388d53 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ClassModelProcessor.java @@ -0,0 +1,132 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.ClassStruct; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Method; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.PathPart; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.PathPartAttributes; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Variable; +import cz.zcu.kiv.crce.restimpl.indexer.definition.RestApiDefinition; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.Endpoint; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.EndpointResponse; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.RequestParameter; + +import java.util.Map; +import java.util.Set; + +/** + * Created by ghessova on 27.03.2018. + */ +public interface ClassModelProcessor { + + /** + * Returns true if the class is a resource of endpoints. + * @param clazz class + * @return true if the class is a resource of endpoints + */ + boolean isResource(ClassStruct clazz); + + /** + * Returns true if the class is a request filter. + * @param clazz class + * @return true if the class is a request filter + */ + boolean isRequestFilter(ClassStruct clazz); + + /** + * Returns true if the class is a parameter bean. + * @param clazz class + * @return true if the class is a parameter bean + */ + boolean canBeParameterBean(ClassStruct clazz, Variable variable); + + /** + * Returns true if the method is a REST endpoint. + * @param method method + * @return true if the method is a REST endpoint + */ + boolean isEndpoint(Method method); + + /** + * Extracts path attributes from a path part. + * @param pathPart path part - class or method + * @return path attributes (name, paths, produces, consumes) + */ + PathPartAttributes getPathAttributes(PathPart pathPart); + + /** + * Returns true if the variable represents an endpoint request parameter (query/path/form/matrix/header/cookie). + * @param variable method parameter or parameter bean field + * @return true if the variable represents an endpoint request parameter + */ + boolean isRequestParameter(Variable variable); + + /** + * Converts variable into an endpoint request parameter. + * @param variable method parameter or parameter bean field + * @return endpoint request parameter + */ + // EndpointParameter convertParameter(Variable variable); + + RequestParameter convertParameter(Variable variable, Set consumes); + + /** + * Returns true if the variable represents a HTTP request body. + * @param variable method parameter + * @return true if the variable represents a HTTP request body + */ + boolean isRequestBody(Variable variable); + + /** + * Returns true if the class represents a subresource (jaxrs). + * @param clazz class + * @return true if the class represents a subresource + */ + boolean isSubresource(ClassStruct clazz); + + /** + * Returns true if the class is a generic response class. + * @param className class name + * @return true if the class is a generic response class + */ + boolean isGenericResponseClass(String className); + + /** + * Gets the REST API definition applied in the current archive being processed. + * @return REST API definition + */ + RestApiDefinition getDefinition(); + + /** + * Extracts request parameters from JavaBean. + * @param endpoint processed endpoint + * @param paramBeanVariable method parameter representing parameter bean + * @param pathVariables set of path variables extracted from URL + * @param classesMap map of all classes in archive + * @return set of request parameters + */ + Set getParamsFromBean(Endpoint endpoint, Variable paramBeanVariable, Set pathVariables, Map classesMap); + + /** + * Returns true if the class is an exception handler. + * @param clazz class + * @return true if the class is an exception handler + */ + boolean isExceptionHandler(ClassStruct clazz); + + /** + * Prepares exception to responses mapping . + * @param exceptionHandlers classes representing exception handlers + * @param classesMap map of all classes in archive + * @return map where key is exception name and value set of possible responses the exception is mapped to + */ + Map> prepareExceptionsMappings(Set exceptionHandlers, Map classesMap); + + /** + * Extracts responses from method declared exceptions + * @param exceptions array of exceptions declared in method signatures + * @param mappings exception to responses mapping + * @return set of responses corresponding to the given exceptions + */ + Set getResponsesFromExceptions(String[] exceptions, Map> mappings); + +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ClassModelProcessorImpl.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ClassModelProcessorImpl.java new file mode 100644 index 00000000..63987e05 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ClassModelProcessorImpl.java @@ -0,0 +1,369 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.ClassStruct; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Field; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Method; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.PathPart; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.PathPartAttributes; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Variable; +import cz.zcu.kiv.crce.restimpl.indexer.definition.RestApiDefinition; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.Endpoint; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.EndpointParameter; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.EndpointResponse; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.ParameterCategory; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.RequestParameter; +import cz.zcu.kiv.crce.restimpl.indexer.util.Util; +import org.objectweb.asm.Opcodes; + + +import java.util.*; + + +/** + * Created by ghessova on 28.03.2018. + */ +public class ClassModelProcessorImpl implements ClassModelProcessor { + + private Map definitions; + + private RestApiDefinition definition; + private Set paramAnnotationNames; + + + public ClassModelProcessorImpl(Map definitions) { + this.definitions = definitions; + } + + private void setDefinition(RestApiDefinition definition) { + this.definition = definition; + paramAnnotationNames = getAnnotationNames(definition.getEndpointParametersProcessors()); + + } + + + + @Override + public boolean isResource(ClassStruct clazz) { + for (String annotationName : clazz.getAnnotations().keySet()) { + if (definition == null) { + for (RestApiDefinition restApiDefinition : definitions.values()) { + if (restApiDefinition.getResourceAnnotations().contains(annotationName)) { + setDefinition(restApiDefinition); + return true; + } + } + } + else { + if (definition.getResourceAnnotations().contains(annotationName)) { + return true; + } + } + } + return false; + } + + @Override + public boolean isRequestFilter(ClassStruct clazz) { + String[] interfaces = clazz.getInterfaces(); + if (interfaces == null) { + return false; + } + for (String anInterface : interfaces) { + if ("javax/ws/rs/container/ContainerRequestFilter".equals(anInterface)) { + return true; + } + } + return false; + } + + @Override + public boolean canBeParameterBean(ClassStruct clazz, Variable variable) { + if (clazz == null) { + return false; + } + if (definition.getParameterBeanAnnotations() != null && !definition.getParameterBeanAnnotations().isEmpty()) { + for (String annotation : definition.getParameterBeanAnnotations()) { + if (variable.getAnnotations().containsKey(annotation)) { + return true; + } + } + return false; + } + /* for (Variable field : clazz.getFields()) { + if (isRequestParameter(field)) { + return true; + } + }*/ + return true; + } + + + @Override + public boolean isEndpoint(Method method) { + if (method.getAccess() != Opcodes.ACC_PUBLIC) { + return false; + } + for (String annotationName : method.getAnnotations().keySet()) { + if (definition.getEndpointAnnotations().contains(annotationName)) { + return true; + } + } + return false; + } + + @Override + public PathPartAttributes getPathAttributes(PathPart pathPart) { + PathPartAttributes attributes = new PathPartAttributes(); + attributes.setName(pathPart.getName()); + attributes.setMethods(Util.getResultsFromAnnotations(definition.getHttpMethodProcessors(), pathPart.getAnnotations())); + attributes.setPaths(Util.getResultsFromAnnotations(definition.getUrlProcessors(), pathPart.getAnnotations())); + attributes.setConsumes(Util.getResultsFromAnnotations(definition.getConsumesProcessors(), pathPart.getAnnotations())); + attributes.setProduces(Util.getResultsFromAnnotations(definition.getProducesProcessors(), pathPart.getAnnotations())); + if (attributes.getPaths().isEmpty()) { + attributes.getPaths().add(""); + } + + return attributes; + } + + @Override + public boolean isRequestParameter(Variable variable) { + for (String annotationName : variable.getAnnotations().keySet()) { + if (paramAnnotationNames.contains(annotationName)) { + return true; + } + } + return false; + } + + + + /* public EndpointParameter convertParameter(Variable variable) { + BasicParameterConverter converter = new BasicParameterConverter(definition); + EndpointParameter parameter = converter.processParameter(variable); + if (parameter.getCategory() == ParameterCategory.PATH) { + parameter.setOptional(false); + } + return parameter; + }*/ + + + /** + * For Spring returns true if the parameter has RequestBody annotation, + * for JAX-RS returns true if the parameter does not have any annotations. + * @param variable method parameter + * @return true if parameter represents request body + */ + @Override + public boolean isRequestBody(Variable variable) { + if (definition.getBodyProcessor().isWithoutAnnotations()) { + for (String annotation : definition.getBodyProcessor().getExcludingAnnotations()) { + if (variable.getAnnotations().containsKey(annotation)) { + return false; + } + } + return true; + } + else { + for (String annotation : definition.getBodyProcessor().getAnnotations()) { + if (variable.getAnnotations().containsKey(annotation)) { + return true; + } + } + return false; + } + } + + @Override + public boolean isSubresource(ClassStruct clazz) { + if (!definition.supportSubresources()) return false; // framework does not allow subresources (spring) + for (Method method : clazz.getMethods()) { + if (isEndpoint(method)) return true; + } + return false; + } + + + + @Override + public boolean isGenericResponseClass(String className) { + return definition.getGenericResponseClasses().contains(className); + } + + @Override + public RestApiDefinition getDefinition() { + return definition; + } + + private Set getAnnotationNames(Set processors) { + Set annotations = new HashSet<>(); + for (AnnotationProcessor processor : processors) { + annotations.add(processor.getAnnotationName()); + } + return annotations; + } + + public RequestParameter convertParameter(Variable variable, Set consumes) { + // get normal information from annotations + BasicParameterConverter converter = new BasicParameterConverter(definition); + RequestParameter parameter = converter.processParameter(variable, true); + editCategoryAccordingToConsumes(consumes, parameter); + if (parameter.getCategory().equals(ParameterCategory.PATH) || variable.getAnnotations().containsKey(definition.getNotNullAnnotation())) { + parameter.setOptional(false); // path parameter is always required + } + return parameter; + } + + /* public EndpointParameter convertFieldToParameter(Field field, Set consumes) { + // get normal information from annotations + BasicParameterConverter converter = new BasicParameterConverter(definition); + EndpointParameter parameter = converter.processParameter(field, fa); + editCategoryAccordingToConsumes(consumes, parameter); + return parameter; + }*/ + + private void editCategoryAccordingToConsumes(Set consumes, EndpointParameter parameter) { + if (parameter.getCategory() == null) { // not determined yet (request parameter in spring) + if (consumes != null && consumes.contains("application/x-www-form-urlencoded")) { // todo + parameter.setCategory(ParameterCategory.FORM); // form parameters are part of a body + } + else { + parameter.setCategory(ParameterCategory.QUERY); + } + } + } + + + public Set getParamsFromBean(Endpoint endpoint, Variable paramBeanVariable, Set pathTemplates, Map classesMap) { + Set parameters = new HashSet<>(); + // retrieve all adepts for endpoint parameters + Set fields = getAllFields(paramBeanVariable, definition.isFieldParamSetterRequired(), classesMap); + if (definition.isFieldParamAnnotations()) { + for (Field field : fields) { // normal way where parameters must be annotated + if (isRequestParameter(field)) { + parameters.add(convertParameter(field, endpoint.getConsumes())); + } + } + } + else { + for (Field field : fields) { // spring way.. + BasicParameterConverter converter = new BasicParameterConverter(definition); + RequestParameter parameter = new RequestParameter(); + parameter.setName(field.getName()); + parameter.setDataType(converter.getParameterDataType(field)); + parameter.setCategory(pathTemplates.contains(parameter.getName()) ? ParameterCategory.PATH : null); + editCategoryAccordingToConsumes(endpoint.getConsumes(), parameter); + parameter.setOptional(converter.isOptional(field)); + if (parameter.getCategory() == ParameterCategory.PATH) { + parameter.setOptional(false); + } + parameters.add(parameter); + } + } + return parameters; + + } + + private Set getAllFields(Variable variable, boolean setterRequired, Map classesMap) { + Set fields = new HashSet<>(); + Set classFields; + for (ClassStruct clazz = classesMap.get(variable.getDataType().getBasicType()); + clazz != null; + clazz = classesMap.get(clazz.getParent())) { + classFields = clazz.getFields(); + for (Field classField : classFields) { + boolean hasSetter = hasSetter(classField, clazz.getMethods()); + if (setterRequired && hasSetter || !setterRequired && (hasSetter || classField.getAccess() == Opcodes.ACC_PUBLIC)) { + fields.add(classField); + } + } + } + return fields; + } + + + + private boolean hasSetter(Field field, Collection methods) { + String fieldName = field.getName(); + fieldName = fieldName.replaceFirst("" + fieldName.charAt(0), String.valueOf(fieldName.charAt(0)).toUpperCase()); + String setterName = "set" + fieldName; + for (Method method : methods) { + if (setterName.equals(method.getName()) && method.getAccess() == Opcodes.ACC_PUBLIC) { + List parameters = method.getParameters(); + if (parameters.size() == 1 && parameters.get(0).getDataType().equals(field.getDataType())) { + return true; + } + } + } + return false; + } + + public boolean isExceptionHandler(ClassStruct clazz) { + if (definition == null) { + for (RestApiDefinition restApiDefinition : definitions.values()) { + if (isExceptionHandler(clazz, restApiDefinition)) { + definition = restApiDefinition; + return true; + } + } + return false; + } + else { + return isExceptionHandler(clazz, definition); + } + } + + private boolean isExceptionHandler(ClassStruct clazz, RestApiDefinition definition) { + ExceptionHandler handlerDef = definition.getExceptionHandler(); + if (handlerDef == null) { + return false; + } + boolean match = false; + for (String anInterface : clazz.getInterfaces()) { + if (handlerDef.getInterfaces().contains(anInterface)) { + match = true; + } + } + if (match) { + for (String annotation : clazz.getAnnotations().keySet()) { + if (handlerDef.getAnnotations().contains(annotation)) { + return true; + } + } + } + return false; + } + + public Map> prepareExceptionsMappings(Set exceptionHandlers, Map classesMap) { + Map> mappings = new HashMap<>(); + ExceptionHandler exceptionHandlerDef = definition.getExceptionHandler(); + if (exceptionHandlerDef == null) { + return mappings; + } + Set responses; + String mappingMethod = exceptionHandlerDef.getMethod(); + MethodBodyInterpreter interpreter = new MethodBodyInterpreter(definition, classesMap); + for (ClassStruct handler : exceptionHandlers) { + for (Method method : handler.getMethods()) { + if (mappingMethod.equals(method.getName()) && definition.getGenericResponseClasses().contains(method.getReturnType().getBasicType()) && method.getParameters().size() == 1) { + responses = interpreter.interpretBody(method.getBodyLog(), 0); + mappings.put(method.getParameters().iterator().next().getDataType().getBasicType(), responses); + } + } + } + return mappings; + } + + public Set getResponsesFromExceptions(String[] exceptions, Map> mappings) { + Set responses = new HashSet<>(); + if (exceptions == null) { + return responses; + } + for (String exception : exceptions) { + if (mappings.containsKey(exception)) { + responses.addAll(mappings.get(exception)); + } + } + return responses; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ExceptionHandler.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ExceptionHandler.java new file mode 100644 index 00000000..5c640745 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ExceptionHandler.java @@ -0,0 +1,37 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + +import java.util.Set; + +/** + * Created by ghessova on 07.05.2018. + */ +public class ExceptionHandler { + + private Set annotations; + private Set interfaces; + private String method; + + public Set getAnnotations() { + return annotations; + } + + public void setAnnotations(Set annotations) { + this.annotations = annotations; + } + + public Set getInterfaces() { + return interfaces; + } + + public void setInterfaces(Set interfaces) { + this.interfaces = interfaces; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/MemberProcessor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/MemberProcessor.java new file mode 100644 index 00000000..ab83fcf0 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/MemberProcessor.java @@ -0,0 +1,52 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Map; + +/** + * Created by ghessova on 09.04.2018. + */ +public class MemberProcessor { + + @JsonProperty + private String owner; + @JsonProperty + private String simpleName; + @JsonProperty + private Map mapping; + @JsonProperty + private String returnType; + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getSimpleName() { + return simpleName; + } + + public void setSimpleName(String simpleName) { + this.simpleName = simpleName; + } + + public Map getMapping() { + return mapping; + } + + public void setMapping(Map mapping) { + this.mapping = mapping; + } + + public String getReturnType() { + return returnType; + } + + public void setReturnType(String returnType) { + this.returnType = returnType; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/MethodBodyInterpreter.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/MethodBodyInterpreter.java new file mode 100644 index 00000000..82259851 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/MethodBodyInterpreter.java @@ -0,0 +1,332 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting.BytecodeDescriptorsProcessor; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.ClassStruct; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.DataType; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Method; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.MethodSignature; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Operation; +import cz.zcu.kiv.crce.restimpl.indexer.definition.RestApiDefinition; + +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.EndpointParameter; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.EndpointResponse; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.ParameterCategory; +import org.objectweb.asm.Opcodes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +import java.util.*; + +/** + * Created by ghessova on 08.04.2018. + */ +public class MethodBodyInterpreter { + + private RestApiDefinition definition; + + private Deque stack; + private Map localVariables; + private EndpointResponse response; + private Set responses; + private Map classesMap; + + private static final Logger logger = LoggerFactory.getLogger(MethodBodyInterpreter.class); + + + /** + * maximum depth of immersion for the processing of known methods returning common response entity + */ + private final int MAX_DEPTH = 3; + + /** + * Constructor + * @param definition REST API definition + * @param classesMap map of all classes in the archive + */ + MethodBodyInterpreter(RestApiDefinition definition, Map classesMap) { + this.definition = definition; + this.classesMap = classesMap; + } + + /** + * Searches method body instructions for HTTP responses. + * @param bodyLog operations list (instructions) + * @param depth depth of immersion + * @return set of responses + */ + public Set interpretBody(List bodyLog, int depth) { + reset(); + if (depth == MAX_DEPTH) { + return responses; + } + for (Operation operation : bodyLog) { + //System.out.println(operation); + interpretOperation(operation, depth); + } + return responses; + } + + private void interpretOperation(Operation operation, int depth) { + switch (operation.getType()) { + case INT_CONSTANT: + case STRING_CONSTANT: + stack.push(new StoredElement(null, operation.getValue())); + break; + case FIELD: + if (isStatusField(operation)) { + Integer status = getStatus(operation); + if (status != null) { + stack.push(new StoredElement(null, status)); + } + } + break; + case STORE: + try { + StoredElement element = stack.peek(); + if (element != null) { + localVariables.put(operation.getIndex(), stack.pop()); + } + } catch (Exception e) { + logger.error("No element in stack (or null)", e); + } + break; + case LOAD: + try { + StoredElement element = localVariables.get(operation.getIndex()); + if (element != null) { + Object object = element.getValue(); + if (object != null && object instanceof EndpointResponse) { + response = (EndpointResponse) object; + } + stack.push(element); + } + + } catch (Exception e) { + logger.error("No element in local variable storage", e); + } + break; + case CALL: // if method return type is not void, push result to stack + MethodSignature signature = BytecodeDescriptorsProcessor.processMethodDescriptor(operation.getDesc()); + List parametersFromStack = new ArrayList<>(); + for (int i = 0; i < signature.getParameterTypes().size(); i++) { + if (!stack.isEmpty()) { + parametersFromStack.add(stack.pop()); + + } + } + if (isCookieInit(operation)) { + EndpointParameter cookie = new EndpointParameter(); + StoredElement nameElement = parametersFromStack.get(1); + StoredElement valueElement = parametersFromStack.get(0); + if (nameElement != null) { + cookie.setCategory(ParameterCategory.COOKIE); + cookie.setName((String)nameElement.getValue()); + cookie.setDataType(valueElement.dataType); + } + stack.push(new StoredElement(null, cookie)); + break; + } + if (isResponseInit(operation)) { + response = new EndpointResponse(); + } + + if (isCookieSetting(operation)) { + StoredElement element = parametersFromStack.get(0); + if (element != null && element.value instanceof EndpointParameter) { + response.addParameter((EndpointParameter)element.value); + } + } + else if (isHeaderSetting(operation)) { + StoredElement valueElement = parametersFromStack.get(0); + StoredElement keyElement = parametersFromStack.get(1); + if (keyElement != null && valueElement != null) { + EndpointParameter parameter = new EndpointParameter(); + parameter.setCategory(ParameterCategory.HEADER); + parameter.setName("" + keyElement.getValue()); + parameter.setDataType(valueElement.dataType); + response.addParameter(parameter); + } + } + else if (!isStatusSettingMethod(operation) && !isEntitySettingMethod(operation)) { // other method, only return type is known + String returnType = getReturnType(operation); + if (returnsResponse(returnType)) { + ClassStruct owner = classesMap.get(operation.getOwner()); + if (owner != null) { + for (Method method : owner.getMethods()) { + if (method.getName().equals(operation.getName()) && method.getDesc().equals(operation.getDesc())) { + MethodBodyInterpreter newInterpreter = new MethodBodyInterpreter(definition, classesMap); + Set innerResponses = newInterpreter.interpretBody(method.getBodyLog(), ++depth); + if (!innerResponses.isEmpty()) { + response = innerResponses.iterator().next(); // we get only first response, nothing complicated + } + } + } + } + } + stack.push(new StoredElement(returnType, null)); + } + else { + if (isStatusSettingMethod(operation)) { + response.setStatus(determineStatus(operation, parametersFromStack)); + + } + if (isEntitySettingMethod(operation)) { + try { + StoredElement element = parametersFromStack.get(0); + String entityType = element.getDataType(); + response.setStructure(entityType); + } catch (Exception e) { + logger.error("No parameter in stack (or null)", e); + } + } + } + if (isResponseBuildMethod(operation)) { // may be also entity setting or status setting method + stack.push(new StoredElement(null, response)); + } + + break; + case RETURN: + responses.add(response); + response = new EndpointResponse(); + break; + } + //System.out.println(stack); + + } + + private boolean returnsResponse(String returnType) { + return definition.getGenericResponseClasses().contains(returnType); + } + + private boolean isCookieSetting(Operation operation) { + MemberProcessor processor = definition.getCookieSettingMethod(); + return operation.getOwner().equals(processor.getOwner()) && operation.getName().equals(processor.getSimpleName()); + } + + private boolean isHeaderSetting(Operation operation) { + MemberProcessor processor = definition.getHeaderSettingMethod(); + return operation.getOwner().equals(processor.getOwner()) && operation.getName().equals(processor.getSimpleName()); + } + + private boolean isCookieInit(Operation operation) { + return "".equals(operation.getName()) && definition.getCookieClass().equals(operation.getOwner()); + } + + private boolean isResponseInit(Operation operation) { + return isStatusSettingMethod(operation) && operation.getOpcode() == Opcodes.INVOKESTATIC; // todo + } + + private String getReturnType(Operation operation) { + if ("".equals(operation.getName())) { + return operation.getOwner(); + } + else { + return operation.getDataType(); + } + } + + + private Integer getStatus(Operation operation) { + Map mapping = definition.getStatusFields().getMapping(); + return (Integer)mapping.get(operation.getName()); + } + + private boolean isStatusField(Operation operation) { + return definition.getStatusFields().getOwner().equals(operation.getOwner()); + } + + private boolean isResponseBuildMethod(Operation operation) { + String returnType = BytecodeDescriptorsProcessor.processMethodDescriptor(operation.getDesc()).getReturnType().getBasicType(); + return definition.getGenericResponseClasses().contains(returnType); + } + + private boolean isStatusSettingMethod(Operation operation) { + String methodName = operation.getName(); + MemberProcessor processor = definition.getStatusSettingMethods(); + return operation.getOwner().equals(processor.getOwner()) && (methodName.equals(processor.getSimpleName()) || processor.getMapping().keySet().contains(methodName)); + } + + private boolean isEntitySettingMethod(Operation operation) { + String methodOwner = operation.getOwner(); + String methodName = operation.getName(); + String methodDesc = operation.getDesc(); + List parameters = BytecodeDescriptorsProcessor.processMethodDescriptor(methodDesc).getParameterTypes(); + Set processors = definition.getEntitySettingMethods(); + for (MemberProcessor processor : processors) { + if (methodOwner.equals(processor.getOwner()) && methodName.equals(processor.getSimpleName()) && !parameters.isEmpty()) { + return true; + } + } + return false; + } + + private int determineStatus(Operation operation, List parametersFromStack) { + String methodName = operation.getName(); + Map mapping = definition.getStatusSettingMethods().getMapping(); + Integer status = (Integer)mapping.get(methodName); + if (status != null) return status; + StoredElement element = parametersFromStack.get(0); + if (element != null) { + Object object = element.getValue(); + if (object instanceof String) { + return Integer.parseInt((String)object); + } + else if (object instanceof Integer) { + return (Integer)object; + } + } + + return -1; + } + + /** + * Resets interpreter's state. + */ + private void reset() { + stack = new ArrayDeque<>(); + response = new EndpointResponse(); + responses = new HashSet<>(); + localVariables = new HashMap<>(); + } + + /** + * Class for representing an element stored in stack or local variable storage. + */ + class StoredElement { + + private String dataType; + private Object value; // value is not required + + + StoredElement(String dataType, Object value) { + if (dataType == null) { + this.dataType = value.getClass().getName(); + } + else { + this.dataType = dataType; + } + this.value = value; + } + + public String getDataType() { + return dataType; + } + + public void setDataType(String dataType) { + this.dataType = dataType; + } + + public Object getValue() { + return value; + } + + @Override + public String toString() { + return "StoredElement{" + + "dataType='" + dataType + '\'' + + ", value=" + value + + '}'; + } + } +} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ParameterNameProcessor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ParameterNameProcessor.java new file mode 100644 index 00000000..a1f9b1b2 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ParameterNameProcessor.java @@ -0,0 +1,52 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + +import com.fasterxml.jackson.annotation.JsonProperty; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Annotation; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Variable; + +import java.util.Map; +import java.util.Set; + +/** + * Created by ghessova on 30.03.2018. + */ +public class ParameterNameProcessor { + + private Set annotationProcessors; + @JsonProperty("from_name") + private boolean fromName; + + public String process(Variable variable) { + // first look for annotations + Map annotationMap = variable.getAnnotations(); + for (AnnotationProcessor annotationProcessor : annotationProcessors) { + Annotation annotation = annotationMap.get(annotationProcessor.getAnnotationName()); + if (annotation != null) { + Set results = annotationProcessor.processAnnotation(annotation); + if (results != null && !results.isEmpty()) { + return results.iterator().next(); + } + } + } + // no relevant annotation found + if (fromName) return variable.getName(); + return null; + } + + public Set getAnnotationProcessors() { + return annotationProcessors; + } + + public void setAnnotationProcessors(Set annotationProcessors) { + this.annotationProcessors = annotationProcessors; + } + + public boolean isFromName() { + return fromName; + } + + public void setFromName(boolean fromName) { + this.fromName = fromName; + } +} + diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ParameterRequirementProcessor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ParameterRequirementProcessor.java new file mode 100644 index 00000000..075ba29f --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/ParameterRequirementProcessor.java @@ -0,0 +1,72 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + + + +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Annotation; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Field; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Variable; + +import java.util.Map; +import java.util.Set; + +/** + * Created by ghessova on 01.05.2018. + */ +public class ParameterRequirementProcessor { + + private Set annotationProcessors; + + private boolean parametersDefault; + private boolean fieldsDefault; + + /** + * Returns true if the variable is required. + * @param variable + * @return + */ + public boolean process(Variable variable) { + // first look for annotations + Map annotationMap = variable.getAnnotations(); + for (AnnotationProcessor annotationProcessor : annotationProcessors) { + Annotation annotation = annotationMap.get(annotationProcessor.getAnnotationName()); + if (annotation != null) { + Set results = annotationProcessor.processAnnotation(annotation); + if (results != null && !results.isEmpty()) { + String result = results.iterator().next(); + return Boolean.valueOf(result); + } + } + } + // no relevant annotation found + if (variable instanceof Field) { + return fieldsDefault; + } + else { + return parametersDefault; + } + } + + public Set getAnnotationProcessors() { + return annotationProcessors; + } + + public void setAnnotationProcessors(Set annotationProcessors) { + this.annotationProcessors = annotationProcessors; + } + + public boolean isParametersDefault() { + return parametersDefault; + } + + public void setParametersDefault(boolean parametersDefault) { + this.parametersDefault = parametersDefault; + } + + public boolean isFieldsDefault() { + return fieldsDefault; + } + + public void setFieldsDefault(boolean fieldsDefault) { + this.fieldsDefault = fieldsDefault; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/RestApiReconstructor.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/RestApiReconstructor.java new file mode 100644 index 00000000..4eaf9e80 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/RestApiReconstructor.java @@ -0,0 +1,27 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + + +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.Endpoint; + +import java.util.Collection; + + +/** + * Created by ghessova on 26.04.2018. + */ +public interface RestApiReconstructor { + + /** + * Extracts REST API endpoints from given source. + * @return set of endpoints representing the REST API + */ + Collection extractEndpoints(); + + /** + * Returns REST framework od specification identified in archive. + * @return REST framework od specification identified in archive + */ + String getFramework(); + + +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/RestApiReconstructorImpl.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/RestApiReconstructorImpl.java new file mode 100644 index 00000000..10a3deec --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/extracting/RestApiReconstructorImpl.java @@ -0,0 +1,466 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.extracting.BytecodeDescriptorsProcessor; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.ClassStruct; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.DataType; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Method; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.PathPartAttributes; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Variable; +import cz.zcu.kiv.crce.restimpl.indexer.definition.RestApiDefinition; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.Endpoint; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.EndpointRequestBody; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.EndpointResponse; +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures.RequestParameter; +import cz.zcu.kiv.crce.restimpl.indexer.util.WebXmlParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created by ghessova on 29.03.2018. + */ +public class RestApiReconstructorImpl implements RestApiReconstructor { + + private static final Logger logger = LoggerFactory.getLogger(RestApiReconstructorImpl.class); + + // current working directory is crce\modules\runner + private static final String DEFS_DIR = "../crce-restimpl-indexer/config/def/api"; + + private Map classesMap; + + private Set resources; + private Set filters; + private Map> exceptionsMappings; + private ClassModelProcessor classModelProcessor; + private MethodBodyInterpreter interpreter; + private WebXmlParser.Result webXmlResult; + + /** + * Constructor - assigns classesMap and loads REST API definitions from YAML config files defined by DEFS_DIR field. + * @param classesMap class model represented by map where keys are full qualified class names + */ + public RestApiReconstructorImpl(Map classesMap, WebXmlParser.Result webXmlResult ) { + this.classesMap = classesMap; + Map definitions = loadDefinitions(); + this.classModelProcessor = new ClassModelProcessorImpl(definitions); + this.webXmlResult = webXmlResult; + } + + + /** + * Method loads Java REST API framework definitions from YAML config files and converts them into RestApiDefinition structures. + * @return definitions map, where the key is framework name + */ + private Map loadDefinitions() { + Map definitions = new HashMap<>(); + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + File[] files = new File(DEFS_DIR).listFiles(); + assert files != null; + for (File file : files) { + try { + RestApiDefinition restApiDefinition = mapper.readValue(file, RestApiDefinition.class); + definitions.put(restApiDefinition.getFramework(), restApiDefinition); + } catch (IOException e) { + logger.error("Failed to read REST API definition from " + file.getAbsolutePath(), e); + } + } + return definitions; + + } + + /** + * Extracts REST API endpoints from class model injected in constructor. + * @return set of endpoints representing the REST API + */ + public Collection extractEndpoints() { + detectResources(classesMap.values()); + this.interpreter = new MethodBodyInterpreter(classModelProcessor.getDefinition(), classesMap); // the correct definition has been picked by now + Collection endpoints = new ArrayList<>(); + for (ClassStruct resource : resources) { + PathPartAttributes resourceAttributes = classModelProcessor.getPathAttributes(resource); + for (Method method : resource.getMethods()) { + if (classModelProcessor.isEndpoint(method)) { + processEndpoint(resourceAttributes, method, endpoints); + + } + } + } + addPrefixesToEndpoints(endpoints); + return endpoints; + } + + @Override + public String getFramework() { + RestApiDefinition definition = classModelProcessor.getDefinition(); + if (definition == null) { + return "undefined"; + } + else { + return definition.getFramework(); + } + } + + /** + * Detects REST API resource classes (controllers) among given classes. + * @param classes collection of classes + */ + private void detectResources(Collection classes) { + resources = new HashSet<>(); + Set exceptionHandlers = new HashSet<>(); + filters = new HashSet<>(); + for (ClassStruct clazz : classes) { + if (isRegisteredProvider(clazz)) { + if (classModelProcessor.isResource(clazz)) { + resources.add(clazz); + } + if (classModelProcessor.isRequestFilter(clazz)) { + filters.add(clazz); + } + if (classModelProcessor.isExceptionHandler(clazz)) { + exceptionHandlers.add(clazz); + } + } + + } + if (!resources.isEmpty()) { + exceptionsMappings = classModelProcessor.prepareExceptionsMappings(exceptionHandlers, classesMap); + } + } + + private boolean isRegisteredProvider(ClassStruct clazz) { + if (webXmlResult == null) { // providers are not set in web.xml + return true; + } + Set providers = webXmlResult.getProviders(); + if (providers == null) { + return true; // providers are not set in web.xml + } + if (providers.contains("*")) { + return true; + } + String className = clazz.getName(); + for (String provider : providers) { + if (className.startsWith(provider)) { + return true; + } + + } + return false; + + } + + + /** + * Converts a method from the class model representation into a REST API endpoint and adds it into set of endpoints. + * @param resourceAttributes attributes of a resource class the method belongs to + * @param method endpoint method + * @param endpoints set of detected endpoints + */ + private void processEndpoint(PathPartAttributes resourceAttributes, Method method, Collection endpoints) { + Endpoint endpoint = new Endpoint(); + + endpoint.setName(resourceAttributes.getName() + "." + method.getName()); + + // path information - method, path, produces, consumes + PathPartAttributes endpointAttributes = classModelProcessor.getPathAttributes(method); + + // methods are all added together + endpoint.setHttpMethods(getEndpointMethods(resourceAttributes.getMethods(), endpointAttributes.getMethods())); + // paths are appended + endpoint.setPaths(getEndpointPaths(resourceAttributes.getPaths(), endpointAttributes.getPaths())); + // MIME types are overwritten + endpoint.setConsumes(getMimeTypes(resourceAttributes.getConsumes(), endpointAttributes.getConsumes())); + endpoint.setProduces(getMimeTypes(resourceAttributes.getProduces(), endpointAttributes.getProduces())); + + // parameters, headers, cookies, request body + processMethodParameters(method, endpoint); + + // responses from return type + boolean saveEndpoint = processReturnType(method, endpoint, endpoints); + + // responses from exception handlers + Set responses = classModelProcessor.getResponsesFromExceptions(method.getExceptions(), exceptionsMappings); + if (endpoint.getResponses() == null) { + endpoint.setResponses(new HashSet()); + } + endpoint.getResponses().addAll(responses); + + if (saveEndpoint) { + setDefaultHttpMethods(endpoint, classModelProcessor.getDefinition()); + setDefaultMimeTypes(endpoint, classModelProcessor.getDefinition()); + endpoints.add(endpoint); + } + } + + private void setDefaultHttpMethods(Endpoint endpoint, RestApiDefinition definition) { + Set defaultMethods = definition.getDefaultHttpMethods(); + if (defaultMethods == null || defaultMethods.isEmpty() ) { + return; + } + if (endpoint.getHttpMethods().isEmpty()) { + endpoint.getHttpMethods().addAll(definition.getDefaultHttpMethods()); + } + } + + /** + * Processes an endpoint method return type and returns true if the endpoint can be added to endpoint list. + * Endpoint method return type can be either + * a) special class like Response + * b) resource class - subresource (jaxrs) + * c) primitive Java type + * d) other class - present or not present in this jar + * @param method endpoint method + * @param endpoint endpoint + * @param endpoints set of detected endpoints + * @return true if the endpoint can be added to endpoint list, false when the method redirects to a subresource (jaxrs) + * and should be further processed + */ + private boolean processReturnType(Method method, Endpoint endpoint, Collection endpoints) { + EndpointResponse response = new EndpointResponse(); + + DataType returnType = method.getReturnType(); + String returnTypeString = returnType.getBasicType(); + // is this a class defined in this archive ? + ClassStruct clazz = classesMap.get(returnTypeString); + + if (clazz != null && classModelProcessor.isSubresource(clazz)) { + PathPartAttributes resourceAttributes = classModelProcessor.getPathAttributes(clazz); + resourceAttributes.getConsumes().addAll(endpoint.getConsumes()); + resourceAttributes.getProduces().addAll(endpoint.getProduces()); + resourceAttributes.setPaths(getEndpointPaths(endpoint.getPaths(), resourceAttributes.getPaths())); + + for (Method method1 : clazz.getMethods()) { + if (classModelProcessor.isEndpoint(method1)) { + processEndpoint(resourceAttributes, method1, endpoints); + } + } + return false; + } + else if (classModelProcessor.isGenericResponseClass(returnTypeString)) { + //System.out.println(method.getName()); + // process body log + Set responses = interpreter.interpretBody(method.getBodyLog(), 0); + endpoint.setResponses(responses); + return true; + } + else { + + if (returnType.isStructured()) { + if (BytecodeDescriptorsProcessor.isArrayOrCollection(returnTypeString)) { + response.setArray(true); + response.setStructure(returnType.getInnerType().getBasicType()); + } + else { // something else, generic + response.setArray(false); + response.setStructure(returnTypeString); + } + } + else { // primitive Java type or other class + response.setStructure(returnTypeString); + + } + } + Set responses = new HashSet<>(); + responses.add(response); + endpoint.setResponses(responses); + + return true; + } + + /** + * Creates endpoint URL by appending a method path to a class resource path. + * @param resourcePath class resource path + * @param methodPath method path + * @return endpoint path + */ + private String getEndpointPath(String resourcePath, String methodPath) { + String url = resourcePath + "/" + (methodPath == null ? "" : methodPath); + url = url.replaceAll("/+", "/"); + if (url.charAt(url.length() - 1) == '/') url = url.substring(0, url.length() - 1); + return url; + } + + /** + * Adds all resource HTTP methods to method HTTP methods (for Spring, JAX-RS does not allow HTTP methods on resources) + * @param resourceMethods class resource HTTP methods + * @param methodMethods endpoint method HTTP methods + * @return list of all methods allowed + */ + private Set getEndpointMethods(List resourceMethods, List methodMethods) { + // remove duplicates + Set endpointMethods = new HashSet<>(methodMethods); + endpointMethods.addAll(resourceMethods); + return endpointMethods; + } + + /** + * Gets all endpoint paths by creating cartesian product of all method paths to a class resource paths. + * @param resourcePaths class resource paths + * @param methodPaths method path + * @return list of endpoint paths + */ + private List getEndpointPaths(List resourcePaths, List methodPaths) { + List urls = new ArrayList<>(); + for (String resourcePath : resourcePaths) { + for (String methodPath : methodPaths) { + urls.add(getEndpointPath(resourcePath, methodPath)); + } + } + return urls; + } + + /** + * Gets all endpoint MIME types (produces/consumes) by replacing the resource ones by the method ones, + * if there are any. + * @param resourceTypes class resource produces/consumes + * @param methodTypes method produces/consumes + * @return list of endpoint produces/consumes + */ + private Set getMimeTypes(List resourceTypes, List methodTypes) { + Set mimeTypes = new HashSet<>(); + if (methodTypes.isEmpty()) { + mimeTypes.addAll(resourceTypes); + } + else { + mimeTypes.addAll(methodTypes); + } + return mimeTypes; + } + + /** + * Processes method parameters and converts them into endpoint request parameters, endpoint request body and others information. + * Method parameter can be either: + * a) endpoint request parameter - query parameter, path parameter, form parameter, matrix parameter, header, cookie + * b) parameter bean + * c) endpoint request body + * d) additional information + * @param method endpoint method + * @param endpoint endpoint + */ + private void processMethodParameters(Method method, Endpoint endpoint) { + Set parameters = new HashSet<>(); + + for (Variable variable : method.getParameters()) { + if (classModelProcessor.isRequestParameter(variable)) { + RequestParameter parameter = classModelProcessor.convertParameter(variable, endpoint.getConsumes()); + parameters.add(parameter); + } + else if (classModelProcessor.isRequestBody(variable)) { + EndpointRequestBody body = new EndpointRequestBody(); + DataType bodyDataType = variable.getDataType(); + if (bodyDataType.isStructured()) { + if (BytecodeDescriptorsProcessor.isArrayOrCollection(bodyDataType.getBasicType())) { + body.setArray(true); + body.setStructure(bodyDataType.getInnerType().getBasicType()); + } + else { // something else, generic + body.setArray(false); + body.setStructure(bodyDataType.getBasicType()); + } + } + else { // primitive Java type or other class + body.setStructure(bodyDataType.getBasicType()); + + } + body.setOptional(!variable.getAnnotations().containsKey(classModelProcessor.getDefinition().getNotNullAnnotation())); + if (endpoint.getBody() == null) { + endpoint.setBody(body); + } + } + else if (canBeParameterBean(variable)) { + Set pathVariables = getPathVariablesFromUrl(endpoint.getPaths()); + Set beanParameters = classModelProcessor.getParamsFromBean(endpoint, variable, pathVariables, classesMap); + parameters.addAll(beanParameters); + } + + + /* else { + // log.. info or warning + }*/ + } + endpoint.setParameters(parameters); + } + + + + + + private void setDefaultMimeTypes(Endpoint endpoint, RestApiDefinition definition) { + EndpointRequestBody requestBody = endpoint.getBody(); + if (endpoint.getConsumes().isEmpty() && requestBody != null) { + setDefaultMimeTypes(requestBody.getStructure(), requestBody.isArray(), endpoint.getConsumes(), definition); + } + if (endpoint.getProduces().isEmpty()) { + Set responses = endpoint.getResponses(); + for (EndpointResponse response : responses) { + setDefaultMimeTypes(response.getStructure(), response.isArray(), endpoint.getProduces(), definition); + } + } + } + + private void setDefaultMimeTypes(String dataType, boolean isArray, Set mimeTypes, RestApiDefinition definition) { + if (dataType == null || "".equals(dataType)) { + return; + } + if (isArray || BytecodeDescriptorsProcessor.isPrimitiveOrString(dataType)) { + mimeTypes.add(definition.getDefaultObjectMime()); + + } + else { + mimeTypes.add(definition.getDefaultPrimitiveMime()); + + } + } + + /** + * Determines whether a method parameter is a parameter bean. + * @param parameter method parameter + * @return true if parameter is a parameter bean + */ + private boolean canBeParameterBean(Variable parameter) { + String dataType = parameter.getDataType().getBasicType(); + ClassStruct clazz = classesMap.get(dataType); + return classModelProcessor.canBeParameterBean(clazz, parameter); + } + + private Set getPathVariablesFromUrl(String url) { + Set variables = new HashSet<>(); + Pattern pattern = Pattern.compile("\\{.*}"); + Matcher matcher = pattern.matcher(url); + while (matcher.find()) { + variables.add(url.substring(matcher.start() + 1, matcher.end() - 1)); + } + return variables; + } + + private Set getPathVariablesFromUrl(Collection urls) { + Set variables = new HashSet<>(); + for (String url : urls) { + variables.addAll(getPathVariablesFromUrl(url)); + } + return variables; + } + + private void addPrefixesToEndpoints(Collection endpoints) { + if (webXmlResult == null) { + return; + } + if (webXmlResult.getUrlPrefixes() == null) { + return; + } + for (Endpoint endpoint : endpoints) { + List paths = getEndpointPaths(webXmlResult.getUrlPrefixes(), endpoint.getPaths()); + endpoint.setPaths(paths); + + } + } + + +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/Endpoint.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/Endpoint.java new file mode 100644 index 00000000..9fa75c08 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/Endpoint.java @@ -0,0 +1,105 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures; + +import java.io.Serializable; +import java.util.List; +import java.util.Set; + +/** + * Created by ghessova on 10.03.2018. + * + - name - id + - url + - method (HTTP method) + - produces - MIME type - XML, JSON, YAML, plain text, all ... + - consumes - MIME type - XML, JSON, YAML, plain text, all ... + */ +public class Endpoint implements Serializable { + + private String name; + private List paths; + private Set httpMethods; // Spring allows endpoint to have more methods specified + private Set consumes; + private Set produces; + + /* -------------------------------------*/ + private EndpointRequestBody body; + private Set responses; + private Set parameters; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getPaths() { + return paths; + } + + public void setPaths(List paths) { + this.paths = paths; + } + + public Set getHttpMethods() { + return httpMethods; + } + + public void setHttpMethods(Set httpMethods) { + this.httpMethods = httpMethods; + } + + public Set getConsumes() { + return consumes; + } + + public void setConsumes(Set consumes) { + this.consumes = consumes; + } + + public Set getProduces() { + return produces; + } + + public void setProduces(Set produces) { + this.produces = produces; + } + + public Set getResponses() { + return responses; + } + + public void setResponses(Set responses) { + this.responses = responses; + } + + public Set getParameters() { + return parameters; + } + + public void setParameters(Set parameters) { + this.parameters = parameters; + } + + public EndpointRequestBody getBody() { + return body; + } + + public void setBody(EndpointRequestBody body) { + this.body = body; + } + + @Override + public String toString() { + return "Endpoint{" + + "name='" + name + '\'' + + ", paths=" + paths + + ", httpMethods='" + httpMethods + '\'' + + ", consumes=" + consumes + + ", produces=" + produces + + ", responses=" + responses + + ", parameters=" + parameters + + '}'; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointParameter.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointParameter.java new file mode 100644 index 00000000..bd458fde --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointParameter.java @@ -0,0 +1,55 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures; + +/** + * Created by ghessova on 10.03.2018. + */ +public class EndpointParameter { + + private String name; + private String dataType; // T + private boolean isArray; + + private ParameterCategory category; + + public ParameterCategory getCategory() { + return category; + } + + public void setCategory(ParameterCategory category) { + this.category = category; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDataType() { + return dataType; + } + + public void setDataType(String dataType) { + this.dataType = dataType; + } + + public boolean isArray() { + return isArray; + } + + public void setArray(boolean array) { + isArray = array; + } + + @Override + public String toString() { + return "EndpointParameter{" + + "name='" + getName() + '\'' + + ", category='" + getCategory() + '\'' + + ", dataType='" + getDataType() + '\'' + + ", isArray=" + isArray() + + '}'; + } +} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointRequestBody.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointRequestBody.java new file mode 100644 index 00000000..5e72ee52 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointRequestBody.java @@ -0,0 +1,37 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures; + +import java.io.Serializable; + +/** + * Created by ghessova on 10.03.2018. + */ +public class EndpointRequestBody implements Serializable { + + private String structure; + private boolean isOptional = true; + private boolean isArray; + + public String getStructure() { + return structure; + } + + public void setStructure(String structure) { + this.structure = structure; + } + + public boolean isOptional() { + return isOptional; + } + + public void setOptional(boolean optional) { + isOptional = optional; + } + + public boolean isArray() { + return isArray; + } + + public void setArray(boolean array) { + isArray = array; + } +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointResponse.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointResponse.java new file mode 100644 index 00000000..0a111cf1 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/EndpointResponse.java @@ -0,0 +1,66 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by ghessova on 10.03.2018. + * + - name - responseid - stejný význam jako name u webservice.endpoint + - status + - type - MIME type + - structure - grammar - XSD, JSON-schema... + - isOptional + - isArray + */ +public class EndpointResponse implements Serializable { + + private int status; // http status + private String structure; + private boolean isArray; + private List parameters = new ArrayList<>(); + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + + public String getStructure() { + return structure; + } + + public void setStructure(String structure) { + this.structure = structure; + } + + public boolean isArray() { + return isArray; + } + + public void setArray(boolean array) { + isArray = array; + } + + public void addParameter(EndpointParameter parameter) { + parameters.add(parameter); + } + + public List getParameters() { + return parameters; + } + + @Override + public String toString() { + return "EndpointResponse{" + + " status=" + status + + ", structure='" + structure + '\'' + + ", isArray=" + isArray + + ", parameters=" + parameters + + '}'; + } +} \ No newline at end of file diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/ParameterCategory.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/ParameterCategory.java new file mode 100644 index 00000000..53293205 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/ParameterCategory.java @@ -0,0 +1,14 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures; + +/** + * Created by ghessova on 12.03.2018. + */ +public enum ParameterCategory { + + QUERY, // www.example.com/context/resource?queryParam=paramValue + MATRIX, // www.example.com/context/resource;matrixParam=paramValue + PATH, // www.example.com/context/resource/pathParamValue + FORM, // in request body: formParamName=formParamValue + HEADER, // request/response header + COOKIE; // request/response cookie (represented by Cookie and Set-Cookie headers) +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/RequestParameter.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/RequestParameter.java new file mode 100644 index 00000000..ba8c998d --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/restmodel/structures/RequestParameter.java @@ -0,0 +1,39 @@ +package cz.zcu.kiv.crce.restimpl.indexer.restmodel.structures; + +/** + * Created by ghessova on 10.05.2018. + */ +public class RequestParameter extends EndpointParameter { + + private boolean isOptional = true; + private String defaultValue; + + public boolean isOptional() { + return isOptional; + } + + public void setOptional(boolean optional) { + isOptional = optional; + } + + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + @Override + public String toString() { + return "RequestParameter{" + + "name='" + getName() + '\'' + + ", category='" + getCategory() + '\'' + + ", dataType='" + getDataType() + '\'' + + ", isOptional=" + isOptional() + + ", isArray=" + isArray() + + ", defaultValue=" + getDefaultValue() + + '}'; + } +} + diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/util/Util.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/util/Util.java new file mode 100644 index 00000000..21959477 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/util/Util.java @@ -0,0 +1,52 @@ +package cz.zcu.kiv.crce.restimpl.indexer.util; + +import cz.zcu.kiv.crce.restimpl.indexer.restmodel.extracting.AnnotationProcessor; +import cz.zcu.kiv.crce.restimpl.indexer.classmodel.structures.Annotation; + +import java.util.*; + +/** + * Created by ghessova on 10.03.2018. + */ +public class Util { + + /** + * Multiple results can be found. + * @param processors + * @param annotations + * @return + */ + public static List getResultsFromAnnotations(Set processors, Map annotations) { + List results = new ArrayList<>(); + for (AnnotationProcessor processor : processors) { + String annotationName = processor.getAnnotationName(); + Annotation annotation = annotations.get(annotationName); + if (annotation != null) { + results.addAll(processor.processAnnotation(annotation)); + } + } + return results; + } + + /** + * Only one value expected. + * First value returned, others are discarded. + * @param processors + * @param annotations + * @return + */ + public static String getResultFromAnnotations(Set processors, Map annotations) { + for (AnnotationProcessor processor : processors) { + String annotationName = processor.getAnnotationName(); + Annotation annotation = annotations.get(annotationName); + if (annotation != null) { + Set results = processor.processAnnotation(annotation); + if (results != null && !results.isEmpty()) { + return results.iterator().next(); + } + } + } + return null; + } + +} diff --git a/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/util/WebXmlParser.java b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/util/WebXmlParser.java new file mode 100644 index 00000000..3f5ebe29 --- /dev/null +++ b/modules/crce-restimpl-indexer/src/main/java/cz.zcu.kiv.crce.restimpl.indexer/util/WebXmlParser.java @@ -0,0 +1,229 @@ +package cz.zcu.kiv.crce.restimpl.indexer.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import cz.zcu.kiv.crce.restimpl.indexer.definition.DispatcherDefinition; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; + +/** + * Created by ghessova on 08.05.2018. + */ +public class WebXmlParser { + + private final String DEF_FILE = "../crce-restimpl-indexer/config/def/dispatcher.yml"; + + private DispatcherDefinition definition; + + public WebXmlParser() throws IOException { + definition = loadDefinition(); + } + + private DispatcherDefinition loadDefinition() throws IOException{ + DispatcherDefinition definition = null; + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + File file = new File(DEF_FILE); + + definition = mapper.readValue(file, DispatcherDefinition.class); + + return definition; + + } + + public Result parseWebXml(InputStream is) { + if (is == null) { + return null; + } + // check whether IDL is a valid XML + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + Document document = null; + try { + builder = factory.newDocumentBuilder(); + document = builder.parse(is); + } catch (ParserConfigurationException | SAXException | IOException ex) { + //logger.debug("IDL is not a valid XML object", ex); + ex.printStackTrace(); // todo log + } + if (document == null) { + return null; + } + + Element root = document.getDocumentElement(); + + // go through servlets + List servlets = getServlets(root); + Map> mappings = getServletMappings(root); + + for (Servlet servlet : servlets) { + Map.Entry entry = findMatch(servlet); + if (entry != null) { + Result result = new Result(); + result.setUrlPrefixes(getUrlPrefixes(mappings.get(servlet.getName()))); + String providersParamName = entry.getValue().getProviders(); + result.setProviders(getProviders(servlet.initParams.get(providersParamName))); + return result; + } + } + return null; + } + + private Set getProviders(String providerString) { + if (providerString == null) { + return null; + } + String[] providers = providerString.split(","); + Set set = new HashSet<>(); + for (String provider : providers) { + set.add(provider.trim().replaceAll("\\.", "/")); + } + return set; + } + + private List getUrlPrefixes(List urlMappings) { + List prefixes = new ArrayList<>(); + for (String urlMapping : urlMappings) { + if (urlMapping.endsWith("*")) { + prefixes.add(urlMapping.replaceAll("\\*", "")); + } + } + return prefixes; + } + + private Map.Entry findMatch(Servlet servlet) { + for (Map.Entry entry : definition.getDispatchers().entrySet()) { + DispatcherDefinition.Dispatcher d = entry.getValue(); + if (d.getDispatcher().equals(servlet.getClassName())) { + return entry; + } + } + return null; + + } + + private List getServlets(Element root) { + NodeList servletNodes = root.getElementsByTagName("servlet"); + Servlet servlet; + List servlets = new ArrayList<>(); + for (int i = 0; i < servletNodes.getLength(); i++) { + Node resourceSet = servletNodes.item(i); + NodeList childNodes = resourceSet.getChildNodes(); + servlet = new Servlet(); + for (int j = 0; j < childNodes.getLength(); j++) { + Node node = childNodes.item(j); + if ("servlet-name".equals(node.getNodeName())) { + servlet.setName(getTextContent(node)); + } + else if ("servlet-class".equals(node.getNodeName())) { + servlet.setClassName(getTextContent(node)); + } + else if ("init-param".equals(node.getNodeName())) { + NodeList initParamChildren = node.getChildNodes(); + String paramName = null; + String paramValue = null; + for (int k = 0; k < initParamChildren.getLength(); k++) { + Node paramNode = initParamChildren.item(k); + if ("param-name".equals(paramNode.getNodeName())) { + paramName = getTextContent(paramNode); + } + else if ("param-value".equals(paramNode.getNodeName())) { + paramValue = getTextContent(paramNode); + } + } + servlet.initParams.put(paramName, paramValue); + } + } + servlets.add(servlet); + } + return servlets; + } + + private String getTextContent(Node node) { + return node.getFirstChild().getTextContent().trim(); + } + + private Map> getServletMappings(Element root) { + NodeList servletNodes = root.getElementsByTagName("servlet-mapping"); + Map> mapping = new HashMap<>(); + for (int i = 0; i < servletNodes.getLength(); i++) { + Node resourceSet = servletNodes.item(i); + NodeList childNodes = resourceSet.getChildNodes(); + String name = null; + String url = null; + for (int j = 0; j < childNodes.getLength(); j++) { + Node node = childNodes.item(j); + if ("servlet-name".equals(node.getNodeName())) { + name = getTextContent(node); + } + else if ("url-pattern".equals(node.getNodeName())) { + url = getTextContent(node); + } + + } + if (mapping.containsKey(name)) { + mapping.get(name).add(url); + } + else { + List urls = new ArrayList<>(); + urls.add(url); + mapping.put(name, urls); + } + } + return mapping; + } + + class Servlet { + private String name; + private String className; + private Map initParams = new HashMap<>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + } + + public static class Result { + private Set providers; + private List urlPrefixes; + + public Set getProviders() { + return providers; + } + + public void setProviders(Set providers) { + this.providers = providers; + } + + public List getUrlPrefixes() { + return urlPrefixes; + } + + public void setUrlPrefixes(List urlPrefixes) { + this.urlPrefixes = urlPrefixes; + } + } +} diff --git a/modules/crce-webui/osgi.bnd b/modules/crce-webui/osgi.bnd new file mode 100644 index 00000000..278c9bfc --- /dev/null +++ b/modules/crce-webui/osgi.bnd @@ -0,0 +1,40 @@ +#----------------------------------------------------------------- +# Use this file to add customized Bnd instructions for the bundle +#----------------------------------------------------------------- + +Bundle-Version>: \ + ${pom.version} + +Bundle-SymbolicName: \ + ${bundle.symbolicName} + +Bundle-Name: CRCE - Web UI + +Bundle-Activator: ${bundle.namespace}.internal.Activator + +Export-Package: + +Import-Package: \ + javax.servlet, \ + javax.servlet.http, \ + javax.servlet.*, \ + javax.servlet.jsp.*, \ + javax.servlet.jsp.jstl.*, \ + javax.xml.parsers, \ + javax.xml.namespace, \ + javax.xml.xpath, \ + org.osgi.framework, \ + org.osgi.service.log, \ + org.osgi.service.useradmin, \ + org.xml.sax, \ + org.w3c.dom, \ + cz.zcu.kiv.crce.metadata, \ + * + +Dynamic-ImportPackage: * + +Bundle-ClassPath: .,WEB-INF/classes + +Web-ContextPath: crce + +Webapp-Context: crce diff --git a/modules/crce-webui/pom.xml b/modules/crce-webui/pom.xml new file mode 100644 index 00000000..12df6c30 --- /dev/null +++ b/modules/crce-webui/pom.xml @@ -0,0 +1,182 @@ + + + + 4.0.0 + + + ../pom + cz.zcu.kiv.crce + crce-modules-parent + 2.1.1-SNAPSHOT + + + crce-webui + war + + CRCE - Web UI + + + ${namespace}.webui + ${namespace}.webui + + + + + + + + com.lukegb.mojo + gitdescribe-maven-plugin + 3.0 + + + + gitdescribe + + git-describe + initialize + + + --tags + + + + + + + maven-war-plugin + + + %regex[WEB-INF/lib/(?!jstl-|standard-).*.jar] + + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + + ${project.parent.version} + ${describe} + + + + + + org.apache.felix + maven-bundle-plugin + true + + + + bundle-manifest + process-classes + + manifest + + + + + + + + + + jar + bundle + war + + + + + + + + + + + + + + + + + javax.servlet + servlet-api + + + javax.servlet + jsp-api + + + commons-fileupload + commons-fileupload + + + commons-io + commons-io + + + taglibs + c + 1.1.2 + tld + runtime + + + taglibs + standard + 1.1.2 + + + javax.servlet + jstl + 1.2 + + + + + + ${project.groupId} + crce-core + pom + + + + ${project.groupId} + crce-metadata-osgi-bundle + ${project.version} + + + ${project.groupId} + crce-compatibility-api + ${project.version} + + + + + + junit + junit + + + org.openengsb.wrapped + net.sourceforge.htmlunit-all + 2.8.w1 + bundle + test + + + + + javax.ws.rs + javax.ws.rs-api + + + org.glassfish.jersey.containers + jersey-container-servlet-core + + + org.glassfish.jersey.media + jersey-media-multipart + + + + + diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Activator.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Activator.java new file mode 100644 index 00000000..87d7511e --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Activator.java @@ -0,0 +1,177 @@ +package cz.zcu.kiv.crce.webui.internal; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Nonnull; +import javax.servlet.http.HttpServletRequest; + +import org.apache.felix.dm.DependencyActivatorBase; +import org.apache.felix.dm.DependencyManager; +import org.osgi.framework.BundleContext; +import org.osgi.service.blueprint.container.ServiceUnavailableException; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cz.zcu.kiv.crce.compatibility.service.CompatibilitySearchService; +import cz.zcu.kiv.crce.metadata.MetadataFactory; +import cz.zcu.kiv.crce.metadata.dao.MetadataDao; +import cz.zcu.kiv.crce.metadata.service.MetadataService; +import cz.zcu.kiv.crce.plugin.PluginManager; +import cz.zcu.kiv.crce.repository.Buffer; +import cz.zcu.kiv.crce.repository.SessionRegister; +import cz.zcu.kiv.crce.repository.Store; + +/** + * Activator of this bundle + * + * @author Jiri Kucera (jiri.kucera@kalwi.eu) + */ +@SuppressWarnings("FinalClass") +public final class Activator extends DependencyActivatorBase { + + private static final Logger logger = LoggerFactory.getLogger(Activator.class); + + private static volatile Activator instance; + + // injected by dependency manager: + private volatile BundleContext bundleContext; + private volatile MetadataFactory metadataFactory; + private volatile MetadataDao metadataDao; + private volatile PluginManager pluginManager; + private volatile SessionRegister sessionRegister; + private volatile MetadataService metadataService; + private volatile CompatibilitySearchService compatibilityService; + + public static Activator instance() { + if (instance == null) { + throw new IllegalStateException("Activator instance is null."); + } + return instance; + } + + public PluginManager getPluginManager() { + return pluginManager; + } + + public SessionRegister getSessionRegister() { + if (sessionRegister == null) { + throw new IllegalStateException("sessionRegister is null."); + } + return sessionRegister; + } + + public MetadataDao getMetadataDao() { + return metadataDao; + } + + public MetadataFactory getMetadataFactory() { + return metadataFactory; + } + + /** + * + * @return Map of repository ID to repository name. + */ + @Nonnull + public Map getRepositories() { + Map stores = new HashMap<>(); + + Collection> serviceReferences; + try { + serviceReferences = bundleContext.getServiceReferences(Store.class, null); + } catch (InvalidSyntaxException e) { + logger.error("Invalid filter.", e); // this should not happen + return stores; + } + + if (serviceReferences == null) { + logger.trace("No stores found."); + return stores; + } + + for (ServiceReference serviceReference : serviceReferences) { + String id = (String) serviceReference.getProperty("id"); + String name = (String) serviceReference.getProperty("name"); + if (id != null) { + stores.put(id, name != null ? name : id); + } + } + + return stores; + } + + public Store getStore(String repositoryId) { + String filter = "(id=" + repositoryId + ")"; + + Collection> serviceReferences; + try { + serviceReferences = bundleContext.getServiceReferences(Store.class, filter); + } catch (InvalidSyntaxException ex) { + logger.error("Invalid filter: " + filter); + return null; + } + + if (serviceReferences == null || serviceReferences.isEmpty()) { + logger.warn("Store not found for repository ID: {}", repositoryId); + return null; + } + + if (serviceReferences.size() > 1) { + logger.warn("More than one stores found for repository ID: {}, using the first one.", repositoryId); + } + + return bundleContext.getService(serviceReferences.iterator().next()); + } + + public CompatibilitySearchService getCompatibilityService() { + if(compatibilityService != null) { + return compatibilityService; + } else { + throw new ServiceUnavailableException("This installation does not support compatibility services!", ""); + } + } + + public boolean isCompatibilityServicePresent() { + return compatibilityService != null; + } + + public Buffer getBuffer(HttpServletRequest req) { + if (req == null) { + return null; + } + + String sid = req.getSession(true).getId(); + return sessionRegister.getSessionData(sid).getBuffer(); + } + + public MetadataService getMetadataService() { + return metadataService; + } + + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "Workaround for providing DM components.") + @Override + public void init(BundleContext context, DependencyManager manager) throws Exception { + instance = this; + + manager.add(createComponent() + .setImplementation(this) + .add(createServiceDependency().setService(SessionRegister.class).setRequired(true)) + .add(createServiceDependency().setService(PluginManager.class).setRequired(true)) + .add(createServiceDependency().setService(MetadataFactory.class).setRequired(true)) + .add(createServiceDependency().setService(MetadataService.class).setRequired(true)) + .add(createServiceDependency().setService(CompatibilitySearchService.class).setRequired(false)) // FIXME 'not required' is only a temporary solution to make the component startable + ); + + + logger.debug("WebUI activator initialized."); + } + + @Override + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + // nothing to do + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java new file mode 100644 index 00000000..f075e75f --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java @@ -0,0 +1,80 @@ +package cz.zcu.kiv.crce.webui.internal; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +//import cz.zcu.kiv.crce.metadata.Resolver; +import cz.zcu.kiv.crce.metadata.Resource; +//import cz.zcu.kiv.crce.metadata.ResourceCreator; + +public class CheckServlet extends HttpServlet { + + private static final Logger logger = LoggerFactory.getLogger(CheckServlet.class); + + private static final long serialVersionUID = -6116518932972052481L; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + List res = chooseFrom(req); + if (res == null) { + req.getRequestDispatcher("resource").forward(req, resp); + } else { + String source = (String) req.getSession().getAttribute("source"); + req.getSession().setAttribute(source, res); + req.getSession().removeAttribute("source"); + req.getRequestDispatcher("jsp/" + source + ".jsp").forward(req, resp); + } + + } + + private List chooseFrom(HttpServletRequest req) { + String source = (String) req.getSession().getAttribute("source"); + if (source == null) { + return null; + } else if (source.equals("buffer")) { + return doCheck(Activator.instance().getBuffer(req).getResources()); + } else if (source.equals("store")) { + return doCheck(Activator.instance().getStore(null).getResources()); + } else { + return null; + } + } + + private List doCheck(List resources) { + logger.warn("Resolver is not designed yet in new Metadata API, returning empty list of resources. Checked resource: {}", resources); +// Resource[] resources = repository.getResources(); +// Resource[] cloned = new Resource[resources.length]; +// System.arraycopy(resources, 0, cloned, 0, resources.length); +// ArrayList ext = new ArrayList<>(); +// HashMap extMap = new HashMap<>(); +// ResourceCreator rc = Activator.instance().getCreator(); +// Resolver resolver = rc.createResolver(repository); +// for (Resource r : cloned) { +// resolver.add(r); +// r.getUri(); +// extMap.put(r.getUri(), new ResourceExt(r)); +// ext.add(new ResourceExt(r)); +// } +// if (!resolver.resolve()) { +// for (Reason r : resolver.getUnsatisfiedRequirements()) { +// if (extMap.containsKey(r.getResource().getUri())) { +// extMap.get(r.getResource().getUri()).addRequirement(r.getRequirement()); +// } +// +// } +// return extMap.values().toArray(new Resource[extMap.values().size()]); +// } else { +// return resources; +// } + return Collections.emptyList(); + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java new file mode 100644 index 00000000..983e1328 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java @@ -0,0 +1,132 @@ +package cz.zcu.kiv.crce.webui.internal; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.webui.internal.custom.ResourceExt; + +public class DownloadServlet extends HttpServlet { + + private static final long serialVersionUID = 6399102910617353070L; + + private static final Logger logger = LoggerFactory.getLogger(DownloadServlet.class); + + private static final int BUFSIZE = 128; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + boolean success; + String message; + @SuppressWarnings("unchecked") + List buffer = (List) req.getSession().getAttribute("buffer"); + List list = Activator.instance().getBuffer(req).commit(true); + if (list.size() == buffer.size()) { + success = true; + message = "All resources commited successfully"; + } else { + success = false; + message = "Not all resources commited successfully"; + } + req.getSession().setAttribute("source", "commit"); + ResourceServlet.setError(req.getSession(), success, message); + req.getRequestDispatcher("resource?link=store").forward(req, resp); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + boolean failed = false; + String message; + if (req.getParameter("uri") != null) { + String link = (String) req.getSession().getAttribute("source"); + String uri = req.getParameter("uri"); + try { + URI fileUri = new URI(uri); + if (link != null) { + switch (link) { + case "store": { + List resources = Activator.instance().getStore(null).getResources(); + Resource found = EditServlet.findResource(fileUri, resources); + doDownload(req, resp, found); + break; + } + case "buffer": { + List resources = Activator.instance().getBuffer(req).getResources(); + Resource found = EditServlet.findResource(fileUri, resources); + logger.debug("Found!" + Activator.instance().getMetadataService().getPresentationName(found)); + doDownload(req, resp, found); + break; + } + default: + failed = true; + break; + } + } else { + failed = true; + } + + } catch (IOException e) { + failed = true; + logger.error("Failed to download resource: {}", uri, e); + } catch (URISyntaxException e) { + failed = true; + logger.error("Failed to download resource, invalid URI: {}", uri, e); + } + } else { + failed = true; + } + + if (failed) { + message = "Download failed"; + } else { + message = "Download successful"; + } + ResourceServlet.setError(req.getSession(), !failed, message); + + } + + private void doDownload(HttpServletRequest req, HttpServletResponse resp, Resource found) throws IOException { // NOPMD req would be used in the future + + File f = new File(Activator.instance().getMetadataService().getUri(found)); + int length = 0; + try (ServletOutputStream op = resp.getOutputStream()) { + ServletContext context = getServletConfig().getServletContext(); + String mimetype = context.getMimeType(Activator.instance().getMetadataService().getUri(found).toString()); + + // + // Set the response and go! + // + // + resp.setContentType((mimetype != null) ? mimetype : "application/octet-stream"); + resp.setContentLength((int) f.length()); + resp.setHeader("Content-Disposition", "attachment; filename=\"" + Activator.instance().getMetadataService().getFileName(found) + "\""); + + // + // Stream to the requester. + // + byte[] bbuf = new byte[BUFSIZE]; + try (DataInputStream in = new DataInputStream(new FileInputStream(f))) { + while (in != null && (length = in.read(bbuf)) != -1) { + op.write(bbuf, 0, length); + } + op.flush(); + } + } + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java new file mode 100644 index 00000000..3121fba0 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java @@ -0,0 +1,1023 @@ +package cz.zcu.kiv.crce.webui.internal; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cz.zcu.kiv.crce.metadata.Attribute; +import cz.zcu.kiv.crce.metadata.Capability; +import cz.zcu.kiv.crce.metadata.Requirement; +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.metadata.impl.GenericAttributeType; +import cz.zcu.kiv.crce.webui.internal.legacy.Type; + +public class EditServlet extends HttpServlet { + + private static final long serialVersionUID = -4949620462179710290L; + + private static final Logger logger = LoggerFactory.getLogger(EditServlet.class); + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + boolean success = false; + Map parameters = req.getParameterMap(); + String form = null; + + if (parameters.containsKey("form")) { + form = ((String[]) parameters.get("form"))[0]; + } + if (form != null) { + switch (form) { + case "addCategory": + if (addCategory(req, resp, parameters)) { + success = editCategories(req, resp); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add category."); + success = true; + } + } else { + ResourceServlet.setError(req.getSession(), false, "Cannot add category."); + success = true; + } + break; + + case "requirements": + if (saveRequirements(req, resp, parameters)) { + success = editRequirements(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot save requirements."); + success = true; + } + } + break; + + case "addRequirement": + if (!addRequirementForm(req, resp, parameters)) { + ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); + } + success = editRequirements(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); + success = true; + } + break; + + case "capabilities": + if (saveCapabilities(req, resp, parameters)) { + success = editCapabilities(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot save capabilities."); + success = true; + } + + } else { + ResourceServlet.setError(req.getSession(), false, "Cannot save capabilities."); + success = true; + } + break; + + case "capability": + if (saveCapability(req, resp, parameters)) { + success = editCapabilities(req, resp, parameters, true); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); + success = true; + } + } else { + ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); + success = true; + } + break; + + case "property": + if (!saveProperty(req, resp, parameters)) { + ResourceServlet.setError(req.getSession(), false, "Cannot add property."); + } + success = editCapabilities(req, resp, parameters, true); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Error while loading capabilities."); + success = true; + } + break; + + case "editProperties": + if (!saveResourceProperty(req, resp, parameters)) { + ResourceServlet.setError(req.getSession(), false, "Cannot change properties."); + } + success = editProperties(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Error while loading capabilities."); + success = true; + } + break; + + default: + } + } + if (!success) { + resp.sendError(HttpServletResponse.SC_ACCEPTED, "NOT FOUND OR FAILED TO PROCEED"); + } + } + + private boolean saveResourceProperty(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String uri; + if (parameters.containsKey("uri")) { + uri = ((String[]) parameters.get("uri"))[0]; + } else { + return false; + } + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List resources = getResources(req, link); + if (resources == null) { + return false; + } + Resource resource = findResource(resURI, resources); + // TODO why was the following here: +// String symbolicName = ((String[]) parameters.get("symbolicName"))[0]; +// String version = ((String[]) parameters.get("version"))[0]; + +// LegacyMetadataHelper.setVersion(Activator.instance().getMetadataFactory(), resource, new Version(version)); +// LegacyMetadataHelper.setSymbolicName(Activator.instance().getMetadataFactory(), resource, symbolicName); + + Activator.instance().getMetadataDao().saveResource(resource); + } catch (URISyntaxException e) { + logger.warn("Can't save resource property: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't save resource property, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't save resource property", e); + return false; + } + + return true; + } + + private boolean saveProperty(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String uri; + String id; + if (parameters.containsKey("uri") && parameters.containsKey("capabilityId")) { + uri = ((String[]) parameters.get("uri"))[0]; + id = ((String[]) parameters.get("capabilityId"))[0]; + } else { + return false; + } + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + Capability capability = resource.getCapabilities().get(Integer.parseInt(id) - 1); + String name = ((String[]) parameters.get("name"))[0]; + String type = ((String[]) parameters.get("propertyType"))[0]; + Object value = ((String[]) parameters.get("value"))[0]; + + try { + capability.setAttribute(new GenericAttributeType(name, type), value); + } catch (IllegalArgumentException e) { + return false; + } + Activator.instance().getMetadataDao().saveResource(resource); + + } catch (URISyntaxException e) { + logger.warn("Can't save property: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't save property, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't save property", e); + return false; + } + + return true; + } + + private boolean editCapabilities(HttpServletRequest req, + HttpServletResponse resp, Map parameters) { + return editCapabilities(req, resp, parameters, false); + } + + private boolean saveCapability(HttpServletRequest req, + HttpServletResponse resp, Map parameters) { + String uri; + String capabilityName; + if (parameters.containsKey("uri") + && parameters.containsKey("capability")) { + uri = ((String[]) parameters.get("uri"))[0]; + capabilityName = ((String[]) parameters.get("capability"))[0]; + } else { + return false; + } + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + int lengthBefore = resource.getCapabilities().size(); + resource.addCapability(Activator.instance().getMetadataFactory().createCapability(capabilityName)); + if (lengthBefore == resource.getCapabilities().size()) { + resp.sendRedirect("resource"); + return false; + } + + Activator.instance().getMetadataDao().saveResource(resource); + + req.setAttribute("capabilityId", String.valueOf(resource.getCapabilities().size())); + } catch (URISyntaxException e) { + logger.warn("Can't save capability: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't save capability, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't save capability", e); + return false; + } + + return true; + } + + private boolean addRequirementForm(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String uri; + if (parameters.containsKey("uri")) { + uri = ((String[]) parameters.get("uri"))[0]; + } else { + return false; + } + + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + String name = null; + Requirement requir = null; + String filter = null; + boolean multiple = false; + boolean extend = false; + boolean optional = false; + Requirement requirBefore = null; + if (parameters.containsKey("name") + && parameters.containsKey("filter")) { + name = ((String[]) parameters.get("name"))[0]; + filter = ((String[]) parameters.get("filter"))[0]; + if (parameters.containsKey("multiple")) { + multiple = ((String[]) parameters.get("multiple"))[0].equals("on"); + } + if (parameters.containsKey("optional")) { + optional = ((String[]) parameters.get("optional"))[0].equals("on"); + } + if (parameters.containsKey("extend")) { + extend = ((String[]) parameters.get("extend"))[0].equals("on"); + } + String comment = null; + if (parameters.containsKey("comment")) { + comment = ((String[]) parameters.get("comment"))[0]; + } + int lengthBefore = resource.getRequirements().size(); + requir = Activator.instance().getMetadataFactory().createRequirement(name); + resource.addRequirement(requir); + if (lengthBefore == resource.getRequirements().size()) { + req.getSession().setAttribute("success", false); + req.getSession().setAttribute("message", "Cannot add requirement."); + return false; + } + try { + logger.warn("OSGi filter is not supported yet with new Metadata API, setting as a directive to track it's usage: {}", filter); + requir.setDirective("filter", filter); + } catch (IllegalArgumentException e) { + resource.removeRequirement(requir); + resource.addRequirement(requirBefore); + } + requir.setDirective("multiple", String.valueOf(multiple)); + requir.setDirective("optional", String.valueOf(optional)); + requir.setDirective("extend", String.valueOf(extend)); + requir.setDirective("comment", comment); + } + Activator.instance().getMetadataDao().saveResource(resource); + } catch (URISyntaxException e) { + logger.warn("Can't add requirement: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add requirement, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't requirement", e); + return false; + } + + req.getSession().setAttribute("success", true); + return true; + + } + + private boolean saveCapabilities(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + int capabilityId = -1; + String uri; + if (parameters.containsKey("uri") && parameters.containsKey("capabilityId")) { + uri = ((String[]) parameters.get("uri"))[0]; + capabilityId = Integer.parseInt(((String[]) parameters.get("capabilityId"))[0]); + } else { + return false; + } + + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + + Capability capability = resource.getCapabilities().get(capabilityId - 1); + List> attributes = capability.getAttributes(); +// Property[] properties = capability.getProperties(); + for (int i = 0; i < attributes.size(); i++) { + String name = ((String[]) parameters.get("name_" + (i + 1)))[0]; + String type = ((String[]) parameters.get("type_" + (i + 1)))[0]; + String value = ((String[]) parameters.get("value_" + (i + 1)))[0]; + Attribute propBefore = attributes.get(i); + int propertiesLengthBefore = attributes.size(); + capability.removeAttribute(attributes.get(i).getAttributeType()); + + if (propertiesLengthBefore == capability.getAttributes().size()) { + req.getSession().setAttribute("success", false); + req.getSession().setAttribute("message", "Cannot change property."); + logger.debug("Cannot change property, resource: {}", resource); + continue; + } + + try { + capability.setAttribute(new GenericAttributeType(name, type), value); + } catch (IllegalArgumentException e) { + capability.setAttribute(propBefore); + req.getSession().setAttribute("success", false); + req.getSession().setAttribute("message", "Cannot change property."); + logger.warn("Cannot change property, resource: {}, capability: {}", resource, capability); + } + } + Activator.instance().getMetadataDao().saveResource(resource); + } catch (URISyntaxException e) { + logger.warn("Can't save capabilities: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't save capabilities, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't save capabilities", e); + return false; + } + return true; + } + + private boolean saveRequirements(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String uri; + if (parameters.containsKey("uri")) { + uri = ((String[]) parameters.get("uri"))[0]; + } else { + return false; + } + + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + + List requirements = resource.getRequirements(); + int requirLengthBefore = 0; + String name = null; + Requirement requir = null; + String filter = null; + String comment = null; + boolean multiple = false; + boolean extend = false; + boolean optional = false; + Requirement requirBefore = null; + for (int i = 0; i < requirements.size(); i++) { + + if (parameters.containsKey("name_" + (i + 1)) + && parameters.containsKey("filter_" + (i + 1))) { + + name = ((String[]) parameters.get("name_" + (i + 1)))[0]; + filter = ((String[]) parameters.get("filter_" + (i + 1)))[0]; + + if (parameters.containsKey("multiple_" + (i + 1))) { + multiple = ((String[]) parameters.get("multiple_" + (i + 1)))[0].equals("on"); + } + if (parameters.containsKey("optional_" + (i + 1))) { + optional = ((String[]) parameters.get("optional_" + (i + 1)))[0].equals("on"); + } + if (parameters.containsKey("extend_" + (i + 1))) { + extend = ((String[]) parameters.get("extend_" + (i + 1)))[0].equals("on"); + } + if (parameters.containsKey("comment_" + (i + 1))) { + comment = ((String[]) parameters.get("comment_" + (i + 1)))[0]; + } +// requirBefore = requirements[i]; + requirLengthBefore = requirements.size(); + resource.removeRequirement(requirements.get(i)); + if (requirLengthBefore == resource.getRequirements().size()) { +//TODO req.getSession().setAttribute("success", false); +//TODO req.getSession().setAttribute("message", "Cannot change requirement."); + continue; + } + requir = Activator.instance().getMetadataFactory().createRequirement(name); + resource.addRequirement(requir); + try { + logger.warn("OSGi filter is not supported yet with new Metadata API, setting as a directive to track it's usage: {}", filter); + requir.setDirective("filter", filter); + } catch (IllegalArgumentException e) { +//TODO req.getSession().setAttribute("success", false); +//TODO req.getSession().setAttribute("message", "Cannot change requirement."); + resource.removeRequirement(requir); + resource.addRequirement(requirBefore); + continue; + } + requir.setDirective("multiple", String.valueOf(multiple)); + requir.setDirective("optional", String.valueOf(optional)); + requir.setDirective("extend", String.valueOf(extend)); + requir.setDirective("comment", comment); +// resource.addRequirement(requir); + } + } + Activator.instance().getMetadataDao().saveResource(resource); + } catch (URISyntaxException e) { + logger.warn("Can't save requirements: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't save requirements, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't save requirements", e); + return false; + } + return true; + } + + private boolean addCategory(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String category = null; + String uri = null; + if (parameters.containsKey("category") + && parameters.containsKey("uri")) { + category = ((String[]) parameters.get("category"))[0]; + uri = ((String[]) parameters.get("uri"))[0]; + + } else { + return false; + } + + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + + + int categoriesLengthBefore = Activator.instance().getMetadataService().getCategories(resource).size(); + Activator.instance().getMetadataService().addCategory(resource, category); + + // check that category was really added + if (categoriesLengthBefore >= Activator.instance().getMetadataService().getCategories(resource).size()) { + req.getSession().setAttribute("success", false); + req.getSession().setAttribute("message", "Cannot add category."); + } + + Activator.instance().getMetadataDao().saveResource(resource); + + } catch (URISyntaxException e) { + logger.warn("Can't add category: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add category, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't add category", e); + return false; + } + return true; + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + cleanSession(req.getSession()); + + req.getSession().removeAttribute("success"); + boolean success = false; + Map parameters = (Map) req.getParameterMap(); + + String type = null; + if (parameters.containsKey("type")) { + type = ((String[]) parameters.get("type"))[0]; + } + if (type != null) { + switch (type) { + case "deleteCompoment": + success = deleteComponent(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot delete component."); + success = true; + } + break; + + case "category": + success = editCategories(req, resp); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot edit category."); + success = true; + } + break; + + case "deleteCategory": + if (!deleteCategory(req, resp, parameters)) { + ResourceServlet.setError(req.getSession(), false, "Cannot delete category."); + success = true; + } + success = editCategories(req, resp); + break; + + case "addCategory": + success = addCategories(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add category."); + success = true; + } + break; + + case "addCapability": + success = addCapabilities(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); + success = true; + } + break; + + case "addCapabilityProperty": + success = addCapabilityProperty(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); + success = true; + } + break; + + case "capability": + success = editCapabilities(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot edit capabilities."); + success = true; + } + break; + + case "requirement": + success = editRequirements(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot edit requirements."); + success = true; + } + break; + + case "addRequirement": + success = addRequirement(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); + success = true; + } + break; + + case "properties": + success = editProperties(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); + success = true; + } + break; + default: + success = false; + break; + } + } + if (!success) { + resp.sendError(HttpServletResponse.SC_ACCEPTED, "NOT FOUND OR FAILED TO PROCEED"); + } + } + + private boolean editProperties(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + String uri = req.getParameter("uri"); + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getRequestDispatcher("jsp/forms/propertiesForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't edit properties: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't edit properties, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't edit properties", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + return true; + } + + private boolean addCapabilityProperty(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + String uri = req.getParameter("uri"); + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getSession().setAttribute("capabilityId", req.getParameter("capabilityId")); + req.getRequestDispatcher("jsp/forms/propertyForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't add capability property: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add capability property, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't add capability property", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean addRequirement(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + String uri = req.getParameter("uri"); + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getRequestDispatcher("jsp/forms/requirementForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't add requirement: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add requirement, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't add requirement", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean editRequirements(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + String uri = req.getParameter("uri"); + + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getRequestDispatcher("jsp/forms/requirementsForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't edit requirement: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't edit requirement, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't edit requirement", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + return true; + } + + private boolean addCapabilities(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + String uri = req.getParameter("uri"); + + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getSession().setAttribute("types", Type.values()); + req.getRequestDispatcher("jsp/forms/capabilityForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't add capabilities: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add capabilities, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't add capabilities", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean editCapabilities(HttpServletRequest req, HttpServletResponse resp, Map parameters, boolean b) { + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + String uri = null; + try { + String id = null; + if (b && parameters.containsKey("uri") && req.getAttribute("capabilityId") != null) { + uri = ((String[]) parameters.get("uri"))[0]; + id = (String) req.getAttribute("capabilityId"); + } else if (parameters.containsKey("capabilityId") && parameters.containsKey("uri")) { + uri = ((String[]) parameters.get("uri"))[0]; + id = ((String[]) parameters.get("capabilityId"))[0]; + } else { + return false; + } + Resource resource = findResource(new URI(uri), array); + + req.getSession().setAttribute("resource", resource); + req.getSession().setAttribute("types", Type.values()); + req.getSession().setAttribute("capability", resource.getCapabilities().get(Integer.parseInt(id) - 1)); + req.getSession().setAttribute("capabilityId", id); + req.getRequestDispatcher("jsp/forms/capabilitiesForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't edit capabilities: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't edit capabilities, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't edit capabilities", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean addCategories(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + String uri = req.getParameter("uri"); + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getRequestDispatcher("jsp/forms/categoryForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't add capabilities: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add capabilities, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't add capabilities", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean editCategories(HttpServletRequest req, HttpServletResponse resp) { + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + String uri = req.getParameter("uri"); + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getRequestDispatcher("jsp/forms/categoriesForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't edit categories: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't edit categories, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't edit categories", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean deleteCategory(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String category = null; + String uri = null; + if (parameters.containsKey("category") + && parameters.containsKey("uri")) { + category = ((String[]) parameters.get("category"))[0]; + uri = ((String[]) parameters.get("uri"))[0]; + + } else { + return false; + } + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + Resource resource = findResource(resURI, array); + + int categoriesLengthBefore = Activator.instance().getMetadataService().getCategories(resource).size(); + Activator.instance().getMetadataService().removeCategory(resource, category); + +// Zjištění zda kategorie byla odstraněna. + if (categoriesLengthBefore == Activator.instance().getMetadataService().getCategories(resource).size()) { + return false; + } + + Activator.instance().getMetadataDao().saveResource(resource); + + } catch (URISyntaxException e) { + logger.warn("Can't delete category: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't delete category, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't delete category", e); + return false; + } + + return true; + } + + private boolean deleteComponent(HttpServletRequest req, HttpServletResponse resp, final Map parameters) { + String link = null; + String uri = null; + if (parameters.containsKey("link") + && parameters.containsKey("uri")) { + link = ((String[]) parameters.get("link"))[0]; + uri = ((String[]) parameters.get("uri"))[0]; + + } else { + return false; + } + try { + URI fileUri = new URI(uri); + if ("store".equals(link)) { + List array = Activator.instance().getStore(getRepositoryId(req)).getResources(); + Resource found = findResource(fileUri, array); + Activator.instance().getStore(getRepositoryId(req)).remove(found); + } else if ("buffer".equals(link)) { + List array = Activator.instance().getBuffer(req).getResources(); + Resource found = findResource(fileUri, array); + if (!Activator.instance().getBuffer(req).remove(found)) { + logger.warn("Buffer didn't contain removed resource: {}", found); + } + } else { + return false; + } + + req.getRequestDispatcher("resource").forward(req, resp); + + } catch (URISyntaxException e) { + logger.warn("Can't delete component: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't delete component, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't delete component", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + return true; + } + + public static Resource findResource(URI uri, List array) throws FileNotFoundException { + Resource found = null; + for (Resource r : array) { + if (Activator.instance().getMetadataService().getUri(r).equals(uri)) { + found = r; + break; + } + } + if (found == null) { + throw new FileNotFoundException(); + } + return found; + } + + private static void cleanSession(HttpSession session) { + session.removeAttribute("resource"); + } + + private List getResources(HttpServletRequest req, String link) { + switch (link) { + case "store": + return Activator.instance().getStore(getRepositoryId(req)).getResources(); + case "buffer": + return Activator.instance().getBuffer(req).getResources(); + default: + return null; + } + } + + private String getRepositoryId(HttpServletRequest req) { + String id = req.getParameter("repositoryId"); + if (id == null) { + Map stores = Activator.instance().getRepositories(); + if (stores.isEmpty()) { + return null; + } + id = stores.keySet().iterator().next(); + logger.trace("Store ID not specified, using the first store found: " + id); + } + return id; + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Helper.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Helper.java new file mode 100644 index 00000000..bc4ea5ed --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Helper.java @@ -0,0 +1,26 @@ +package cz.zcu.kiv.crce.webui.internal; + +import java.io.IOException; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author kalwi + */ +public class Helper { + + private static final Logger logger = LoggerFactory.getLogger(Helper.class); + + public static void forwardTo(String url, HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + logger.debug("Forwarding to: " + url); + + RequestDispatcher rd = req.getRequestDispatcher(url); + rd.forward(req, res); + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java new file mode 100644 index 00000000..77aef538 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java @@ -0,0 +1,389 @@ +package cz.zcu.kiv.crce.webui.internal; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.annotation.CheckForNull; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cz.zcu.kiv.crce.compatibility.Compatibility; +import cz.zcu.kiv.crce.compatibility.CompatibilityVersionComparator; +import cz.zcu.kiv.crce.metadata.Requirement; +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiIdentity; +import cz.zcu.kiv.crce.metadata.type.Version; +import cz.zcu.kiv.crce.plugin.Plugin; +import cz.zcu.kiv.crce.webui.internal.bean.Category; +import cz.zcu.kiv.crce.webui.internal.custom.ResourceExt; + +public class ResourceServlet extends HttpServlet { + + private static final long serialVersionUID = -4218424299866417104L; + + private static final Logger logger = LoggerFactory.getLogger(ResourceServlet.class); + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + String source = (String) req.getSession().getAttribute("source"); + logger.debug("Resource servlet POST source: {}", source); + + //if form was submit, set session parameters{ + if ("yes".equalsIgnoreCase(req.getParameter("showStoreTag"))) { + req.getSession().setAttribute("showStoreTag", "yes"); + logger.debug("showStoreTag session attribute set to yes"); + } else { + req.getSession().setAttribute("showStoreTag", "no"); + logger.debug("showStoreTag session attribute set to no"); + } + + if ("yes".equalsIgnoreCase(req.getParameter("showBufferTag"))) { + req.getSession().setAttribute("showBufferTag", "yes"); + logger.debug("showBufferTag session attribute set to yes"); + } else { + req.getSession().setAttribute("showBufferTag", "no"); + logger.debug("showBufferTag session attribute set to no"); + } + + if ("upload".equals(source) || "commit".equals(source)) { + doGet(req, resp); + } else { + String filter = req.getParameter("filter"); + if (filter != null && !filter.isEmpty()) { + + logger.warn("LDAP filter is not supported yet with new Metadata API, returning all resources for filter: {}", filter); + + fillSession(source, req, null); // TODO there was filter instead of null in implementation with old metadata + req.getRequestDispatcher("jsp/" + source + ".jsp").forward(req, resp); + } else { + doGet(req, resp); + } + } + + + + + + +// else if (req.getParameter("repositorySelection") != null) { +// req.getSession().setAttribute("repositoryId", req.getParameter("repositorySelection")); +// } + + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + + String link = null; + + if (req.getParameter("link") != null) { + link = req.getParameter("link"); + } + + try { + if (fillSession(link, req, null)) { + //resp.sendRedirect("jsp/"+link+".jsp"); + req.getRequestDispatcher("jsp/" + link + ".jsp").forward(req, resp); + } else { + logger.debug("Default forward"); + req.getRequestDispatcher("resource?link=store").forward(req, resp); + } + + } catch (ServletException e) { + logger.warn("Can't forward: {}", e); + } catch (IOException e) { + logger.error("Can't forward", e); + } + } + + public static void cleanSession(HttpSession session) { + session.removeAttribute("resources"); + session.removeAttribute("plugins"); + session.removeAttribute("store"); + } + + public static void setError(HttpSession session, boolean success, String message) { + session.setAttribute("success", success); + session.setAttribute("message", message); + } + + private boolean fillSession(String link, HttpServletRequest req, Requirement filter) { + + String errorMessage = filter + " is not a valid filter"; + HttpSession session = req.getSession(); + cleanSession(session); + if (link == null) { + return false; + } + + Set> repositories = Activator.instance().getRepositories().entrySet(); + session.setAttribute("showRepositorySelection", repositories.size() > 1); // TODO this logic should be in header.jsp + session.setAttribute("repositories", repositories); + session.setAttribute("repositoryId", getRepositoryId(req)); + + switch (link) { + case "buffer": { + List resources; + if (filter == null) { + resources = Activator.instance().getBuffer(req).getResources(); + } else { + try { + resources = Activator.instance().getBuffer(req).getResources(filter, true); + } catch (Exception e) { // TODO there was catch of InvalidSyntaxException, why? + setError(session, false, errorMessage); + resources = Activator.instance().getBuffer(req).getResources(); + } + } + List bufferResourcesExt = new ArrayList<>(resources.size()); + for (Resource resource : resources) { + bufferResourcesExt.add(new ResourceExt(resource, Activator.instance().getMetadataService())); + } + session.setAttribute("buffer", bufferResourcesExt); + return true; + } + + case "plugins": { + List plugins; + if (filter == null) { + plugins = Activator.instance().getPluginManager().getPlugins(); + } else { + plugins = Activator.instance().getPluginManager().getPlugins(); + logger.warn("Filtering plugins with new Metadata API is not supported yet, returning all plugins."); +// plugins = Activator.instance().getPluginManager().getPlugins(Plugin.class, filter); + } + List pluginWrappers = new ArrayList<>(plugins.size()); + for (Plugin plugin : plugins) { + pluginWrappers.add(new cz.zcu.kiv.crce.webui.internal.custom.Plugin(plugin)); + } + session.setAttribute("plugins", pluginWrappers); + return true; + } + + case "store": { + String id = getRepositoryId(req); + if (id == null) { + return true; + } + List resources; + if (filter == null) { + resources = Activator.instance().getStore(id).getResources(); + } else { + try { + resources = Activator.instance().getStore(id).getResources(filter, false); + } catch (Exception e) { // TODO there was catch of InvalidSyntaxException, why? + setError(session, false, errorMessage); + resources = Activator.instance().getStore(id).getResources(); + } + } + List storeResourcesExt = new ArrayList<>(resources.size()); + for (Resource resource : resources) { + storeResourcesExt.add(new ResourceExt(resource, Activator.instance().getMetadataService())); + } + session.setAttribute("store", storeResourcesExt); + return true; + } + + case "tags": { + List resources = prepareResources(req, filter); + ArrayList categoryList = prepareCategoryList(resources); + ArrayList filteredResourceList; + + String selectedCategory; + if (req.getParameter("tag") != null) { + selectedCategory = req.getParameter("tag"); + + filteredResourceList = filterResources(selectedCategory, resources); + + } else { + filteredResourceList = null; + } + + session.setAttribute("resources", filteredResourceList); + session.setAttribute("categoryList", categoryList); + + return true; + } + + case "compatibility": { + String name = req.getParameter("name"); + String version = req.getParameter("version"); + String id = getRepositoryId(req); + + List lower = null; + List upper = null; + + if (name == null || name.isEmpty() || version == null || version.isEmpty() || id == null) { + session.setAttribute("nodata", true); + return true; + } + session.setAttribute("nodata", false); + + Requirement resFilter = Activator.instance().getMetadataFactory().createRequirement(NsOsgiIdentity.NAMESPACE__OSGI_IDENTITY); + resFilter.addAttribute(NsOsgiIdentity.ATTRIBUTE__SYMBOLIC_NAME, name); + Version v = new Version(version); + resFilter.addAttribute(NsOsgiIdentity.ATTRIBUTE__VERSION, v); + + List res = Activator.instance().getStore(id).getResources(resFilter, false); + if (!res.isEmpty()) { + lower = Activator.instance().getCompatibilityService().listLowerCompatibilities(res.get(0)); + Collections.sort(lower, CompatibilityVersionComparator.getBaseComparator()); + + upper = Activator.instance().getCompatibilityService().listUpperCompatibilities(res.get(0)); + Collections.sort(upper, CompatibilityVersionComparator.getUpperComparator()); + + } + + session.setAttribute("pivotName", name); + session.setAttribute("pivotVersion", version); + session.setAttribute("lower", lower); + session.setAttribute("upper", upper); + + return true; + } + + default: + return false; + } + } + + /** + * Prepare resource array. Resource array is created from store and buffer. Store resources are added, if request parameter + * store is "yes". Buffer resources are added, if request parameter + * buffer is "yes". + * + * @param req request with parameters + * @param filter possible filter of resources + * @return array of resources + */ + private List prepareResources(HttpServletRequest req, Requirement filter) { + HttpSession session = req.getSession(); + + List storeResources = Collections.emptyList(); + List bufferResources = Collections.emptyList(); + + String id = getRepositoryId(req); + if (id != null && "yes".equalsIgnoreCase((String) session.getAttribute("showStoreTag"))) { + if (filter == null) { + storeResources = Activator.instance().getStore(id).getResources(); + } else { + try { + storeResources = Activator.instance().getStore(id).getResources(filter, false); + } catch (Exception e) { // TODO there was catch of InvalidSyntaxException, why? + logger.warn("Invalid syntax", e); + setError(session, false, filter + " is not a valid filter"); + storeResources = Activator.instance().getStore(id).getResources(); + } + } + } + + if ("yes".equals((String) session.getAttribute("showBufferTag"))) { + if (filter == null) { + bufferResources = Activator.instance().getBuffer(req).getResources(); + } else { + try { + bufferResources = Activator.instance().getBuffer(req).getResources(filter, true); + } catch (Exception e) { // TODO there was catch of InvalidSyntaxException, why? + logger.warn("Invalid syntax", e); + setError(session, false, filter + " is not a valid filter"); + bufferResources = Activator.instance().getBuffer(req).getResources(); + } + } + } + + //merge two resources arrays + List resources = new ArrayList<>(storeResources.size() + bufferResources.size()); + resources.addAll(storeResources); + resources.addAll(bufferResources); + + return resources; + } + + /** + * Prepare list of categories (tags) that are on all resources in the store. Category is represented by name and the number of + * occurrences. + * + * @param resources - all resources from the store + * @return array list of categories + */ + private ArrayList prepareCategoryList(List resources) { + + HashMap categoryMap = new HashMap<>(); + + for (Resource resource : resources) { + List categories = Activator.instance().getMetadataService().getCategories(resource); + for (String category : categories) { + if (categoryMap.containsKey(category)) { + //category is already contained, increase count + categoryMap.put(category, categoryMap.get(category) + 1); + } else { + //add new category + categoryMap.put(category, 1); + } + } + } + + ArrayList categoryList = new ArrayList<>(); + + //Get categories from map to list + for (Map.Entry entry : categoryMap.entrySet()) { + Category newCategory = new Category(entry.getKey()); + newCategory.setCount(entry.getValue()); + categoryList.add(newCategory); + } + + //sort category list + Collections.sort(categoryList); + + return categoryList; + + + } + + /** + * Filter resources according some category. Output list contains only resources that have required category. + * + * @param filterCategory required category + * @param resources resources + * @return filtered resources list + */ + private ArrayList filterResources(String filterCategory, List resources) { + ArrayList filteredResourceList = new ArrayList<>(); + for (Resource resource : resources) { + List categories = Activator.instance().getMetadataService().getCategories(resource); + for (String category : categories) { + if (category.equals(filterCategory)) { + filteredResourceList.add(new ResourceExt(resource, Activator.instance().getMetadataService())); + break; + } + } + } + + return filteredResourceList; + } + + @CheckForNull + private String getRepositoryId(HttpServletRequest req) { + String id = req.getParameter("repositoryId"); + if (id == null) { + Map stores = Activator.instance().getRepositories(); + if (stores.isEmpty()) { + return null; + } + id = stores.keySet().iterator().next(); + logger.trace("Store ID not specified, using the first store found: " + id); + } + return id; + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java new file mode 100644 index 00000000..9c3dabf9 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java @@ -0,0 +1,111 @@ +package cz.zcu.kiv.crce.webui.internal; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.repository.plugins.Executable; + +public class RuntimeServlet extends HttpServlet { + + private static final Logger logger = LoggerFactory.getLogger(RuntimeServlet.class); + + /** + * + */ + private static final long serialVersionUID = 1L; + private String message = null; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + if (isStoreBufferAction(req)) { + if (setSessionForForm(req)) { + req.getRequestDispatcher("jsp/forms/testForm.jsp").forward(req, resp); // FIXME hardcoded + } else { + message = "No bundles selected"; + logger.warn(message); + ResourceServlet.setError(req.getSession(), false, message); + req.getRequestDispatcher("jsp/" + req.getSession().getAttribute("source") + ".jsp").forward(req, resp); + } + } + ResourceServlet.setError(req.getSession(), false, "Wrong params!"); + req.getRequestDispatcher("resource").forward(req, resp); + + } + + private boolean setSessionForForm(HttpServletRequest req) { + Resource[] toTest = parseParams(req); + if (toTest == null) { + return false; + } else { + HttpSession session = req.getSession(); + ResourceServlet.cleanSession(session); + session.setAttribute("resources", toTest); + List testPlugins = Activator.instance().getPluginManager().getPlugins(Executable.class); + // Executable is not Serializable so this workaround is needed + List testPluginIds = new ArrayList<>(testPlugins.size()); + for (Executable executable : testPlugins) { + testPluginIds.add(executable.getPluginId()); + } + session.setAttribute("tests", testPluginIds); + return true; + } + } + + private List fetchRightResources(String source, HttpServletRequest req) { + Activator a = Activator.instance(); + if (source.equals("store")) { + return a.getStore(null).getResources(); + } else { + return a.getBuffer(req).getResources(); + } + } + + private Resource[] parseParams(HttpServletRequest req) { + + + String[] uris = req.getParameterValues("check"); + if (uris == null || uris.length == 0) { + return null; + } + List resources = fetchRightResources((String) req.getSession().getAttribute("source"), req); + Resource[] toTest = new Resource[uris.length]; + for (int i = 0; i < uris.length; i++) { + try { + toTest[i] = EditServlet.findResource(new URI(uris[i]), resources); + } catch (FileNotFoundException e) { + message = "File not found! Please try again!"; + return null; + } catch (URISyntaxException e) { + message = "Malformed URI cant make URI from param!"; + return null; + } + + } + return toTest; + } + + private boolean isStoreBufferAction(HttpServletRequest req) { + String source = (String) req.getSession().getAttribute("source"); + logger.debug("Runtime servlet POST source: {}", source); + if ("buffer".equals(source) || "store".equals(source)) { + return true; + } else { + return false; + } + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/SessionListener.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/SessionListener.java new file mode 100644 index 00000000..754137b0 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/SessionListener.java @@ -0,0 +1,25 @@ +package cz.zcu.kiv.crce.webui.internal; + +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +/** + * + * @author Jiri Kucera (jiri.kucera@kalwi.eu) + */ +public class SessionListener implements HttpSessionListener { + + @Override + public void sessionCreated(HttpSessionEvent se) { + se.getSession(); + String sid = se.getSession().getId(); + Activator.instance().getSessionRegister().registerSession(sid); + } + + @Override + public void sessionDestroyed(HttpSessionEvent se) { + String sid = se.getSession().getId(); + Activator.instance().getSessionRegister().unregisterSession(sid); + } + +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/UploadServlet.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/UploadServlet.java new file mode 100644 index 00000000..fa929a3b --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/UploadServlet.java @@ -0,0 +1,213 @@ +package cz.zcu.kiv.crce.webui.internal; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cz.zcu.kiv.crce.repository.Buffer; +import cz.zcu.kiv.crce.repository.RefusedArtifactException; +import java.net.MalformedURLException; +import java.net.URL; + +/** + * + * @author kalwi + */ +public class UploadServlet extends HttpServlet { + + private static final long serialVersionUID = -7359560802937893940L; + + private static final Logger logger = LoggerFactory.getLogger(UploadServlet.class); + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + boolean failed = false; + + if (req.getParameter("uri") != null) { + Buffer buffer = Activator.instance().getBuffer(req); +// List resources = buffer.getResources(); +// String uriParam = req.getParameter("uri"); + try { +// URI uri = new URI(uriParam); +// Resource found = EditServlet.findResource(uri, resources); + buffer.commit(true); //TODO! Bad API -> Resources should be committed one by one +// } catch (URISyntaxException e) { +// logger.error("Invalid URI syntax", e); +// failed = true; + } catch (IOException e) { + logger.error("Could not commit", e); + failed = true; + } + } else { + failed = true; + } + if (failed) { + logger.error("Commit failed"); + ResourceServlet.setError(req.getSession(), !failed, "Commit failed"); + } else { + req.getRequestDispatcher("resource?link=buffer"); + } + + /*PrintWriter out = resp.getWriter(); + out.println("

Resources to commit:

"); + for (Resource res : buffer.getRepository().getResources()) { + out.println(res.getId() + " " + res.getUri()); + } + + List commited = buffer.commit(true); + out.println("

Commited resources " + commited.size() + ":

"); + for (Resource res : commited) { + out.println(res.getId() + " " + res.getUri() + "
"); + }*/ + + // HttpSession session = req.getSession(true); + // + // PrintWriter out = resp.getWriter(); + // out.println("m_stack: " + (Activator.instance().getBuffer(req) != null ? "found" : "not found")); // XXX + // + // Enumeration en = session.getAttributeNames(); + // + // while (en.hasMoreElements()) { + // String name = (String) en.nextElement(); + // out.println(name + ": " + session.getAttribute(name)); + // } + // + // session.setAttribute("id" + new Random().nextInt(100), new Random().nextInt(10)); + // + // + // out.close(); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + boolean success = true; + String message; + String from = req.getParameter("from"); + + if (from != null && from.equalsIgnoreCase("local")) { + // local upload from hdd + logger.debug("Got \"from\" parameter with value \"{}\".", from); + if (ServletFileUpload.isMultipartContent(req)) { + ServletFileUpload servletFileUpload = new ServletFileUpload(new DiskFileItemFactory()); + List fileItemsList; + try { + fileItemsList = servletFileUpload.parseRequest(req); + } catch (FileUploadException e) { + logger.error("Exception handling request: " + req.getRequestURL(), e); + sendResponse(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return; + } + + for (Object o : fileItemsList) { + FileItem fi = (FileItem) o; + + if (!fi.isFormField()) { + String fileName = fi.getName(); + try (InputStream is = fi.getInputStream()) { + try { + Activator.instance().getBuffer(req).put(fileName, is); + } catch (RefusedArtifactException ex) { + logger.warn("Artifact revoked: ", ex.getMessage()); + success = false; + } + } + } + } + } else { + success = false; + } + } else { + // remote upload from url + logger.debug("Got \"from\" parameter with value \"{}\".", from); + String url = req.getParameter("url"); + if (from != null && from.equalsIgnoreCase("remote") && url != null && url.length() > 0) { + logger.debug("Got \"url\" parameter with value \"{}\".", url); + InputStream is = createInputStreamFromIdlUri(url); + try { + Activator.instance().getBuffer(req).put(url, is); + } catch (RefusedArtifactException ex) { + logger.warn("Artifact revoked: ", ex.getMessage()); + success = false; + } + } else { + success = false; + } + } + + StringBuilder metadataIndexerResult = new StringBuilder(); + if (success) { + message = "Upload was succesful."; + +// MetadataIndexingResultService indexerResult = Activator.instance().getMetadataIndexerResult(); +// if (!indexerResult.isEmpty()) { +// String[] metadataIndexerMessages = indexerResult.getMessages(); +// for (String indexerMessage : metadataIndexerMessages) { +// metadataIndexerResult.append("
").append(indexerMessage); +// } +// indexerResult.removeAllMessages(); +// } + } else { + message = "Upload failed."; + } + + ResourceServlet.setError(req.getSession(), success, message + metadataIndexerResult); + req.getSession().setAttribute("source", "upload"); + req.getRequestDispatcher("resource?link=buffer").forward(req, resp); + } + + // send a response with the specified status code + private void sendResponse(HttpServletResponse response, int statusCode) { + sendResponse(response, statusCode, ""); + } + + // send a response with the specified status code and description + private void sendResponse(HttpServletResponse response, int statusCode, String description) { + try { + response.sendError(statusCode, description); + } catch (Exception e) { + logger.warn("Unable to send response with status code '{}'", statusCode, e); + } + } + + /** + * Opens remote URL of IDL document and returns {@link java.io.InputStream} of that location in order to read content from it. + * + * + * @param url Remote URL + * @return {@link java.io.InputStream} of passed url location. + */ + private InputStream createInputStreamFromIdlUri(String url) { + + // try to access IDL content at uri + logger.debug("Attempting to access IDL at \"{}\".", url); + URL urlObj = null; + try { + urlObj = new URL(url); + } catch (MalformedURLException ex) { + logger.error("MalformedURLException: {}", url, ex); + } + if (urlObj == null) { + return null; + } + + // try to return InputStream + try { + return urlObj.openStream(); + } catch (IOException ex) { + logger.error("IOException: {}", url, ex); + return null; + } + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/VersionInfo.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/VersionInfo.java new file mode 100644 index 00000000..ac31f678 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/VersionInfo.java @@ -0,0 +1,67 @@ +package cz.zcu.kiv.crce.webui.internal; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import javax.servlet.ServletContext; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides information about application version. + * @author Jiri Kucera (jiri.kucera@kalwi.eu) + */ +public class VersionInfo { + + private static final Logger logger = LoggerFactory.getLogger(VersionInfo.class); + + private static final String MANIFEST = "/META-INF/MANIFEST.MF"; + private static final String PRODUCT_VERSION = "Product-Version"; + private static final String IMPLEMENTATION_BUILD = "Implementation-Build"; + private static final String UNKNOWN = "unknown"; + + private static VersionInfo instance = null; + private String productVersion; + private String buildRevision; + + /** + * Returns singleton instance of this class. + * @param servletContext Servlet context for reading WAR Manifest entries. If null, then the current + * class classloader will be used to read Manifest entries which can lead to that wrong Manifest will be read. + * @return Instance of this class. + */ + public static synchronized VersionInfo getVersionInfo(ServletContext servletContext) { + if (instance == null) { + instance = new VersionInfo(); + /* + * Product version is currently stored in WebUI MANIFEST, which could cause + * information mismatch if WAR from another build will be deployed. + * But for now it's enough. + */ + try (InputStream is + = servletContext != null ? servletContext.getResourceAsStream(MANIFEST) : Class.class.getResourceAsStream(MANIFEST)) { + Properties properties = new Properties(); + properties.load(is); + instance.productVersion = properties.getProperty(PRODUCT_VERSION); + instance.buildRevision = properties.getProperty(IMPLEMENTATION_BUILD); + } catch (IOException e) { + logger.error("Could not read version info from Manifest.", e); + } + } + return instance; + } + + public String getProductVersion() { + return productVersion != null ? productVersion : UNKNOWN; + } + + public String getBuildRevision() { + return buildRevision != null ? buildRevision : UNKNOWN; + } + + private VersionInfo() { + // singleton + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/bean/Category.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/bean/Category.java new file mode 100644 index 00000000..e59c9f1e --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/bean/Category.java @@ -0,0 +1,65 @@ +package cz.zcu.kiv.crce.webui.internal.bean; + +import java.io.Serializable; + +/** + * Bean class for category (tag of resources). + * Category is represented by name and number of occurences in the store. + * @author Jan Reznicek + * @version 1.0 + */ +public class Category implements Serializable, Comparable{ + private static final long serialVersionUID = 1L; + /** + * Name of category (jar,zip..) + */ + private String name; + /** + * Number of occurences of category in the store. + */ + private int count; + + public Category(String name) { + this.name = name; + count = 1; + } + + public String getName() { + return name; + } + public int getCount() { + return count; + } + public void setName(String name) { + this.name = name; + } + public void setCount(int count) { + this.count = count; + } + + @Override + public boolean equals(Object obj) { + if(this == obj) return true; + if(obj == null || obj.getClass() != this.getClass()) { + return false; + } + Category otherCat = (Category)obj; + if (otherCat.getName().equals(this.getName())) { + return true; + } + else { + return false; + } + } + + @Override + public int hashCode() { + + return name.hashCode(); + } + + public int compareTo(Category cat) { + return this.getName().compareTo(cat.getName()); + } + +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/Plugin.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/Plugin.java new file mode 100644 index 00000000..99bcbbc9 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/Plugin.java @@ -0,0 +1,47 @@ +package cz.zcu.kiv.crce.webui.internal.custom; + +import java.io.Serializable; +import java.util.List; + +/** + * + * @author Jiri Kucera (jiri.kucera@kalwi.eu) + */ +public class Plugin implements Serializable { + + private static final long serialVersionUID = 7452244491708601610L; + + private final String pluginId; + private final String pluginDescription; + private final String pluginPriority; + private final String pluginVersion; + private final List pluginKeywords; + + public Plugin(cz.zcu.kiv.crce.plugin.Plugin plugin) { + pluginId = plugin.getPluginId(); + pluginDescription = plugin.getPluginDescription(); + pluginPriority = String.valueOf(plugin.getPluginPriority()); + pluginVersion = plugin.getPluginVersion().toString(); + pluginKeywords = plugin.getPluginKeywords(); + } + + public String getPluginId() { + return pluginId; + } + + public String getPluginDescription() { + return pluginDescription; + } + + public String getPluginPriority() { + return pluginPriority; + } + + public String getPluginVersion() { + return pluginVersion; + } + + public List getPluginKeywords() { + return pluginKeywords; + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java new file mode 100644 index 00000000..2fe19dba --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java @@ -0,0 +1,85 @@ +package cz.zcu.kiv.crce.webui.internal.custom; + +import cz.zcu.kiv.crce.webui.internal.legacy.Capability; +import cz.zcu.kiv.crce.webui.internal.legacy.Requirement; + +public class RequirementAdapter implements Requirement { + + @Override + public String getName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getFilter() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isMultiple() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isOptional() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isExtend() { + // TODO Auto-generated method stub + return false; + } + + @Override + public String getComment() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isWritable() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isSatisfied(Capability capability) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Requirement setFilter(String filter) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement setMultiple(boolean multiple) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement setOptional(boolean optional) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement setExtend(boolean extend) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement setComment(String comment) { + // TODO Auto-generated method stub + return null; + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java new file mode 100644 index 00000000..10f68e53 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java @@ -0,0 +1,21 @@ +package cz.zcu.kiv.crce.webui.internal.custom; + +import cz.zcu.kiv.crce.metadata.Requirement; + +public class RequirementExt extends RequirementsWrap { + + private boolean satisfied; + + public RequirementExt(Requirement r) { + super(r); + satisfied = false; + } + + public void setSatisfied(boolean satisfied) { + this.satisfied = satisfied; + } + + public boolean getSatisfied() { + return satisfied; + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java new file mode 100644 index 00000000..2dec5c03 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java @@ -0,0 +1,42 @@ +package cz.zcu.kiv.crce.webui.internal.custom; + +import cz.zcu.kiv.crce.metadata.Requirement; + +public class RequirementsWrap extends RequirementAdapter { + + protected Requirement requirement; + + public RequirementsWrap(Requirement r) { + this.requirement = r; + } + + @Override + public String getName() { + return requirement.getNamespace(); + } + + @Override + public String getFilter() { + return requirement.getDirective("filter"); // TODO filter is not supported yet + } + + @Override + public boolean isExtend() { + return Boolean.valueOf(requirement.getDirective("extend")); + } + + @Override + public boolean isMultiple() { + return Boolean.valueOf(requirement.getDirective("multiple")); + } + + @Override + public boolean isOptional() { + return Boolean.valueOf(requirement.getDirective("optional")); + } + + @Override + public boolean isWritable() { + return true; + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java new file mode 100644 index 00000000..b7f8f204 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java @@ -0,0 +1,341 @@ +package cz.zcu.kiv.crce.webui.internal.custom; + +import java.net.URI; +import java.net.URL; +import java.util.Map; +import java.util.Set; + +import cz.zcu.kiv.crce.metadata.type.Version; + +import cz.zcu.kiv.crce.webui.internal.legacy.Capability; +import cz.zcu.kiv.crce.webui.internal.legacy.NewProperty; +import cz.zcu.kiv.crce.webui.internal.legacy.Property; +import cz.zcu.kiv.crce.webui.internal.legacy.Requirement; +import cz.zcu.kiv.crce.webui.internal.legacy.Resource; +import cz.zcu.kiv.crce.webui.internal.legacy.Type; + +public class ResourceAdapter implements Resource { + + @Override + public Property[] getProperties() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Property getProperty(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getPropertyString(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(Property property) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, String value, Type type) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, String string) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, Version version) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, URL url) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, URI uri) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, long llong) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, double ddouble) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, Set values) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource unsetProperty(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getId() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getSymbolicName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Version getVersion() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getPresentationName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public URI getUri() { + // TODO Auto-generated method stub + return null; + } + + @Override + public URI getRelativeUri() { + // TODO Auto-generated method stub + return null; + } + + @Override + public NewProperty[] getNewProperties() { + // TODO Auto-generated method stub + return null; + } + + @Override + public long getSize() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public String[] getCategories() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Capability[] getCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Capability[] getCapabilities(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement[] getRequirements() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement[] getRequirements(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map getPropertiesMap() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean hasCategory(String category) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean hasCapability(Capability capability) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean hasRequirement(Requirement requirement) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void setSymbolicName(String name) { + // TODO Auto-generated method stub + + } + + @Override + public void setSymbolicName(String name, boolean isStatic) { + // TODO Auto-generated method stub + + } + + @Override + public void setPresentationName(String name) { + // TODO Auto-generated method stub + + } + + @Override + public void setVersion(Version version) { + // TODO Auto-generated method stub + + } + + @Override + public void setVersion(Version version, boolean isStatic) { + // TODO Auto-generated method stub + + } + + @Override + public void setVersion(String version) { + // TODO Auto-generated method stub + + } + + @Override + public void setVersion(String version, boolean isStatic) { + // TODO Auto-generated method stub + + } + + @Override + public void addCategory(String category) { + // TODO Auto-generated method stub + + } + + @Override + public void addCapability(Capability capability) { + // TODO Auto-generated method stub + + } + + @Override + public void addRequirement(Requirement requirement) { + // TODO Auto-generated method stub + + } + + @Override + public Capability createCapability(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement createRequirement(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void unsetCategory(String category) { + // TODO Auto-generated method stub + + } + + @Override + public void unsetCapability(Capability capability) { + // TODO Auto-generated method stub + + } + + @Override + public void unsetRequirement(Requirement requirement) { + // TODO Auto-generated method stub + + } + + @Override + public void setSize(long size) { + // TODO Auto-generated method stub + + } + + @Override + public void setUri(URI uri) { + // TODO Auto-generated method stub + + } + + @Override + public boolean isWritable() { + // TODO Auto-generated method stub + return false; + } + + @Override + public void unsetWritable() { + // TODO Auto-generated method stub + + } + + @Override + public boolean isVersionStatic() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isSymbolicNameStatic() { + // TODO Auto-generated method stub + return false; + } + + @Override + public String asString() { + // TODO Auto-generated method stub + return null; + } + +// @Override +// public Repository getRepository() { +// // TODO Auto-generated method stub +// return null; +// } +// +// @Override +// public void setRepository(WritableRepository repository) { +// // TODO Auto-generated method stub +// } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java new file mode 100644 index 00000000..8229291b --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java @@ -0,0 +1,45 @@ +package cz.zcu.kiv.crce.webui.internal.custom; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.metadata.service.MetadataService; + +public class ResourceExt extends ResourceWrap { + + private static final Logger logger = LoggerFactory.getLogger(ResourceExt.class); + + private boolean satisfied; + + public ResourceExt(Resource r, MetadataService metadataService) { + super(r, metadataService); + this.satisfied = true; + } + + public boolean getSatisfied() { + return satisfied; + } + + @Override + public void addRequirement(cz.zcu.kiv.crce.webui.internal.legacy.Requirement requirement) { + satisfied = false; + logger.warn("Adding legacy requirements is not supported yet with new Metadata API: {}", requirement); // TODO fix functionality +// resource.unsetRequirement(requirement); +// RequirementExt rext = new RequirementExt(requirement); +// resource.addRequirement(rext); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof cz.zcu.kiv.crce.webui.internal.legacy.Resource) { + return this.getUri().equals(((cz.zcu.kiv.crce.webui.internal.legacy.Resource) obj).getUri()); + } + return super.equals(obj); + } + + @Override + public int hashCode() { + return resource.hashCode(); + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java new file mode 100644 index 00000000..44aa323e --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java @@ -0,0 +1,482 @@ +package cz.zcu.kiv.crce.webui.internal.custom; + +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import javax.annotation.Nonnull; + +import cz.zcu.kiv.crce.metadata.type.Version; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cz.zcu.kiv.crce.metadata.Attribute; +import cz.zcu.kiv.crce.metadata.Capability; +import cz.zcu.kiv.crce.metadata.Requirement; +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiBundle; +import cz.zcu.kiv.crce.metadata.service.MetadataService; +import cz.zcu.kiv.crce.webui.internal.legacy.NewProperty; +import cz.zcu.kiv.crce.webui.internal.legacy.Property; +import cz.zcu.kiv.crce.webui.internal.legacy.Type; + +abstract class ResourceWrap extends ResourceAdapter { + + private static final Logger logger = LoggerFactory.getLogger(ResourceWrap.class); + + protected Resource resource; + private final MetadataService metadataService; + + protected ResourceWrap(Resource r, MetadataService metadataService) { + this.resource = r; + this.metadataService = metadataService; + } + + @Override + public Property[] getProperties() { + Property[] properties; + List crceCapabilities = Collections.singletonList(metadataService.getIdentity(resource)); + + int crceSize = crceCapabilities.isEmpty() ? 0 : crceCapabilities.get(0).getAttributes().size(); + + properties = new Property[crceSize]; + int i = 0; + if (crceSize > 0) { + for (Attribute atr : crceCapabilities.get(0).getAttributes()) { + properties[i++] = new PropertyImpl(atr); + } + } + return properties; + } + + @Override + public NewProperty[] getNewProperties() { + List newProperties = resource.getProperties(); + NewProperty[] properties = new NewProperty[newProperties.size()]; + int i = 0; + for (cz.zcu.kiv.crce.metadata.Property newProperty : newProperties) { + properties[i++] = new NewPropertyImpl(newProperty); + } + return properties; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability[] getCapabilities() { + List capabilities = resource.getCapabilities(); + cz.zcu.kiv.crce.webui.internal.legacy.Capability[] result = new cz.zcu.kiv.crce.webui.internal.legacy.Capability[capabilities.size()]; + int i = 0; + for (Capability capability : capabilities) { + result[i++] = new CapabilityImpl(capability); + } + return result; + } + + @Override + public String[] getCategories() { + return metadataService.getCategories(resource).toArray(new String[0]); + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement[] getRequirements() { + List requirements = resource.getRequirements(); + cz.zcu.kiv.crce.webui.internal.legacy.Requirement[] result = new cz.zcu.kiv.crce.webui.internal.legacy.Requirement[requirements.size()]; + int i = 0; + for (Requirement requirement : requirements) { + result[i++] = new RequirementImpl(requirement); + } + return result; + } + + @Override + public String getSymbolicName() { + String name = "unknown-symbolic-name"; + List capabilities = resource.getCapabilities(NsOsgiBundle.NAMESPACE__OSGI_BUNDLE); + if (!capabilities.isEmpty()) { + name = capabilities.get(0).getAttributeValue(NsOsgiBundle.ATTRIBUTE__SYMBOLIC_NAME); + } + return name; + } + + @Override + public String getId() { + return resource.getId(); + } + + @Override + public Version getVersion() { + Version version = null; + List capabilities = resource.getCapabilities(NsOsgiBundle.NAMESPACE__OSGI_BUNDLE); + if (!capabilities.isEmpty()) { + version = capabilities.get(0).getAttributeValue(NsOsgiBundle.ATTRIBUTE__VERSION); + } + return version; + } + + @Override + public String getPresentationName() { + return metadataService.getPresentationName(resource); + } + + @Override + public URI getUri() { + return metadataService.getUri(resource); + } + + @Override + public URI getRelativeUri() { + return metadataService.getUri(resource); + } + + @Override + public long getSize() { + return metadataService.getSize(resource); + } + + private static class PropertyImpl implements Property { + + private final Attribute attribute; + + public PropertyImpl(Attribute attribute) { + this.attribute = attribute; + } + + @Override + public String getName() { + return attribute.getAttributeType().getName(); + } + + @Override + public Type getType() { + return Type.getValue(attribute.getAttributeType().getType().getSimpleName()); + } + + @Override + public String getValue() { + + Object value = attribute.getValue(); + if (value instanceof Double) { + return String.format("%.3f", value); + } + + return attribute.getStringValue(); + } + + @Override + public Object getConvertedValue() { + return attribute.getValue(); + } + + @Override + public boolean isWritable() { + return true; + } + } + + private static class NewPropertyImpl implements NewProperty { + + private final cz.zcu.kiv.crce.metadata.Property property; + + public NewPropertyImpl(cz.zcu.kiv.crce.metadata.Property property) { + this.property = property; + } + + @Override + public String getName() { + return property.getNamespace(); + } + + @Override + public Property[] getProperties() { + List> attributes = property.getAttributes(); + Property[] properties = new Property[attributes.size()]; + int i = 0; + for (Attribute attribute : attributes) { + properties[i++] = new PropertyImpl(attribute); + } + return properties; + } + + @Override + public Property getProperty(String name) { + Attribute attribute = property.getAttributesMap().get(name); + if (attribute != null) { + return new PropertyImpl(attribute); + } + return null; + } + + @Override + public String getPropertyString(String name) { + Attribute attribute = property.getAttributesMap().get(name); + if (attribute != null) { + return attribute.getStringValue(); + } + return null; + } + + @SuppressWarnings("unchecked") + @Override + public NewProperty setProperty(Property property) { + this.property.setAttribute(property.getName(), (Class) property.getType().getTypeClass(), property.getConvertedValue()); + return this; + } + + @SuppressWarnings("unchecked") + @Override + public NewProperty setProperty(String name, String value, Type type) { + this.property.setAttribute(name, (Class) type.getTypeClass(), Type.propertyValueFromString(type, value)); + return this; + } + + @Override + public NewProperty setProperty(String name, String string) { + this.property.setAttribute(name, String.class, string); + return this; + } + + @Override + public NewProperty setProperty(String name, Version version) { + this.property.setAttribute(name, Version.class, version); + return this; + } + + @Override + public NewProperty setProperty(String name, URL url) { + this.property.setAttribute(name, String.class, url.toString()); + return this; + } + + @Override + public NewProperty setProperty(String name, URI uri) { + this.property.setAttribute(name, String.class, uri.toString()); + return this; + } + + @Override + public NewProperty setProperty(String name, long llong) { + this.property.setAttribute(name, Long.class, llong); + return this; + } + + @Override + public NewProperty setProperty(String name, double ddouble) { + this.property.setAttribute(name, Double.class, ddouble); + return this; + } + + @SuppressWarnings("unchecked") + @Override + public NewProperty setProperty(String name, Set values) { + this.property.setAttribute(name, List.class, new ArrayList<>(values)); + return this; + } + + @Override + public NewProperty unsetProperty(String name) { + this.property.removeAttribute(name); + return this; + } + + } + + private static class CapabilityImpl implements cz.zcu.kiv.crce.webui.internal.legacy.Capability { + + private final Capability capability; + + public CapabilityImpl(Capability capability) { + this.capability = capability; + } + + @Override + public String getName() { + return capability.getNamespace(); + } + + @Override + public NewProperty[] getNewProperties() { + List newProperties = capability.getProperties(); + NewProperty[] properties = new NewProperty[newProperties.size()]; + int i = 0; + for (cz.zcu.kiv.crce.metadata.Property newProperty : newProperties) { + properties[i++] = new NewPropertyImpl(newProperty); + } + return properties; + } + + @Override + public Property[] getProperties() { + List> attributes = capability.getAttributes(); + Property[] properties = new Property[attributes.size()]; + int i = 0; + for (Attribute attribute : attributes) { + properties[i++] = new PropertyImpl(attribute); + } + return properties; + } + + @Override + public Property getProperty(String name) { + Attribute attribute = capability.getAttributesMap().get(name); + if (attribute != null) { + return new PropertyImpl(attribute); + } + return null; + } + + @Override + public String getPropertyString(String name) { + Attribute attribute = capability.getAttributesMap().get(name); + if (attribute != null) { + return attribute.getStringValue(); + } + return null; + } + + @Override + @SuppressWarnings("unchecked") + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(Property property) { + capability.setAttribute(property.getName(), (Class) property.getType().getTypeClass(), property.getConvertedValue()); + return this; + } + + @Override + @SuppressWarnings("unchecked") + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, String value, Type type) { + capability.setAttribute(name, (Class) type.getTypeClass(), Type.propertyValueFromString(type, value)); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, String value) { + capability.setAttribute(name, String.class, value); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, Version version) { + capability.setAttribute(name, Version.class, version); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, URL url) { + capability.setAttribute(name, String.class, url.toString()); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, URI uri) { + capability.setAttribute(name, String.class, uri.toString()); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, long llong) { + capability.setAttribute(name, Long.class, llong); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, double ddouble) { + capability.setAttribute(name, Double.class, ddouble); + return this; + } + + @Override + @SuppressWarnings("unchecked") + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, Set values) { + capability.setAttribute(name, List.class, new ArrayList<>(values)); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability unsetProperty(String name) { + capability.removeAttribute(name); + return this; + } + } + + private static class RequirementImpl implements cz.zcu.kiv.crce.webui.internal.legacy.Requirement { + + private final Requirement requirement; + + public RequirementImpl(@Nonnull Requirement requirement) { + this.requirement = requirement; + } + + @Override + public String getName() { + return requirement.getNamespace(); + } + + @Override + public String getFilter() { + return requirement.getDirective("filter"); + } + + @Override + public boolean isMultiple() { + return Boolean.valueOf(requirement.getDirective("multiple")); + } + + @Override + public boolean isOptional() { + return Boolean.valueOf(requirement.getDirective("optional")); + } + + @Override + public boolean isExtend() { + return Boolean.valueOf(requirement.getDirective("extend")); + } + + @Override + public String getComment() { + return requirement.getDirective("comment"); + } + + @Override + public boolean isWritable() { + return true; + } + + @Override + public boolean isSatisfied(cz.zcu.kiv.crce.webui.internal.legacy.Capability capability) { + logger.warn("Method isSatisfied is not supported by new Metadata API, returning false for Capability: {}, Requirement: {}", capability, requirement); + return false; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setFilter(String filter) { + requirement.setDirective("filter", filter); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setMultiple(boolean multiple) { + requirement.setDirective("multiple", String.valueOf(multiple)); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setOptional(boolean optional) { + requirement.setDirective("optional", String.valueOf(optional)); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setExtend(boolean extend) { + requirement.setDirective("extend", String.valueOf(extend)); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setComment(String comment) { + requirement.setDirective("comment", String.valueOf(comment)); + return this; + } + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/filter/CompatibilityAvailabilityFilter.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/filter/CompatibilityAvailabilityFilter.java new file mode 100644 index 00000000..c3ac82aa --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/filter/CompatibilityAvailabilityFilter.java @@ -0,0 +1,39 @@ +package cz.zcu.kiv.crce.webui.internal.filter; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import cz.zcu.kiv.crce.webui.internal.Activator; + +/** + * This filter checks for CompatibilityService presence + * and sets hasCompatInfo attribute for the request accordingly. + * + * Date: 25.3.15 + * + * @author Jakub Danek + */ +public class CompatibilityAvailabilityFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + request.setAttribute("hasCompatInfo", Activator.instance().isCompatibilityServicePresent()); + chain.doFilter(request, response); + } + + @Override + public void destroy() { + + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Capability.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Capability.java new file mode 100644 index 00000000..67004a9f --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Capability.java @@ -0,0 +1,13 @@ +package cz.zcu.kiv.crce.webui.internal.legacy; + +/** + * Represents an OBR Capability. + * + * @author Jiri Kucera (jiri.kucera@kalwi.eu) + */ +public interface Capability extends PropertyProvider { + + String getName(); + + NewProperty[] getNewProperties(); +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java new file mode 100644 index 00000000..c989b1d2 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java @@ -0,0 +1,13 @@ +package cz.zcu.kiv.crce.webui.internal.legacy; + +/** + * A property that can be set to a Resource or a Capability. + * + * This Property corresponds to cz.zcu.kiv.crce.metadata.Property + * + * @author Jan Smajcl (smajcl@students.zcu.cz) + */ +public interface NewProperty extends PropertyProvider { + + String getName(); +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Property.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Property.java new file mode 100644 index 00000000..44f96394 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Property.java @@ -0,0 +1,36 @@ +package cz.zcu.kiv.crce.webui.internal.legacy; + +/** + * A property that can be set to a Resource or a Capability. + * + * @author Jiri Kucera (jiri.kucera@kalwi.eu) + */ +public interface Property { + + String getName(); + + Type getType(); + + String getValue(); + + Object getConvertedValue(); + + boolean isWritable(); + +// void setValue(String value, Type type); +// +// void setValue(String string); +// +// void setValue(Version version); +// +// void setValue(URL url); +// +// void setValue(URI uri); +// +// void setValue(long llong); +// +// void setValue(double ddouble); +// +// void setValue(Set values); + +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/PropertyProvider.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/PropertyProvider.java new file mode 100644 index 00000000..64df3c52 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/PropertyProvider.java @@ -0,0 +1,41 @@ +package cz.zcu.kiv.crce.webui.internal.legacy; + +import java.net.URI; +import java.net.URL; +import java.util.Set; +import cz.zcu.kiv.crce.metadata.type.Version; + +/** + * Common interface for subclasses that can provide Properties. + * + * @author Jiri Kucera (jiri.kucera@kalwi.eu) + * @param + */ +public interface PropertyProvider> { + + Property[] getProperties(); + + Property getProperty(String name); + + String getPropertyString(String name); + + T setProperty(Property property); + + T setProperty(String name, String value, Type type); + + T setProperty(String name, String string); + + T setProperty(String name, Version version); + + T setProperty(String name, URL url); + + T setProperty(String name, URI uri); + + T setProperty(String name, long llong); + + T setProperty(String name, double ddouble); + + T setProperty(String name, Set values); + + T unsetProperty(String name); +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Requirement.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Requirement.java new file mode 100644 index 00000000..88ab5470 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Requirement.java @@ -0,0 +1,36 @@ +package cz.zcu.kiv.crce.webui.internal.legacy; + +/** + * Represents a requirement to a capability with the same name. + * + * @author Jiri Kucera (jiri.kucera@kalwi.eu) + */ +public interface Requirement { + + String getName(); + + String getFilter(); + + boolean isMultiple(); + + boolean isOptional(); + + boolean isExtend(); + + String getComment(); + + boolean isWritable(); + + boolean isSatisfied(Capability capability); + + Requirement setFilter(String filter); + + Requirement setMultiple(boolean multiple); + + Requirement setOptional(boolean optional); + + Requirement setExtend(boolean extend); + + Requirement setComment(String comment); + +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Resource.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Resource.java new file mode 100644 index 00000000..7217ea2d --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Resource.java @@ -0,0 +1,122 @@ +package cz.zcu.kiv.crce.webui.internal.legacy; + +import java.net.URI; +import java.util.Map; +import cz.zcu.kiv.crce.metadata.type.Version; + +/** + * Resource represents an artifact and it's OBR metadata. + * + *

An unique identificator of a resource is it's symbolic name and version. + * + *

Resource have capabilities, requirements, properties and categories. + * + * @author Jiri Kucera (jiri.kucera@kalwi.eu) + */ +public interface Resource extends PropertyProvider { + + String getId(); + + String getSymbolicName(); + + Version getVersion(); + + String getPresentationName(); + + URI getUri(); + + URI getRelativeUri(); + +// Repository getRepository(); + + NewProperty[] getNewProperties(); + + /** + * Returns the resource size in bytes or -1 if size is unknown. + * @return the resource size. + */ + long getSize(); + + String[] getCategories(); + + Capability[] getCapabilities(); + + Capability[] getCapabilities(String name); + + Requirement[] getRequirements(); + + Requirement[] getRequirements(String name); + + Map getPropertiesMap(); + + boolean hasCategory(String category); + + boolean hasCapability(Capability capability); + + boolean hasRequirement(Requirement requirement); + + /* --- setters --- */ + + void setSymbolicName(String name); + + void setSymbolicName(String name, boolean isStatic); + + void setPresentationName(String name); + + void setVersion(Version version); + + void setVersion(Version version, boolean isStatic); + + void setVersion(String version); + + void setVersion(String version, boolean isStatic); + + void addCategory(String category); + + void addCapability(Capability capability); + + void addRequirement(Requirement requirement); + + Capability createCapability(String name); + + Requirement createRequirement(String name); + + void unsetCategory(String category); + + void unsetCapability(Capability capability); + + void unsetRequirement(Requirement requirement); + + + /** + * Sets resource size. + * @param size size in bytes to set. + */ + void setSize(long size); + + void setUri(URI uri); + +// void setRepository(WritableRepository repository); + + boolean isWritable(); + + void unsetWritable(); + + /** + * Tells whether or not the version of this resource is hard-coded in + * artifact's binary data (e.g. in bundle manifest). + * @return true if the version is hard-coded and can not be + * changed. + */ + boolean isVersionStatic(); + + /** + * Tells whether or not the symbolic name of this resource is hard-coded in + * artifact's binary data (e.g. in bundle manifest). + * @return true if the symbolic name is hard-coded and can not + * be changed. + */ + boolean isSymbolicNameStatic(); + + String asString(); +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Type.java b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Type.java new file mode 100644 index 00000000..c728d2c9 --- /dev/null +++ b/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Type.java @@ -0,0 +1,79 @@ +package cz.zcu.kiv.crce.webui.internal.legacy; + +import java.util.Arrays; +import java.util.List; + +import cz.zcu.kiv.crce.metadata.type.Version; + +/** + * This enumeration indicates the type of Properties. + * + * @author Jiri Kucera (jiri.kucera@kalwi.eu) + */ +public enum Type { + + STRING("string", String.class), + VERSION("version", Version.class), + LONG("long", Long.class), + DOUBLE("double", Double.class), +// URL("url", String.class), + URI("uri", String.class), // TODO URI is not supported type yet (PENDING) +// SET("set", List.class); + LIST("list", List.class), + BOOLEAN("boolean", Boolean.class); + + private final String string; + private final Class clazz; + + Type(String string, Class clazz) { + this.string = string; + this.clazz = clazz; + } + + @Override + public String toString() { + return string; + } + + public Class getTypeClass() { + return clazz; + } + + /** + * Returns Type for given string value. + * @param value + * @return + */ + public static Type getValue(String value) { + if (value != null) { + return valueOf(value.toUpperCase()); + } + return STRING; + } + + public static Object propertyValueFromString(Type type, String value) { + if (value == null) { + return null; + } + + switch (type) { + case DOUBLE: + return Double.valueOf(value); + + case LIST: + return Arrays.asList(value.split(",")); + + case LONG: + return Long.valueOf(value); + + case STRING: + return String.valueOf(type); + + case VERSION: + return new Version(value); + + default: + return null; + } + } +} diff --git a/modules/crce-webui/src/main/webapp/META-INF/MANIFEST.MF b/modules/crce-webui/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 00000000..254272e1 --- /dev/null +++ b/modules/crce-webui/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/modules/crce-webui/src/main/webapp/WEB-INF/web.xml b/modules/crce-webui/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..cafe9f52 --- /dev/null +++ b/modules/crce-webui/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,89 @@ + + + + + + + + index.jsp + + + + + cz.zcu.kiv.crce.webui.internal.SessionListener + + + + + CompatInfoCheckFilter + cz.zcu.kiv.crce.webui.internal.filter.CompatibilityAvailabilityFilter + + + + CompatInfoCheckFilter + /* + + + + + + download + cz.zcu.kiv.crce.webui.internal.DownloadServlet + + + download + /download + + + + check + cz.zcu.kiv.crce.webui.internal.CheckServlet + + + check + /check + + + + test + cz.zcu.kiv.crce.webui.internal.RuntimeServlet + + + test + /test + + + + resource + cz.zcu.kiv.crce.webui.internal.ResourceServlet + + + resource + /resource + + + + edit + cz.zcu.kiv.crce.webui.internal.EditServlet + + + edit + /edit + + + + UploadServlet + cz.zcu.kiv.crce.webui.internal.UploadServlet + + + UploadServlet + /upload + + + + org.apache.commons.fileupload.servlet.FileCleanerCleanup + + + diff --git a/modules/crce-webui/src/main/webapp/crce.png b/modules/crce-webui/src/main/webapp/crce.png new file mode 100644 index 0000000000000000000000000000000000000000..5a37614626349e47e3131c19b088758be6fb7cb7 GIT binary patch literal 1334 zcmV-61Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf02y>eSaefwW^{L9 za%BKPWN%_+AW3auXJt}lVPtu6$z?nM00gE9N z1Zk$WvtD!{NT`oBGd-|1&(Ml$oOX}CnVMlNYsl8Xjq2Gv*!`~bGv~+bHDY~rd`i$W zO=S$+1NQD51{+2X)DwemrrtYW)Sxq0tM%raKh$YG%4VdYt)$h8^I&U**}SJzksz_pN=qg{I>i+&g-Q z;dId0aX0U{tGmAfzzos(W89g&8MilAA3H}iXEKOtJu_8J39IX%{nk|IJb4Y=iUu=*BM9?b+ zs-h-u_&Rt=4Z8K^(F?x%d9#8czW0+)4Z1gg8laaPc3vgE+a_T7#T+{R&uDZvsst5< zlv%ej->CO*b9!V)w}jnNdu4Pcyvz&0vX+IJrM5HQM}ocqLjWT+mHEisqrhYpBWB%HAB_(j7Bng(^kz-H9aG~)HkDD&7+V; zb+i4??mzP9Jzhz7ct_tMR4`RRgC`WDUA@Ztp{{&4ezc%JJ&evnKrfCbJ$l#no`*6) z>!?BB!=7nwTPt(DJFrm=$gbX%ZXbu3DW2#_By3aAKFC7>O>>SUygN7o+&3(`N{aZhpAwEzGB07*qoM6N<$g5%+WN&o-= literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/css/styl.css b/modules/crce-webui/src/main/webapp/css/styl.css new file mode 100644 index 00000000..c19c4c94 --- /dev/null +++ b/modules/crce-webui/src/main/webapp/css/styl.css @@ -0,0 +1,612 @@ +/* CSS Document */ + +body { + margin: 0 auto; + text-align: center; + font-family: Verdana; +} + +img { + border: 0; +} + +a { + color: #666; +} + +a:hover { + color: #BBB; +} + +p { + padding: 0 0 5px 15px; +} + +h2 { + color: #464A47; + padding: 0 0 0 10px; + font-size: 1.1em; + font-weight: bold; +} + +h3 { + padding: 0 0 0 15px; + font-size: 0.9em; + font-weight: normal; + color: #464A47; +} + +.konec { + clear: both; + width: 0; + visibility: hidden; + height: 0; + font-size: 0; + display: block; +} + +#stranka { + width: 902px; + margin: 0 auto; + margin-top: 20px; + border: 1px solid #AAA; +} + +/*--------------------HLAVICKA----------------------------------------*/ + +#hlavicka { + /*border: 1px solid black;*/ + width: 100%; + background: url('../graphic/hlavicka_bg.png') no-repeat; + text-align: left; + padding: 26px 0px; +} + +#hlavicka .loga_h { + height: 90px; + background: url('../graphic/hlavicka_loga.png') no-repeat; +} + +#hlavicka .logo_img { + float: left; + width: 600px; + color: red; + /*border: 1px solid black;*/ + margin: 10px 0px 0px 12px; +} + +#hlavicka .nazev { + float: left; + width: 600px; + color: #666; + font-weight: bold; + font-size: 1.6em; + /*border: 1px solid black;*/ + margin: 5px 0px 5px 12px; +} + +#hlavicka .vyhledavani { + float: right; + width: 250px; + text-align: right; + border: 1px solid black; + margin: 10px 15px 0 0; +} + +#hlavicka .vyhledavani .text { + width: 150px; + color: #222; + background-color: #EEE; + border: 1px solid #AAA; +} + +#hlavicka .vyhledavani .tlacitko { + width: 55px; + background-color: #666; + border: 1px solid #AAA; + color: #FFF; + font-weight: bold; +} + +#hlavicka .vyhledavani .tlacitko:hover { + color: #222; + background-color: #BBB; + border: 1px solid #AAA; +} + +/*--------------------MENU----------------------------------------*/ + +#menu .vyhledavani_h { + float: right; + width: 450px; + height: 24px; + /*line-height: 20px;*/ + text-align: right; + margin-right: 6px; + +} + +#menu .vyhledavani_h .text { + width: 150px; + height: 16px; + color: #565c59; + background-color: white; + border: 1px solid black; + margin-top: 2px; + +} + +#menu .vyhledavani_h .tlacitko { + width: 25px; + height: 18px; + background-color: #eeeee5; + color: black; + font-family: Verdana; + font-weight: normal; + line-height: 16px; + font-size: 8pt; +} + +#menu .vyhledavani_h .repository_selection { + width: 250px; +} + +#menu { + background: url('../graphic/menu_bg.png') repeat-x; + height: 24px; + +} + +#menu ul { + padding: 0px; + margin: 0px; + float: left; +} + +#menu li { + display: inline; + list-style: none; + padding: 0px 10px; +} + +#menu li a:link, +#menu li a:visited, +#menu li a:active, +#menu li a:hover { + + text-decoration: none; + color: white; + font-weight: bold; + font-size: 0.7em; +} + +#menu li a:hover { + text-decoration: underline; +} + +#menu li a.aktivni { + color: #c0c0a0; +} + +/* Vycisteni menu */ +.vycisteni:after { + display: block; + clear: both; + visibility: hidden; + height: 0; + font-size: 0; + content: ' '; +} + +.vycisteni { + min-height: 1px; +} + +.vycisteni { + display: inline-block; +} + +/* Backslash hack - nemel by to videt IE/Mac \*/ +.vycisteni { + display: block; +} + +/* Konec hacku */ + +/*-------------------------ZPRAVA USPECH NEUSPECH---------------------------------*/ +#zprava { + color: #FFF; + text-align: center; + width: 100%; + margin: 0 auto; + padding: 3px 0px; + font-weight: bold; + font-size: 0.7em; +} + +.uspech { + background-color: #b2c980; +} + +.neuspech { + background-color: #f86965; +} + +/*--------------------TELO----------------------------------------*/ +#telo { + width: 100%; + padding: 10px 0 10px 0; + text-align: left; + margin: 0 auto; + background-color: #EEEEE5; +} + +.pridat { + width: 880px; + margin: 0 auto; + padding: 10px 0 10px 0; +} + +.komponenta { + width: 880px; + margin: 0 auto; + border: 1px solid #AAA; + overflow: hidden; +} + +.komponenta div.nadpis { + /*border: 1px solid black;*/ + background: url('../graphic/heading-bg.png') repeat-x; + height: 21px; + line-height: 21px; + padding: 0px 10px 0px 10px; + font-weight: bold; + font-size: 0.7em; +} + +.komponenta .nadpis .popis { + width: 740px; + height: 21px; + line-height: 21px; + float: left; + border: 0px solid black; +} + +.komponenta .nadpis .popis a { + width: 100%; + /*padding: 0 0 0 10px;*/ + text-decoration: none; + + /*color: #222;*/ + /*border: 1px solid black;*/ +} + +.komponenta .nadpis .popis a:hover { + text-decoration: underline; +} + +.komponenta .nadpis:hover { + /*background-color: #777;*/ +} + +.komponenta .nadpis .popis .sName { + color: #7b847c; + font-style: italic; + margin-left: 10px; + font-size: 0.9em; +} + +.komponenta .nadpis .popis .version { + color: #464a47; + margin-left: 10px; +} + +.komponenta .nadpis .popis .version_obsah { + color: #7b847c; +} + +.komponenta .nadpis .popis .pName { + color: #464a47; + +} + +.komponenta .nadpis .popis .category { + color: #464a47; +} + +.komponenta .nadpis .popis .category_obsah { + color: #7b847c; +} + +.komponenta .nadpis .nabidka { + float: right; + text-align: right; + margin: 2px 0 0 0; + border: 0px solid black; + width: 120px; + height: 19px; + line-height: 19px; +} + +.komponenta .informace { + /*border: 1px solid black;*/ + /*background-color: #EEE;*/ + padding: 5px 10px 5px 10px; + font-size: 0.8em; +} + +.komponenta .polozka { + color: #464a47; + padding-bottom: 10px; +} + +.komponenta .polozka li { + font-size: 0.9em; +} + +.komponenta a.edit, +.edit-addnew { + text-decoration: underline; + font-size: 0.8em; + color: #464a47; +} + +.komponenta a.edit:hover, +.edit-addnew { + text-decoration: none; +} + +.komponenta .polozka .inline { + margin-bottom: 10px; +} + +.komponenta .polozka .inline li { + float: left; + padding-left: 5px; + list-style: none; +} + +.vsechnykategorie { + /*float:left;*/ + margin-bottom: 20px; +} + +.kategorie { + width: 100px; + margin: 5px 2px 2px 2px; + border: 1px solid #AAA; + overflow: hidden; + height: 21px; + line-height: 21px; + padding: 0px 10px 0px 10px; + font-weight: bold; + font-size: 0.7em; +} + +.komponenty .komponenta { + /*width: 760px;*/ +} + +.komponenty .komponenta .nadpis .popis { + /*width: 640px;*/ +} + +/*--------------------POSKYTUJE-------------------------*/ + +.poskytuje { + padding: 5px; + width: 100%; + margin: 0 auto; + +} + +.poskytuje th { + text-align: left; + font-weight: bold; + +} + +.poskytuje .text { + width: 98%; +} + +.poskytuje .jmeno { + +} + +.poskytuje .typ { + width: 90px; +} + +.poskytuje .hodnota { + max-width: 580px; + width: 580px; +} + +/*-------------------------VYZADUJE------------------------------*/ +.vyzaduje { + padding: 10px; + width: 100%; + margin: 0 auto; + font-size: 0.9em; +} + +.komponenta .vyzaduje { + padding: 0px; + width: 830px; +} + +.vyzaduje input { + width: 98%; + margin: 0 auto; +} + +.vyzaduje th { + text-align: left; + font-weight: bold; + /*background: #f5f5f1;*/ +} + +.vyzaduje .text { + width: 98%; + margin: 0 auto; +} + +.vyzaduje .tlacitko { + width: 150px; +} + +.vyzaduje .komentar { + width: 98%; + padding: 0 0 10px 0; + font-size: 0.9em; + font-style: italic; +} + +.vyzaduje .jmeno { + width: 100px; +} + +.vyzaduje .filter { + width: 600px; +} + +.vyzaduje td.req-neuspech { + color: #f86965; +} + +/*---------------ANIMACNI_ODKAZY---------------------------------------*/ +#animacni_odkazy { + width: 880px; + margin: 0 auto; + font-size: 0.8em; + padding-top: 5px; + text-align: right; + border: 0px solid black; + +} + +/*--------------------PATICKA----------------------------------------*/ +#paticka { + padding-top: 3px; + width: 904px; + font-size: 0.6em; + margin: 0 auto; + /*border: 1px solid black;*/ + background-color: #EEE; + color: #333; +} + +/*-------------TLACITKO----------------------------------------------*/ + +.tlacitko { + text-align: center; + /*background-color: #666;*/ + background: #ddddca; + /*border: 1px solid #AAA;*/ + border: 1px solid #c8b8b5; + color: #000; + font-size: 0.8em; + +} + +.tlacitko:hover { + /*color: #222;*/ + background-color: #FFF; +} + +div.tlac { + float: left; + margin-right: 5px; +} + +/*----------------UPLOAD---------------------------------------------*/ + +div.upload { + background-color: #999; + margin-bottom: 10px; + padding: 5px; +} + +table.upload { + + /*width: 880px;*/ + /*margin: 0 auto;*/ + +} + +.upload td { + text-align: left; + width: 100%; +} + +.upload .text { + width: 400px; + color: #222; + background-color: #FFF; + border: 1px solid #AAA; +} + +.upload .tlacitko { + /*width: 200px;*/ + font-size: 0.8em; +} + +/*--------------------FORMULAR----------------------------------------*/ + +.formular { + padding: 10px; + width: 100%; + text-align: left; + +} + +.formular th { + font-weight: bold; + font-size: 0.8em; + color: #464a47; +} + +.formular td { + text-align: left; + margin: 0 auto; +} + +.formular .text { + width: 500px; + color: #222; + background-color: #FFF; + border: 1px solid #AAA; +} + +.formular .chyba { + color: red; + font-weight: bold; + padding: 0 10px 0 10px; +} + +.formular .tlacitko { + margin: 10px 0 0 0; +} + +.formy th { + font-size: 0.8em; + color: #464a47; +} + +.categorie-edit-ul li { + font-size: 0.8em; + color: #464a47; + +} + +/*-----------------EXECUTE_COMMIT-------------------------*/ + +.execute_commit .tlacitko { + margin: 0 0 10px 10px; +} + +/*------------------COMPATIBILITY-------------------------*/ +.pivot { + background-color: #FCFC55; +} \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/graphic/add.png b/modules/crce-webui/src/main/webapp/graphic/add.png new file mode 100644 index 0000000000000000000000000000000000000000..6332fefea4be19eeadf211b0b202b272e8564898 GIT binary patch literal 733 zcmV<30wVp1P)9VHk(~TedF+gQSL8D5xnVSSWAVY>J9b+m>@{iq7_KE}go~11+5s4;8hc+i0Xa zI1j@EX5!S+Me6HNqKzU5YQwL;-W5$p%ZMKMeR<%zp69-~?<4?8|C8S?bklXr4v&Ov zb&06v2|-x?qB`90yn>Qi%Sh2^G4n)$ZdyvTPf9}1)_buUT7>`e2G&2VU@~Bb(o+Mz zi4)>IxlSY${Dj4k={-9RzU^W5g9|2V5RZ2ZulL9s2xQbZ@r6eP9Ra5u(s|C0Nj#&4>wTSkb?%#=9?@ z^oxDy-O@tyN{L@by(WWvQ3%CyEu8x{+#Jb4-h&K9Owi)2pgg+heWDyked|3R$$kL@A z#sp1v-r+=G4B8D6DqsDH0@7OztA7aT9qc1Py{()w`m``?Y0&gi2=ROcc-9+nU^I6< zT=e_Y=vSnG@?3Ue{BW5ONFttcE!R-R_W4O01|0-|K-YNXLo2`4Qv z`r1LxR6#yf3FB%T95gJnaKKivA~Z}S9A(ZxEDK}O3T04USJ P00000NkvXXu0mjf^IS-S literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/check.png b/modules/crce-webui/src/main/webapp/graphic/check.png new file mode 100644 index 0000000000000000000000000000000000000000..cec81d14814bbd9d7122a1bc06a246243c9b3517 GIT binary patch literal 1388 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl4m>B|mLR|m<|F2U$5M-ZS}_O#kK7f z&3zYdK7R20?d-*CR;<~u@93FJx1SbNw@;X}^6%e23zo0bvvk>YxFQ>A_$u~SLxBT(**Bw(AZrgM4?&B9n&t7Zjoq6ZsljNK-4P(2a z+Rn>YZ|ppD^48r)0kP?>{*lubtZeR|=^K^+bT-fKy3kEu@tU3@DNPv~q)_{S*07To` z0tKukSvWbx#5g%wB&|RK7Ah><+zhg^4BXr-D(pZ3b`~{dMFCM!0Yzms7Lb4~I~SLN zy1cx)0v8uMP>YC(hN+p1B?E(vjG3v1i3o!<1A~%2sH|dO)>mQxa{2lAB=jHxdJ=qm z{0yqb9BjI5KoMpj#bK-pG?ar$+>ni#naxm~i38*gMkZ}0IddT)b2%V`5hNhU#LL9X z!viFk1VI9}jKWNsMm#)5noPosV87ThGTLfMNoj#-hyajc1Ogxh1X_Z!9of;-?t@(B M>FVdQ&MBb@0H?mEU;qFB literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/commit.png b/modules/crce-webui/src/main/webapp/graphic/commit.png new file mode 100644 index 0000000000000000000000000000000000000000..526a654a3bd7a84c4bd02113e1c55707ad063ef9 GIT binary patch literal 891 zcmbVKO-NKx6h7zP>w9nhoN-3U)G5hPByeldCJG}B60xX^7Vc`15!9k(v}>2!Xc+}9 zVyFaXs}gS7Bt}^Zl0`|Q`STp#&poI6W`x;yIQM*a@twc>-Nz%t=Tq^vH~^%E1_wqB zW}@Q=6Q4}p>NjBBA057A(Ab?9_N0N>-NCVY0Et|55S~731(5AS17|KjSi+3l46({S z2r3TAJY>7U$$^kqDf8AcY_Ed9Q)kr^>@0MRK(1ifNd*ju$iRW8HY5- zO8)lM{KU!T!P-3^FBtawz0%y~bPxh7VOCZY!oEiifv}NfB&9ziO>MuN{Zk5d zqiHKXldis!>Om`GQs65ub~=TO%+}a5ZfSbG=(|jWnsK*W+5gCrec%|#f&fykw>R(4 z_9pt8WVZPC)zt5zzsu&KwRtxP+(qA8;7A851N5PcD-KZy@R>iY_{($UnZPBZ2{ULx zuD4$)YOWX+swO&6U6jcqNfk=g5V4FQnvqFrcij!%Y5mPiUERR|?*M)0Fh^k%u`Prn z*%E=$74j-Sz2Hqqs|PC8KVMYR=za*{xPS~sy|)>@Fs~7qp8st(#}gmcuHjNtVCdZN K!0WT)kNyFp5+VHn literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/crce.png b/modules/crce-webui/src/main/webapp/graphic/crce.png new file mode 100644 index 0000000000000000000000000000000000000000..5a37614626349e47e3131c19b088758be6fb7cb7 GIT binary patch literal 1334 zcmV-61Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf02y>eSaefwW^{L9 za%BKPWN%_+AW3auXJt}lVPtu6$z?nM00gE9N z1Zk$WvtD!{NT`oBGd-|1&(Ml$oOX}CnVMlNYsl8Xjq2Gv*!`~bGv~+bHDY~rd`i$W zO=S$+1NQD51{+2X)DwemrrtYW)Sxq0tM%raKh$YG%4VdYt)$h8^I&U**}SJzksz_pN=qg{I>i+&g-Q z;dId0aX0U{tGmAfzzos(W89g&8MilAA3H}iXEKOtJu_8J39IX%{nk|IJb4Y=iUu=*BM9?b+ zs-h-u_&Rt=4Z8K^(F?x%d9#8czW0+)4Z1gg8laaPc3vgE+a_T7#T+{R&uDZvsst5< zlv%ej->CO*b9!V)w}jnNdu4Pcyvz&0vX+IJrM5HQM}ocqLjWT+mHEisqrhYpBWB%HAB_(j7Bng(^kz-H9aG~)HkDD&7+V; zb+i4??mzP9Jzhz7ct_tMR4`RRgC`WDUA@Ztp{{&4ezc%JJ&evnKrfCbJ$l#no`*6) z>!?BB!=7nwTPt(DJFrm=$gbX%ZXbu3DW2#_By3aAKFC7>O>>SUygN7o+&3(`N{aZhpAwEzGB07*qoM6N<$g5%+WN&o-= literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/del.png b/modules/crce-webui/src/main/webapp/graphic/del.png new file mode 100644 index 0000000000000000000000000000000000000000..08f249365afd29594b51210c6e21ba253897505d GIT binary patch literal 715 zcmV;+0yO=JP)C4}Mrzlg<+1Y8PEBfUp0jJpx4B>@E+cy3`^(Gw`Mf+2&yxZm<$to~Vpgvg&QKNR z_f#1(r6svZt%iF?s+n<8X?B&!h3g9Dbb8_=MX}!;HiQSAh`bp^WMl~Z-44teO7W_Y zV4thSL{h;rJY7!l3%5J4H1!tIzB`Dv+YxO(haWeausGZYkI8^hWj6mzo=L0{%;yxzh{5!Htr?51 zvG|W62MzC8BZ76hRpCyO2zOn<%e)K>NHge!-~)Ap33OdWw6hsLYbCxGNt0%wk_2z7 zfyYvXheSG)5HRK1VB~%mq7Dmurw#bi@hEcOr3&G1ZiF*$M=&9nB#VNf&Q^r$4G5kp zTURh&s)E0%5&hyVD}sp<72~zmAY`Y(9aqO6CXF%=zFHGzO-A&I(pE}v70YQxCPJ{Y z4L+?5-crdLn3ZRPEs!A4ehEY3ZRpL~w9>@aMN+{F4dI@v&>(QDHQum!mG~E^$OS8l z!7?%Uwib*ROP67Hw`ika)gX-(8Ia`-u_IEhxG7U<13kSsMW+$lbb2dUMm5p6pa}cjgA+U$^mJ^AjD?&bdi)8~y+Q002ovPDHLkV1g8IMc@Dc literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/edit.png b/modules/crce-webui/src/main/webapp/graphic/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..0bfecd50ee9f5bc5828f0c0745aa3e0effcbe250 GIT binary patch literal 450 zcmV;z0X_bSP)Rq1}l<=psl5*5Xz9i;M}s*NP=ugs7Q#8Z;Dyx|}!`#}xw_C3!B-yaPC&0j)XcpuX@rNfq|q}N(wJOjA& z>u+z?dfJEuLePrqzy!)73pvLjxk4d6XNZt?hm_iYES{i}J5y3l?}PPNYDBR7oPc~6 zL^d)Bi4Q2L3pnp!nFxN9c2E+=@XAl&+;2m6a~kZj1r3Mz3C=hmUG<{+vWR@t4q?fJ zhFc(ozZD#Mx`^Q~g1v=K6!QnfuqyD4>U4EjF0eamL}Jx| z%&`kR-H+3GBYr*Qx}frLU4`%n9(`uSomzw)t%%NagXkA*R5Mbv9VLDp1wMo$cOMa~ s3Wm%r7^bwK$2$}-<~D8p`#1iScU4^XCLAA~0ssI207*qoM6N<$g3sK(Qvd(} literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/heading-bg.png b/modules/crce-webui/src/main/webapp/graphic/heading-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..6afae2fedfef36ff5344e29ad25d3ac33b2cd33c GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{P!2~2Z41|M$6mzkYX9x!e$L)vy4}e_G0*}aI z1_o{+5N5n|x9$&6P^QE+q9iy!t)x7$D3!r6B|j-u!7Z~WwLHHlyI8?F*o1A< zVjy+SMX8A;nfZANA(^?U3lA4tsY e@9Uhv&fvDpZvNDj?B9TD7(8A5T-G@yGywoXVK>15 literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/hlavicka_bg.png b/modules/crce-webui/src/main/webapp/graphic/hlavicka_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..3cef00983338b1656f5f628cee54f87c70e62def GIT binary patch literal 10258 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 b+(!a^?@SU}w3)I0G7CTo8uFF0<{$qbBZQ&~ literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/hlavicka_loga.png b/modules/crce-webui/src/main/webapp/graphic/hlavicka_loga.png new file mode 100644 index 0000000000000000000000000000000000000000..5969e7664142c5ee3b7cb6355c036d2cfe3c0a6a GIT binary patch literal 22199 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

2lDFs2dSX8UkFNzAIeO9Y# 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 literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/logo.png b/modules/crce-webui/src/main/webapp/graphic/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..87567f53eb5556c4f181154d8eb9ccb2af116e29 GIT binary patch literal 18213 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 literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/menu_bg.png b/modules/crce-webui/src/main/webapp/graphic/menu_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..cf2484448f1d1476b5e848851d15abc13e29bedc GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^%s?!`!2~2XL|@nd5-4`^4B_D5xc$)o0g%gC;1OBO zz`!j8!i<;h*8Kqr%9OZ9lmzFem6RtIr7}3C literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/save.png b/modules/crce-webui/src/main/webapp/graphic/save.png new file mode 100644 index 0000000000000000000000000000000000000000..1ae95dcfb28af5adce789c1a5a9bea866e0078df GIT binary patch literal 870 zcmcgp`%9An6g}#UO_T)9G6y^N||U)oipFf)TJgE5*j`hm4!bPfz;>zhUmh*mvgwBb1%0<7#;5Ba@Ylc8=uD! zk==bSsZL});kRE*Hj0WB#R6VT20547NbIfQUe<`yl$tDA1_72LO-|7HDKZryB4mo3 z8&gCG;Gh)>B;4KI-S)l-WKSSt1PKErBeo~=+r_VKNFGAkFqHjJ^&_qu@;=0LAkhR# zCu$d=c!iW92D=s&btx524LY!?(pWR0U{5fQDpK7h!_i0u~WrlA>y zdIXu{D4s>)AnM-ZszGB|tF?TId$@#)&*B~|i7KtSF&l(!h-l6q+)V2Hs5Y!d=w`rf zK+z0tO`&`qSrdq9hx{dOjv?NF&>Dm{A+iNwbqKA(xhhmIfZJGL+Jw%Ed<#;|5VYnQ z*Kd<|{p+Bp>#U@vQX`5M|M?$*!29ieq~mWshb75gmh-qya2VD4!=34R=EqZ-k3f)r zbedk);6f5E$pJc7sd=(|y4;Qnk~0|&si|KVBwENBN{>PsC3i=!cci$pwM`)c=8ANsO`?C2o1>1!LaRA<(^Z+2uJeM6y~Z`41^^Nm*SF%(ZJL8uO{rxb4}@iW0Q8bF0Y@Sy~L{5Cz+JGW98e&EWzG1FMoDyGqZ;) zNj%9!07I?+Zb+w<)SqVjGJbBeZ+5bc!P8!1)A{qqe8}z02paSY_R!tc?ER9@jpjTL HlNS610AX;q literal 0 HcmV?d00001 diff --git a/modules/crce-webui/src/main/webapp/graphic/zoom.png b/modules/crce-webui/src/main/webapp/graphic/zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..908612e394525fc2e52a7e9b94689c25ce167381 GIT binary patch literal 692 zcmV;l0!#ggP)m+BBgry{~j2fHLegbHP( zrgXNbr0}2;^nywdjLjZe?uxtrd3D(pZH@fFFc0{BW_~jxoO1w7-VX;6vK@ROA$$R6 zEmo;Ht-Mj|>5jUy{bQ^V5@53LRI8AgLpUm|m+15sqcz@QtVSo|oz7ArM8?pIn+>gN z0b=4_b5O|4A*;Q+vc9Vqr~%3V155*NV~@gTz}KSUiKB-uJzjMZ>5%Q#n24H!V{ zTY(LLAE*NAHZ}C#wnj%Bw5OFIkRhkkAW#kDC3j9Wm0YXRaXlyyp>#mVfYG)eC;@ab zDb=T-BCAY4LI(Z@GOTr2V_A{pRwSmz+8Be>CjAw(=gnbVWAeguvZa93JmL(EDxv1m z0OP4q=fpAK1Mq!C2`OkEn37o;m#wF#(t(8Pu#S?2f#x<~4EO{@fmm`p9veD6RZ_jp z@Au4};q&`XuKEYgIiB4((kgxOs#YdqJw0fY>9^K_agEu5+$#k;w#%I2N>n_?)YIqu z`tq&#_^p?-%K*U0^}|7+9U(&k0?s;=r=uCZ%)H9_edH8wK}gB(nUB1FFk+2Ol%BXV zHoFY`D~2x|2 + +<%@page import="cz.zcu.kiv.crce.metadata.Attribute"%> +<%@page import="java.util.List"%> +<% + response.sendRedirect("resource"); + %> + +<%@page import="cz.zcu.kiv.crce.plugin.Plugin"%> +<%@page import="cz.zcu.kiv.crce.metadata.Requirement"%> +<%@page import="cz.zcu.kiv.crce.metadata.Property"%> +<%@page import="cz.zcu.kiv.crce.metadata.Capability"%> +<%@page import="cz.zcu.kiv.crce.repository.Buffer"%> +<%@page import="cz.zcu.kiv.crce.webui.internal.Activator"%> +<%@page import="cz.zcu.kiv.crce.metadata.Resource"%> +<%@page contentType="text/html" pageEncoding="UTF-8"%> + + + + + KIV CRCE + + + +

+ +
+ +

Store bundle:

+ +
+
+ +
+ <% + String success = request.getParameter("success"); + if ("true".equals(success)) { + out.println("

Upload successful

"); + } + if ("false".equals(success)) { + out.println("

Upload failed

"); + } + %> + +

Plugins in plugin manager:

+ <% + List plugins = Activator.instance().getPluginManager().getPlugins(); + out.println(""); + out.println(""); + for (Plugin plugin : plugins) { + out.println(""); + out.println(""); + out.println(""); + } + out.println("
IDprioritydescription
" + plugin.getPluginId() + "" + plugin.getPluginPriority() + "" + plugin.getPluginDescription() + "
"); + %> + +

Resources in buffer

+ + <% + + + Buffer buffer = Activator.instance().getBuffer(request); + for (Resource res : buffer.getResources()) { + out.println("

" + res.getId() + "

"); + + out.println(""); + out.println(""); + out.println(""); + out.println(""); + out.print(""); + out.println("
Presentation name:" + Activator.instance().getMetadataService().getPresentationName(res) + "
Size:" + Activator.instance().getMetadataService().getSize(res) + "
URI:" + Activator.instance().getMetadataService().getUri(res).normalize() + "
Categories:"); + boolean first = true; + for (String category : Activator.instance().getMetadataService().getCategories(res)) { + if (first) { + first = false; + } else { + out.print(", "); + } + out.print(category); + } + out.println("
"); + + /* + out.println("

Properties

"); + out.println("
"); + out.println(""); + out.println(""); + for (Property prop : res.getProperties()) { + out.println(""); + } + out.println("
typenamevalue
" + prop.getType() + "" + prop.getName() + "" + prop.getValue() + "
"); + out.println("
"); + */ + + out.println("

Capabilities

"); + + out.println(""); + + out.println(""); + + for (Capability cap : res.getCapabilities()) { + out.println(""); + out.println(""); + + out.println(""); + out.println(""); + } + + out.println("
NameProperties
" + cap.getNamespace()+ ""); + out.println(""); + out.println(""); + for (Attribute attr : cap.getAttributes()) { + out.println(""); + } + out.println("
typenamevalue
" + attr.getAttributeType().getType() + + "" + attr.getAttributeType().getName() + "" + attr.getValue() + "
"); + out.println("
"); + + + out.println("

Requirements

"); + out.println(""); + out.println(""); + for (Requirement req : res.getRequirements()) { + out.println("" + + "" + + "" + + "" + + ""); + } + out.println("
NameFilterOptionalMultipleExtended
" + req.getNamespace()+ "" + req.getDirective("filter") + "" + (Boolean.getBoolean(req.getDirective("optional")) ? "Y" : "N") + "" + (Boolean.getBoolean(req.getDirective("multiple")) ? "Y" : "N") + "" + (Boolean.getBoolean(req.getDirective("extend")) ? "Y" : "N") + "
"); + + out.println("
"); + } + + + %> + +
+ + diff --git a/modules/crce-webui/src/main/webapp/js/jquery-1.5.1.js b/modules/crce-webui/src/main/webapp/js/jquery-1.5.1.js new file mode 100644 index 00000000..78fcfa46 --- /dev/null +++ b/modules/crce-webui/src/main/webapp/js/jquery-1.5.1.js @@ -0,0 +1,8316 @@ +/*! + * jQuery JavaScript Library v1.5.1 + * http://jquery.com/ + * + * Copyright 2011, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Wed Feb 23 13:55:29 2011 -0500 + */ +(function( window, undefined ) { + +// Use the correct document accordingly with window argument (sandbox) +var document = window.document; +var jQuery = (function() { + +// Define a local copy of jQuery +var jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // A central reference to the root jQuery(document) + rootjQuery, + + // A simple way to check for HTML strings or ID strings + // (both of which we optimize for) + quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/, + + // Check if a string has a non-whitespace character in it + rnotwhite = /\S/, + + // Used for trimming whitespace + trimLeft = /^\s+/, + trimRight = /\s+$/, + + // Check for digits + rdigit = /\d/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, + rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + + // Useragent RegExp + rwebkit = /(webkit)[ \/]([\w.]+)/, + ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, + rmsie = /(msie) ([\w.]+)/, + rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + + // Keep a UserAgent string for use with jQuery.browser + userAgent = navigator.userAgent, + + // For matching the engine and version of the browser + browserMatch, + + // Has the ready events already been bound? + readyBound = false, + + // The deferred used on DOM ready + readyList, + + // Promise methods + promiseMethods = "then done fail isResolved isRejected promise".split( " " ), + + // The ready event handler + DOMContentLoaded, + + // Save a reference to some core methods + toString = Object.prototype.toString, + hasOwn = Object.prototype.hasOwnProperty, + push = Array.prototype.push, + slice = Array.prototype.slice, + trim = String.prototype.trim, + indexOf = Array.prototype.indexOf, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), or $(undefined) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context && document.body ) { + this.context = document; + this[0] = document.body; + this.selector = "body"; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + match = quickExpr.exec( selector ); + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = (context ? context.ownerDocument || context : document); + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); + + if ( ret ) { + if ( jQuery.isPlainObject( context ) ) { + selector = [ document.createElement( ret[1] ) ]; + jQuery.fn.attr.call( selector, context, true ); + + } else { + selector = [ doc.createElement( ret[1] ) ]; + } + + } else { + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); + selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; + } + + return jQuery.merge( this, selector ); + + // HANDLE: $("#id") + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return (context || rootjQuery).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if (selector.selector !== undefined) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.5.1", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return slice.call( this, 0 ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = this.constructor(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + (this.selector ? " " : "") + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Attach the listeners + jQuery.bindReady(); + + // Add the callback + readyList.done( fn ); + + return this; + }, + + eq: function( i ) { + return i === -1 ? + this.slice( i ) : + this.slice( i, +i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ), + "slice", slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + window.$ = _$; + + if ( deep ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + // A third-party is pushing the ready event forwards + if ( wait === true ) { + jQuery.readyWait--; + } + + // Make sure that the DOM is not already loaded + if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger( "ready" ).unbind( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyBound ) { + return; + } + + readyBound = true; + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + return setTimeout( jQuery.ready, 1 ); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + document.attachEvent("onreadystatechange", DOMContentLoaded); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e) {} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + } + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + // A crude way of determining if an object is a window + isWindow: function( obj ) { + return obj && typeof obj === "object" && "setInterval" in obj; + }, + + isNaN: function( obj ) { + return obj == null || !rdigit.test( obj ) || isNaN( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + for ( var name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw msg; + }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test(data.replace(rvalidescape, "@") + .replace(rvalidtokens, "]") + .replace(rvalidbraces, "")) ) { + + // Try to use the native JSON parser first + return window.JSON && window.JSON.parse ? + window.JSON.parse( data ) : + (new Function("return " + data))(); + + } else { + jQuery.error( "Invalid JSON: " + data ); + } + }, + + // Cross-browser xml parsing + // (xml & tmp used internally) + parseXML: function( data , xml , tmp ) { + + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + + tmp = xml.documentElement; + + if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) { + jQuery.error( "Invalid XML: " + data ); + } + + return xml; + }, + + noop: function() {}, + + // Evalulates a script in a global context + globalEval: function( data ) { + if ( data && rnotwhite.test(data) ) { + // Inspired by code by Andrea Giammarchi + // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html + var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement, + script = document.createElement( "script" ); + + if ( jQuery.support.scriptEval() ) { + script.appendChild( document.createTextNode( data ) ); + } else { + script.text = data; + } + + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709). + head.insertBefore( script, head.firstChild ); + head.removeChild( script ); + } + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, + length = object.length, + isObj = length === undefined || jQuery.isFunction(object); + + if ( args ) { + if ( isObj ) { + for ( name in object ) { + if ( callback.apply( object[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( object[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in object ) { + if ( callback.call( object[ name ], name, object[ name ] ) === false ) { + break; + } + } + } else { + for ( var value = object[0]; + i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} + } + } + + return object; + }, + + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, + + // results is for internal usage only + makeArray: function( array, results ) { + var ret = results || []; + + if ( array != null ) { + // The window, strings (and functions) also have 'length' + // The extra typeof function check is to prevent crashes + // in Safari 2 (See: #3039) + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + var type = jQuery.type(array); + + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { + push.call( ret, array ); + } else { + jQuery.merge( ret, array ); + } + } + + return ret; + }, + + inArray: function( elem, array ) { + if ( array.indexOf ) { + return array.indexOf( elem ); + } + + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === elem ) { + return i; + } + } + + return -1; + }, + + merge: function( first, second ) { + var i = first.length, + j = 0; + + if ( typeof second.length === "number" ) { + for ( var l = second.length; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var ret = [], retVal; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( var i = 0, length = elems.length; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var ret = [], value; + + // Go through the array, translating each of the items to their + // new value (or values). + for ( var i = 0, length = elems.length; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + proxy: function( fn, proxy, thisObject ) { + if ( arguments.length === 2 ) { + if ( typeof proxy === "string" ) { + thisObject = fn; + fn = thisObject[ proxy ]; + proxy = undefined; + + } else if ( proxy && !jQuery.isFunction( proxy ) ) { + thisObject = proxy; + proxy = undefined; + } + } + + if ( !proxy && fn ) { + proxy = function() { + return fn.apply( thisObject || this, arguments ); + }; + } + + // Set the guid of unique handler to the same of original handler, so it can be removed + if ( fn ) { + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; + } + + // So proxy can be declared as an argument + return proxy; + }, + + // Mutifunctional method to get and set values to a collection + // The value/s can be optionally by executed if its a function + access: function( elems, key, value, exec, fn, pass ) { + var length = elems.length; + + // Setting many attributes + if ( typeof key === "object" ) { + for ( var k in key ) { + jQuery.access( elems, k, key[k], exec, fn, value ); + } + return elems; + } + + // Setting one attribute + if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = !pass && exec && jQuery.isFunction(value); + + for ( var i = 0; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + + return elems; + } + + // Getting an attribute + return length ? fn( elems[0], key ) : undefined; + }, + + now: function() { + return (new Date()).getTime(); + }, + + // Create a simple deferred (one callbacks list) + _Deferred: function() { + var // callbacks list + callbacks = [], + // stored [ context , args ] + fired, + // to avoid firing when already doing so + firing, + // flag to know if the deferred has been cancelled + cancelled, + // the deferred itself + deferred = { + + // done( f1, f2, ...) + done: function() { + if ( !cancelled ) { + var args = arguments, + i, + length, + elem, + type, + _fired; + if ( fired ) { + _fired = fired; + fired = 0; + } + for ( i = 0, length = args.length; i < length; i++ ) { + elem = args[ i ]; + type = jQuery.type( elem ); + if ( type === "array" ) { + deferred.done.apply( deferred, elem ); + } else if ( type === "function" ) { + callbacks.push( elem ); + } + } + if ( _fired ) { + deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] ); + } + } + return this; + }, + + // resolve with given context and args + resolveWith: function( context, args ) { + if ( !cancelled && !fired && !firing ) { + firing = 1; + try { + while( callbacks[ 0 ] ) { + callbacks.shift().apply( context, args ); + } + } + // We have to add a catch block for + // IE prior to 8 or else the finally + // block will never get executed + catch (e) { + throw e; + } + finally { + fired = [ context, args ]; + firing = 0; + } + } + return this; + }, + + // resolve with this as context and given arguments + resolve: function() { + deferred.resolveWith( jQuery.isFunction( this.promise ) ? this.promise() : this, arguments ); + return this; + }, + + // Has this deferred been resolved? + isResolved: function() { + return !!( firing || fired ); + }, + + // Cancel + cancel: function() { + cancelled = 1; + callbacks = []; + return this; + } + }; + + return deferred; + }, + + // Full fledged deferred (two callbacks list) + Deferred: function( func ) { + var deferred = jQuery._Deferred(), + failDeferred = jQuery._Deferred(), + promise; + // Add errorDeferred methods, then and promise + jQuery.extend( deferred, { + then: function( doneCallbacks, failCallbacks ) { + deferred.done( doneCallbacks ).fail( failCallbacks ); + return this; + }, + fail: failDeferred.done, + rejectWith: failDeferred.resolveWith, + reject: failDeferred.resolve, + isRejected: failDeferred.isResolved, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + if ( obj == null ) { + if ( promise ) { + return promise; + } + promise = obj = {}; + } + var i = promiseMethods.length; + while( i-- ) { + obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ]; + } + return obj; + } + } ); + // Make sure only one callback list will be used + deferred.done( failDeferred.cancel ).fail( deferred.cancel ); + // Unexpose cancel + delete deferred.cancel; + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + return deferred; + }, + + // Deferred helper + when: function( object ) { + var lastIndex = arguments.length, + deferred = lastIndex <= 1 && object && jQuery.isFunction( object.promise ) ? + object : + jQuery.Deferred(), + promise = deferred.promise(); + + if ( lastIndex > 1 ) { + var array = slice.call( arguments, 0 ), + count = lastIndex, + iCallback = function( index ) { + return function( value ) { + array[ index ] = arguments.length > 1 ? slice.call( arguments, 0 ) : value; + if ( !( --count ) ) { + deferred.resolveWith( promise, array ); + } + }; + }; + while( ( lastIndex-- ) ) { + object = array[ lastIndex ]; + if ( object && jQuery.isFunction( object.promise ) ) { + object.promise().then( iCallback(lastIndex), deferred.reject ); + } else { + --count; + } + } + if ( !count ) { + deferred.resolveWith( promise, array ); + } + } else if ( deferred !== object ) { + deferred.resolve( object ); + } + return promise; + }, + + // Use of jQuery.browser is frowned upon. + // More details: http://docs.jquery.com/Utilities/jQuery.browser + uaMatch: function( ua ) { + ua = ua.toLowerCase(); + + var match = rwebkit.exec( ua ) || + ropera.exec( ua ) || + rmsie.exec( ua ) || + ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || + []; + + return { browser: match[1] || "", version: match[2] || "0" }; + }, + + sub: function() { + function jQuerySubclass( selector, context ) { + return new jQuerySubclass.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySubclass, this ); + jQuerySubclass.superclass = this; + jQuerySubclass.fn = jQuerySubclass.prototype = this(); + jQuerySubclass.fn.constructor = jQuerySubclass; + jQuerySubclass.subclass = this.subclass; + jQuerySubclass.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySubclass) ) { + context = jQuerySubclass(context); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass ); + }; + jQuerySubclass.fn.init.prototype = jQuerySubclass.fn; + var rootjQuerySubclass = jQuerySubclass(document); + return jQuerySubclass; + }, + + browser: {} +}); + +// Create readyList deferred +readyList = jQuery._Deferred(); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +browserMatch = jQuery.uaMatch( userAgent ); +if ( browserMatch.browser ) { + jQuery.browser[ browserMatch.browser ] = true; + jQuery.browser.version = browserMatch.version; +} + +// Deprecated, use jQuery.browser.webkit instead +if ( jQuery.browser.webkit ) { + jQuery.browser.safari = true; +} + +if ( indexOf ) { + jQuery.inArray = function( elem, array ) { + return indexOf.call( array, elem ); + }; +} + +// IE doesn't match non-breaking spaces with \s +if ( rnotwhite.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); + +// Cleanup functions for the document ready method +if ( document.addEventListener ) { + DOMContentLoaded = function() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }; + +} else if ( document.attachEvent ) { + DOMContentLoaded = function() { + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( document.readyState === "complete" ) { + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }; +} + +// The DOM ready check for Internet Explorer +function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch(e) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); +} + +// Expose jQuery to the global object +return jQuery; + +})(); + + +(function() { + + jQuery.support = {}; + + var div = document.createElement("div"); + + div.style.display = "none"; + div.innerHTML = "
a"; + + var all = div.getElementsByTagName("*"), + a = div.getElementsByTagName("a")[0], + select = document.createElement("select"), + opt = select.appendChild( document.createElement("option") ), + input = div.getElementsByTagName("input")[0]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return; + } + + jQuery.support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: div.firstChild.nodeType === 3, + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText insted) + style: /red/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: a.getAttribute("href") === "/a", + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55$/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: input.value === "on", + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Will be defined later + deleteExpando: true, + optDisabled: false, + checkClone: false, + noCloneEvent: true, + noCloneChecked: true, + boxModel: null, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableHiddenOffsets: true + }; + + input.checked = true; + jQuery.support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as diabled) + select.disabled = true; + jQuery.support.optDisabled = !opt.disabled; + + var _scriptEval = null; + jQuery.support.scriptEval = function() { + if ( _scriptEval === null ) { + var root = document.documentElement, + script = document.createElement("script"), + id = "script" + jQuery.now(); + + try { + script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); + } catch(e) {} + + root.insertBefore( script, root.firstChild ); + + // Make sure that the execution of code works by injecting a script + // tag with appendChild/createTextNode + // (IE doesn't support this, fails, and uses .text instead) + if ( window[ id ] ) { + _scriptEval = true; + delete window[ id ]; + } else { + _scriptEval = false; + } + + root.removeChild( script ); + // release memory in IE + root = script = id = null; + } + + return _scriptEval; + }; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + + } catch(e) { + jQuery.support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent("onclick", function click() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + jQuery.support.noCloneEvent = false; + div.detachEvent("onclick", click); + }); + div.cloneNode(true).fireEvent("onclick"); + } + + div = document.createElement("div"); + div.innerHTML = ""; + + var fragment = document.createDocumentFragment(); + fragment.appendChild( div.firstChild ); + + // WebKit doesn't clone checked state correctly in fragments + jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; + + // Figure out if the W3C box model works as expected + // document.body must exist before we can do this + jQuery(function() { + var div = document.createElement("div"), + body = document.getElementsByTagName("body")[0]; + + // Frameset documents with no body should not run this code + if ( !body ) { + return; + } + + div.style.width = div.style.paddingLeft = "1px"; + body.appendChild( div ); + jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; + + if ( "zoom" in div.style ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2; + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2; + } + + div.innerHTML = "
t
"; + var tds = div.getElementsByTagName("td"); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0; + + tds[0].style.display = ""; + tds[1].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE < 8 fail this test) + jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0; + div.innerHTML = ""; + + body.removeChild( div ).style.display = "none"; + div = tds = null; + }); + + // Technique from Juriy Zaytsev + // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ + var eventSupported = function( eventName ) { + var el = document.createElement("div"); + eventName = "on" + eventName; + + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( !el.attachEvent ) { + return true; + } + + var isSupported = (eventName in el); + if ( !isSupported ) { + el.setAttribute(eventName, "return;"); + isSupported = typeof el[eventName] === "function"; + } + el = null; + + return isSupported; + }; + + jQuery.support.submitBubbles = eventSupported("submit"); + jQuery.support.changeBubbles = eventSupported("change"); + + // release memory in IE + div = all = a = null; +})(); + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ jQuery.expando ] = id = ++jQuery.uuid; + } else { + id = jQuery.expando; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery + // metadata on plain JS objects when the object is serialized using + // JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); + } else { + cache[ id ] = jQuery.extend(cache[ id ], name); + } + } + + thisCache = cache[ id ]; + + // Internal jQuery data is stored in a separate object inside the object's data + // cache in order to avoid key collisions between internal data and user-defined + // data + if ( pvt ) { + if ( !thisCache[ internalKey ] ) { + thisCache[ internalKey ] = {}; + } + + thisCache = thisCache[ internalKey ]; + } + + if ( data !== undefined ) { + thisCache[ name ] = data; + } + + // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should + // not attempt to inspect the internal events object using jQuery.data, as this + // internal data object is undocumented and subject to change. + if ( name === "events" && !thisCache[name] ) { + return thisCache[ internalKey ] && thisCache[ internalKey ].events; + } + + return getByName ? thisCache[ name ] : thisCache; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var internalKey = jQuery.expando, isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ]; + + if ( thisCache ) { + delete thisCache[ name ]; + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !isEmptyDataObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( pvt ) { + delete cache[ id ][ internalKey ]; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + var internalCache = cache[ id ][ internalKey ]; + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + if ( jQuery.support.deleteExpando || cache != window ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the entire user cache at once because it's faster than + // iterating through each key, but we need to continue to persist internal + // data if it existed + if ( internalCache ) { + cache[ id ] = {}; + // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery + // metadata on plain JS objects when the object is serialized using + // JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + + cache[ id ][ internalKey ] = internalCache; + + // Otherwise, we need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + } else if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ jQuery.expando ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( jQuery.expando ); + } else { + elem[ jQuery.expando ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 ) { + var attr = this[0].attributes, name; + for ( var i = 0, l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = name.substr( 5 ); + dataAttr( this[0], name, data[ name ] ); + } + } + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + var parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value === undefined ) { + data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + // Try to fetch any internally stored data first + if ( data === undefined && this.length ) { + data = jQuery.data( this[0], key ); + data = dataAttr( this[0], key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + + } else { + return this.each(function() { + var $this = jQuery( this ), + args = [ parts[0], value ]; + + $this.triggerHandler( "setData" + parts[1] + "!", args ); + jQuery.data( this, key, value ); + $this.triggerHandler( "changeData" + parts[1] + "!", args ); + }); + } + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + data = elem.getAttribute( "data-" + key ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + !jQuery.isNaN( data ) ? parseFloat( data ) : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON +// property to be considered empty objects; this property always exists in +// order to make sure JSON.stringify does not expose internal metadata +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +jQuery.extend({ + queue: function( elem, type, data ) { + if ( !elem ) { + return; + } + + type = (type || "fx") + "queue"; + var q = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( !data ) { + return q || []; + } + + if ( !q || jQuery.isArray(data) ) { + q = jQuery._data( elem, type, jQuery.makeArray(data) ); + + } else { + q.push( data ); + } + + return q; + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(); + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift("inprogress"); + } + + fn.call(elem, function() { + jQuery.dequeue(elem, type); + }); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue", true ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + } + + if ( data === undefined ) { + return jQuery.queue( this[0], type ); + } + return this.each(function( i ) { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; + type = type || "fx"; + + return this.queue( type, function() { + var elem = this; + setTimeout(function() { + jQuery.dequeue( elem, type ); + }, time ); + }); + }, + + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspaces = /\s+/, + rreturn = /\r/g, + rspecialurl = /^(?:href|src|style)$/, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rradiocheck = /^(?:radio|checkbox)$/i; + +jQuery.props = { + "for": "htmlFor", + "class": "className", + readonly: "readOnly", + maxlength: "maxLength", + cellspacing: "cellSpacing", + rowspan: "rowSpan", + colspan: "colSpan", + tabindex: "tabIndex", + usemap: "useMap", + frameborder: "frameBorder" +}; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.attr ); + }, + + removeAttr: function( name, fn ) { + return this.each(function(){ + jQuery.attr( this, name, "" ); + if ( this.nodeType === 1 ) { + this.removeAttribute( name ); + } + }); + }, + + addClass: function( value ) { + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + self.addClass( value.call(this, i, self.attr("class")) ); + }); + } + + if ( value && typeof value === "string" ) { + var classNames = (value || "").split( rspaces ); + + for ( var i = 0, l = this.length; i < l; i++ ) { + var elem = this[i]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className ) { + elem.className = value; + + } else { + var className = " " + elem.className + " ", + setClass = elem.className; + + for ( var c = 0, cl = classNames.length; c < cl; c++ ) { + if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { + setClass += " " + classNames[c]; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + self.removeClass( value.call(this, i, self.attr("class")) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + var classNames = (value || "").split( rspaces ); + + for ( var i = 0, l = this.length; i < l; i++ ) { + var elem = this[i]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + var className = (" " + elem.className + " ").replace(rclass, " "); + for ( var c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[c] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this); + self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspaces ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " "; + for ( var i = 0, l = this.length; i < l; i++ ) { + if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + if ( !arguments.length ) { + var elem = this[0]; + + if ( elem ) { + if ( jQuery.nodeName( elem, "option" ) ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + + // We need to handle select boxes special + if ( jQuery.nodeName( elem, "select" ) ) { + var index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { + var option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery(option).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + } + + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { + return elem.getAttribute("value") === null ? "on" : elem.value; + } + + // Everything else, we just grab the value + return (elem.value || "").replace(rreturn, ""); + + } + + return undefined; + } + + var isFunction = jQuery.isFunction(value); + + return this.each(function(i) { + var self = jQuery(this), val = value; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call(this, i, self.val()); + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray(val) ) { + val = jQuery.map(val, function (value) { + return value == null ? "" : value + ""; + }); + } + + if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { + this.checked = jQuery.inArray( self.val(), val ) >= 0; + + } else if ( jQuery.nodeName( this, "select" ) ) { + var values = jQuery.makeArray(val); + + jQuery( "option", this ).each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + this.selectedIndex = -1; + } + + } else { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attr: function( elem, name, value, pass ) { + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) { + return undefined; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery(elem)[name](value); + } + + var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), + // Whether we are setting (or getting) + set = value !== undefined; + + // Try to normalize/fix the name + name = notxml && jQuery.props[ name ] || name; + + // Only do all the following if this is a node (faster for style) + if ( elem.nodeType === 1 ) { + // These attributes require special treatment + var special = rspecialurl.test( name ); + + // Safari mis-reports the default selected property of an option + // Accessing the parent's selectedIndex property fixes it + if ( name === "selected" && !jQuery.support.optSelected ) { + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + + // If applicable, access the attribute via the DOM 0 way + // 'in' checks fail in Blackberry 4.7 #6931 + if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) { + if ( set ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } + + if ( value === null ) { + if ( elem.nodeType === 1 ) { + elem.removeAttribute( name ); + } + + } else { + elem[ name ] = value; + } + } + + // browsers index elements by id/name on forms, give priority to attributes. + if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { + return elem.getAttributeNode( name ).nodeValue; + } + + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + if ( name === "tabIndex" ) { + var attributeNode = elem.getAttributeNode( "tabIndex" ); + + return attributeNode && attributeNode.specified ? + attributeNode.value : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + + return elem[ name ]; + } + + if ( !jQuery.support.style && notxml && name === "style" ) { + if ( set ) { + elem.style.cssText = "" + value; + } + + return elem.style.cssText; + } + + if ( set ) { + // convert the value to a string (all browsers do this but IE) see #1070 + elem.setAttribute( name, "" + value ); + } + + // Ensure that missing attributes return undefined + // Blackberry 4.7 returns "" from getAttribute #6938 + if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) { + return undefined; + } + + var attr = !jQuery.support.hrefNormalized && notxml && special ? + // Some attributes require a special call on IE + elem.getAttribute( name, 2 ) : + elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return attr === null ? undefined : attr; + } + // Handle everything which isn't a DOM element node + if ( set ) { + elem[ name ] = value; + } + return elem[ name ]; + } +}); + + + + +var rnamespaces = /\.(.*)$/, + rformElems = /^(?:textarea|input|select)$/i, + rperiod = /\./g, + rspace = / /g, + rescape = /[^\w\s.|`]/g, + fcleanup = function( nm ) { + return nm.replace(rescape, "\\$&"); + }; + +/* + * A number of helper functions used for managing events. + * Many of the ideas behind this code originated from + * Dean Edwards' addEvent library. + */ +jQuery.event = { + + // Bind an event to an element + // Original by Dean Edwards + add: function( elem, types, handler, data ) { + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // TODO :: Use a try/catch until it's safe to pull this out (likely 1.6) + // Minor release fix for bug #8018 + try { + // For whatever reason, IE has trouble passing the window object + // around, causing it to be cloned in the process + if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { + elem = window; + } + } + catch ( e ) {} + + if ( handler === false ) { + handler = returnFalse; + } else if ( !handler ) { + // Fixes bug #7229. Fix recommended by jdalton + return; + } + + var handleObjIn, handleObj; + + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the function being executed has a unique ID + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure + var elemData = jQuery._data( elem ); + + // If no elemData is found then we must be trying to bind to one of the + // banned noData elements + if ( !elemData ) { + return; + } + + var events = elemData.events, + eventHandle = elemData.handle; + + if ( !events ) { + elemData.events = events = {}; + } + + if ( !eventHandle ) { + elemData.handle = eventHandle = function() { + // Handle the second event of a trigger and when + // an event is called after a page has unloaded + return typeof jQuery !== "undefined" && !jQuery.event.triggered ? + jQuery.event.handle.apply( eventHandle.elem, arguments ) : + undefined; + }; + } + + // Add elem as a property of the handle function + // This is to prevent a memory leak with non-native events in IE. + eventHandle.elem = elem; + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = types.split(" "); + + var type, i = 0, namespaces; + + while ( (type = types[ i++ ]) ) { + handleObj = handleObjIn ? + jQuery.extend({}, handleObjIn) : + { handler: handler, data: data }; + + // Namespaced event handlers + if ( type.indexOf(".") > -1 ) { + namespaces = type.split("."); + type = namespaces.shift(); + handleObj.namespace = namespaces.slice(0).sort().join("."); + + } else { + namespaces = []; + handleObj.namespace = ""; + } + + handleObj.type = type; + if ( !handleObj.guid ) { + handleObj.guid = handler.guid; + } + + // Get the current list of functions bound to this event + var handlers = events[ type ], + special = jQuery.event.special[ type ] || {}; + + // Init the event handler queue + if ( !handlers ) { + handlers = events[ type ] = []; + + // Check for a special event handler + // Only use addEventListener/attachEvent if the special + // events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add the function to the element's handler list + handlers.push( handleObj ); + + // Keep track of which events have been used, for global triggering + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, pos ) { + // don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + if ( handler === false ) { + handler = returnFalse; + } + + var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + events = elemData && elemData.events; + + if ( !elemData || !events ) { + return; + } + + // types is actually an event object here + if ( types && types.type ) { + handler = types.handler; + types = types.type; + } + + // Unbind all events for the element + if ( !types || typeof types === "string" && types.charAt(0) === "." ) { + types = types || ""; + + for ( type in events ) { + jQuery.event.remove( elem, type + types ); + } + + return; + } + + // Handle multiple events separated by a space + // jQuery(...).unbind("mouseover mouseout", fn); + types = types.split(" "); + + while ( (type = types[ i++ ]) ) { + origType = type; + handleObj = null; + all = type.indexOf(".") < 0; + namespaces = []; + + if ( !all ) { + // Namespaced event handlers + namespaces = type.split("."); + type = namespaces.shift(); + + namespace = new RegExp("(^|\\.)" + + jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); + } + + eventType = events[ type ]; + + if ( !eventType ) { + continue; + } + + if ( !handler ) { + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( all || namespace.test( handleObj.namespace ) ) { + jQuery.event.remove( elem, origType, handleObj.handler, j ); + eventType.splice( j--, 1 ); + } + } + + continue; + } + + special = jQuery.event.special[ type ] || {}; + + for ( j = pos || 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( handler.guid === handleObj.guid ) { + // remove the given handler for the given type + if ( all || namespace.test( handleObj.namespace ) ) { + if ( pos == null ) { + eventType.splice( j--, 1 ); + } + + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + + if ( pos != null ) { + break; + } + } + } + + // remove generic event handler if no more handlers exist + if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + ret = null; + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + var handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + delete elemData.events; + delete elemData.handle; + + if ( jQuery.isEmptyObject( elemData ) ) { + jQuery.removeData( elem, undefined, true ); + } + } + }, + + // bubbling is internal + trigger: function( event, data, elem /*, bubbling */ ) { + // Event object or event type + var type = event.type || event, + bubbling = arguments[3]; + + if ( !bubbling ) { + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + jQuery.extend( jQuery.Event(type), event ) : + // Just the event type (string) + jQuery.Event(type); + + if ( type.indexOf("!") >= 0 ) { + event.type = type = type.slice(0, -1); + event.exclusive = true; + } + + // Handle a global trigger + if ( !elem ) { + // Don't bubble custom events when global (to avoid too much overhead) + event.stopPropagation(); + + // Only trigger if we've ever bound an event for it + if ( jQuery.event.global[ type ] ) { + // XXX This code smells terrible. event.js should not be directly + // inspecting the data cache + jQuery.each( jQuery.cache, function() { + // internalKey variable is just used to make it easier to find + // and potentially change this stuff later; currently it just + // points to jQuery.expando + var internalKey = jQuery.expando, + internalCache = this[ internalKey ]; + if ( internalCache && internalCache.events && internalCache.events[ type ] ) { + jQuery.event.trigger( event, data, internalCache.handle.elem ); + } + }); + } + } + + // Handle triggering a single element + + // don't do events on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { + return undefined; + } + + // Clean up in case it is reused + event.result = undefined; + event.target = elem; + + // Clone the incoming data, if any + data = jQuery.makeArray( data ); + data.unshift( event ); + } + + event.currentTarget = elem; + + // Trigger the event, it is assumed that "handle" is a function + var handle = jQuery._data( elem, "handle" ); + + if ( handle ) { + handle.apply( elem, data ); + } + + var parent = elem.parentNode || elem.ownerDocument; + + // Trigger an inline bound script + try { + if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { + if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { + event.result = false; + event.preventDefault(); + } + } + + // prevent IE from throwing an error for some elements with some event types, see #3533 + } catch (inlineError) {} + + if ( !event.isPropagationStopped() && parent ) { + jQuery.event.trigger( event, data, parent, true ); + + } else if ( !event.isDefaultPrevented() ) { + var old, + target = event.target, + targetType = type.replace( rnamespaces, "" ), + isClick = jQuery.nodeName( target, "a" ) && targetType === "click", + special = jQuery.event.special[ targetType ] || {}; + + if ( (!special._default || special._default.call( elem, event ) === false) && + !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { + + try { + if ( target[ targetType ] ) { + // Make sure that we don't accidentally re-trigger the onFOO events + old = target[ "on" + targetType ]; + + if ( old ) { + target[ "on" + targetType ] = null; + } + + jQuery.event.triggered = true; + target[ targetType ](); + } + + // prevent IE from throwing an error for some elements with some event types, see #3533 + } catch (triggerError) {} + + if ( old ) { + target[ "on" + targetType ] = old; + } + + jQuery.event.triggered = false; + } + } + }, + + handle: function( event ) { + var all, handlers, namespaces, namespace_re, events, + namespace_sort = [], + args = jQuery.makeArray( arguments ); + + event = args[0] = jQuery.event.fix( event || window.event ); + event.currentTarget = this; + + // Namespaced event handlers + all = event.type.indexOf(".") < 0 && !event.exclusive; + + if ( !all ) { + namespaces = event.type.split("."); + event.type = namespaces.shift(); + namespace_sort = namespaces.slice(0).sort(); + namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)"); + } + + event.namespace = event.namespace || namespace_sort.join("."); + + events = jQuery._data(this, "events"); + + handlers = (events || {})[ event.type ]; + + if ( events && handlers ) { + // Clone the handlers to prevent manipulation + handlers = handlers.slice(0); + + for ( var j = 0, l = handlers.length; j < l; j++ ) { + var handleObj = handlers[ j ]; + + // Filter the functions by class + if ( all || namespace_re.test( handleObj.namespace ) ) { + // Pass in a reference to the handler function itself + // So that we can later remove it + event.handler = handleObj.handler; + event.data = handleObj.data; + event.handleObj = handleObj; + + var ret = handleObj.handler.apply( this, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + + if ( event.isImmediatePropagationStopped() ) { + break; + } + } + } + } + + return event.result; + }, + + props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // store a copy of the original event object + // and "clone" to set read-only properties + var originalEvent = event; + event = jQuery.Event( originalEvent ); + + for ( var i = this.props.length, prop; i; ) { + prop = this.props[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary + if ( !event.target ) { + // Fixes #1925 where srcElement might not be defined either + event.target = event.srcElement || document; + } + + // check if target is a textnode (safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && event.fromElement ) { + event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; + } + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && event.clientX != null ) { + var doc = document.documentElement, + body = document.body; + + event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); + event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); + } + + // Add which for key events + if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { + event.which = event.charCode != null ? event.charCode : event.keyCode; + } + + // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) + if ( !event.metaKey && event.ctrlKey ) { + event.metaKey = event.ctrlKey; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && event.button !== undefined ) { + event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); + } + + return event; + }, + + // Deprecated, use jQuery.guid instead + guid: 1E8, + + // Deprecated, use jQuery.proxy instead + proxy: jQuery.proxy, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady, + teardown: jQuery.noop + }, + + live: { + add: function( handleObj ) { + jQuery.event.add( this, + liveConvert( handleObj.origType, handleObj.selector ), + jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); + }, + + remove: function( handleObj ) { + jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj ); + } + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src ) { + // Allow instantiation without the 'new' keyword + if ( !this.preventDefault ) { + return new jQuery.Event( src ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // timeStamp is buggy for some events on Firefox(#3843) + // So we won't rely on the native value + this.timeStamp = jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Checks if an event happened on an element within another element +// Used in jQuery.event.special.mouseenter and mouseleave handlers +var withinElement = function( event ) { + // Check if mouse(over|out) are still within the same parent element + var parent = event.relatedTarget; + + // Firefox sometimes assigns relatedTarget a XUL element + // which we cannot access the parentNode property of + try { + + // Chrome does something similar, the parentNode property + // can be accessed but is null. + if ( parent !== document && !parent.parentNode ) { + return; + } + // Traverse up the tree + while ( parent && parent !== this ) { + parent = parent.parentNode; + } + + if ( parent !== this ) { + // set the correct event type + event.type = event.data; + + // handle event if we actually just moused on to a non sub-element + jQuery.event.handle.apply( this, arguments ); + } + + // assuming we've left the element since we most likely mousedover a xul element + } catch(e) { } +}, + +// In case of event delegation, we only need to rename the event.type, +// liveHandler will take care of the rest. +delegate = function( event ) { + event.type = event.data; + jQuery.event.handle.apply( this, arguments ); +}; + +// Create mouseenter and mouseleave events +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + setup: function( data ) { + jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); + }, + teardown: function( data ) { + jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); + } + }; +}); + +// submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function( data, namespaces ) { + if ( this.nodeName && this.nodeName.toLowerCase() !== "form" ) { + jQuery.event.add(this, "click.specialSubmit", function( e ) { + var elem = e.target, + type = elem.type; + + if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { + trigger( "submit", this, arguments ); + } + }); + + jQuery.event.add(this, "keypress.specialSubmit", function( e ) { + var elem = e.target, + type = elem.type; + + if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { + trigger( "submit", this, arguments ); + } + }); + + } else { + return false; + } + }, + + teardown: function( namespaces ) { + jQuery.event.remove( this, ".specialSubmit" ); + } + }; + +} + +// change delegation, happens here so we have bind. +if ( !jQuery.support.changeBubbles ) { + + var changeFilters, + + getVal = function( elem ) { + var type = elem.type, val = elem.value; + + if ( type === "radio" || type === "checkbox" ) { + val = elem.checked; + + } else if ( type === "select-multiple" ) { + val = elem.selectedIndex > -1 ? + jQuery.map( elem.options, function( elem ) { + return elem.selected; + }).join("-") : + ""; + + } else if ( elem.nodeName.toLowerCase() === "select" ) { + val = elem.selectedIndex; + } + + return val; + }, + + testChange = function testChange( e ) { + var elem = e.target, data, val; + + if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) { + return; + } + + data = jQuery._data( elem, "_change_data" ); + val = getVal(elem); + + // the current data will be also retrieved by beforeactivate + if ( e.type !== "focusout" || elem.type !== "radio" ) { + jQuery._data( elem, "_change_data", val ); + } + + if ( data === undefined || val === data ) { + return; + } + + if ( data != null || val ) { + e.type = "change"; + e.liveFired = undefined; + jQuery.event.trigger( e, arguments[1], elem ); + } + }; + + jQuery.event.special.change = { + filters: { + focusout: testChange, + + beforedeactivate: testChange, + + click: function( e ) { + var elem = e.target, type = elem.type; + + if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { + testChange.call( this, e ); + } + }, + + // Change has to be called before submit + // Keydown will be called before keypress, which is used in submit-event delegation + keydown: function( e ) { + var elem = e.target, type = elem.type; + + if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || + (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || + type === "select-multiple" ) { + testChange.call( this, e ); + } + }, + + // Beforeactivate happens also before the previous element is blurred + // with this event you can't trigger a change event, but you can store + // information + beforeactivate: function( e ) { + var elem = e.target; + jQuery._data( elem, "_change_data", getVal(elem) ); + } + }, + + setup: function( data, namespaces ) { + if ( this.type === "file" ) { + return false; + } + + for ( var type in changeFilters ) { + jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); + } + + return rformElems.test( this.nodeName ); + }, + + teardown: function( namespaces ) { + jQuery.event.remove( this, ".specialChange" ); + + return rformElems.test( this.nodeName ); + } + }; + + changeFilters = jQuery.event.special.change.filters; + + // Handle when the input is .focus()'d + changeFilters.focus = changeFilters.beforeactivate; +} + +function trigger( type, elem, args ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + // Don't pass args or remember liveFired; they apply to the donor event. + var event = jQuery.extend( {}, args[ 0 ] ); + event.type = type; + event.originalEvent = {}; + event.liveFired = undefined; + jQuery.event.handle.call( elem, event ); + if ( event.isDefaultPrevented() ) { + args[ 0 ].preventDefault(); + } +} + +// Create "bubbling" focus and blur events +if ( document.addEventListener ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + jQuery.event.special[ fix ] = { + setup: function() { + this.addEventListener( orig, handler, true ); + }, + teardown: function() { + this.removeEventListener( orig, handler, true ); + } + }; + + function handler( e ) { + e = jQuery.event.fix( e ); + e.type = fix; + return jQuery.event.handle.call( this, e ); + } + }); +} + +jQuery.each(["bind", "one"], function( i, name ) { + jQuery.fn[ name ] = function( type, data, fn ) { + // Handle object literals + if ( typeof type === "object" ) { + for ( var key in type ) { + this[ name ](key, data, type[key], fn); + } + return this; + } + + if ( jQuery.isFunction( data ) || data === false ) { + fn = data; + data = undefined; + } + + var handler = name === "one" ? jQuery.proxy( fn, function( event ) { + jQuery( this ).unbind( event, handler ); + return fn.apply( this, arguments ); + }) : fn; + + if ( type === "unload" && name !== "one" ) { + this.one( type, data, fn ); + + } else { + for ( var i = 0, l = this.length; i < l; i++ ) { + jQuery.event.add( this[i], type, handler, data ); + } + } + + return this; + }; +}); + +jQuery.fn.extend({ + unbind: function( type, fn ) { + // Handle object literals + if ( typeof type === "object" && !type.preventDefault ) { + for ( var key in type ) { + this.unbind(key, type[key]); + } + + } else { + for ( var i = 0, l = this.length; i < l; i++ ) { + jQuery.event.remove( this[i], type, fn ); + } + } + + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.live( types, data, fn, selector ); + }, + + undelegate: function( selector, types, fn ) { + if ( arguments.length === 0 ) { + return this.unbind( "live" ); + + } else { + return this.die( types, null, fn, selector ); + } + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + + triggerHandler: function( type, data ) { + if ( this[0] ) { + var event = jQuery.Event( type ); + event.preventDefault(); + event.stopPropagation(); + jQuery.event.trigger( event, data, this[0] ); + return event.result; + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + i = 1; + + // link all the functions, so any of them can unbind this click handler + while ( i < args.length ) { + jQuery.proxy( fn, args[ i++ ] ); + } + + return this.click( jQuery.proxy( fn, function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + })); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +var liveMap = { + focus: "focusin", + blur: "focusout", + mouseenter: "mouseover", + mouseleave: "mouseout" +}; + +jQuery.each(["live", "die"], function( i, name ) { + jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { + var type, i = 0, match, namespaces, preType, + selector = origSelector || this.selector, + context = origSelector ? this : jQuery( this.context ); + + if ( typeof types === "object" && !types.preventDefault ) { + for ( var key in types ) { + context[ name ]( key, data, types[key], selector ); + } + + return this; + } + + if ( jQuery.isFunction( data ) ) { + fn = data; + data = undefined; + } + + types = (types || "").split(" "); + + while ( (type = types[ i++ ]) != null ) { + match = rnamespaces.exec( type ); + namespaces = ""; + + if ( match ) { + namespaces = match[0]; + type = type.replace( rnamespaces, "" ); + } + + if ( type === "hover" ) { + types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); + continue; + } + + preType = type; + + if ( type === "focus" || type === "blur" ) { + types.push( liveMap[ type ] + namespaces ); + type = type + namespaces; + + } else { + type = (liveMap[ type ] || type) + namespaces; + } + + if ( name === "live" ) { + // bind live handler + for ( var j = 0, l = context.length; j < l; j++ ) { + jQuery.event.add( context[j], "live." + liveConvert( type, selector ), + { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); + } + + } else { + // unbind live handler + context.unbind( "live." + liveConvert( type, selector ), fn ); + } + } + + return this; + }; +}); + +function liveHandler( event ) { + var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, + elems = [], + selectors = [], + events = jQuery._data( this, "events" ); + + // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) + if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { + return; + } + + if ( event.namespace ) { + namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)"); + } + + event.liveFired = this; + + var live = events.live.slice(0); + + for ( j = 0; j < live.length; j++ ) { + handleObj = live[j]; + + if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { + selectors.push( handleObj.selector ); + + } else { + live.splice( j--, 1 ); + } + } + + match = jQuery( event.target ).closest( selectors, event.currentTarget ); + + for ( i = 0, l = match.length; i < l; i++ ) { + close = match[i]; + + for ( j = 0; j < live.length; j++ ) { + handleObj = live[j]; + + if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) { + elem = close.elem; + related = null; + + // Those two events require additional checking + if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { + event.type = handleObj.preType; + related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; + } + + if ( !related || related !== elem ) { + elems.push({ elem: elem, handleObj: handleObj, level: close.level }); + } + } + } + } + + for ( i = 0, l = elems.length; i < l; i++ ) { + match = elems[i]; + + if ( maxLevel && match.level > maxLevel ) { + break; + } + + event.currentTarget = match.elem; + event.data = match.handleObj.data; + event.handleObj = match.handleObj; + + ret = match.handleObj.origHandler.apply( match.elem, arguments ); + + if ( ret === false || event.isPropagationStopped() ) { + maxLevel = match.level; + + if ( ret === false ) { + stop = false; + } + if ( event.isImmediatePropagationStopped() ) { + break; + } + } + } + + return stop; +} + +function liveConvert( type, selector ) { + return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&"); +} + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.bind( name, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } +}); + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set; + + if ( !expr ) { + return []; + } + + for ( var i = 0, l = Expr.order.length; i < l; i++ ) { + var match, + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + var left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( var type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + var found, item, + filter = Expr.filter[ type ], + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( var i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + var pass = not ^ !!found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw "Syntax error, unrecognized expression: " + msg; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return "text" === elem.getAttribute( 'type' ); + }, + radio: function( elem ) { + return "radio" === elem.type; + }, + + checkbox: function( elem ) { + return "checkbox" === elem.type; + }, + + file: function( elem ) { + return "file" === elem.type; + }, + password: function( elem ) { + return "password" === elem.type; + }, + + submit: function( elem ) { + return "submit" === elem.type; + }, + + image: function( elem ) { + return "image" === elem.type; + }, + + reset: function( elem ) { + return "reset" === elem.type; + }, + + button: function( elem ) { + return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + var first = match[2], + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + var doneName = match[0], + parent = elem.parentNode; + + if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { + var count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent.sizcache = doneName; + } + + var diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // If the nodes are siblings (or identical) we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Utility function for retreiving the text value of an array of DOM nodes +Sizzle.getText = function( elems ) { + var ret = "", elem; + + for ( var i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += Sizzle.getText( elem.childNodes ); + } + } + + return ret; +}; + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector, + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + if ( matches ) { + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + return matches.call( node, expr ); + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.POS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var ret = this.pushStack( "", "find", selector ), + length = 0; + + for ( var i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( var n = length; n < ret.length; n++ ) { + for ( var r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && jQuery.filter( selector, this ).length > 0; + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + if ( jQuery.isArray( selectors ) ) { + var match, selector, + matches = {}, + level = 1; + + if ( cur && selectors.length ) { + for ( i = 0, l = selectors.length; i < l; i++ ) { + selector = selectors[i]; + + if ( !matches[selector] ) { + matches[selector] = jQuery.expr.match.POS.test( selector ) ? + jQuery( selector, context || this.context ) : + selector; + } + } + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( selector in matches ) { + match = matches[selector]; + + if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { + ret.push({ selector: selector, elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + } + + return ret; + } + + var pos = POS.test( selectors ) ? + jQuery( selectors, context || this.context ) : null; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique(ret) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + if ( !elem || typeof elem === "string" ) { + return jQuery.inArray( this[0], + // If it receives a string, the selector is used + // If it receives nothing, the siblings are used + elem ? jQuery( elem ) : this.parent().children() ); + } + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( elem.parentNode.firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ), + // The variable 'args' was introduced in + // https://github.com/jquery/jquery/commit/52a0238 + // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. + // http://code.google.com/p/v8/issues/detail?id=1050 + args = slice.call(arguments); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, args.join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return (elem === qualifier) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return (jQuery.inArray( elem, qualifier ) >= 0) === keep; + }); +} + + + + +var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /", "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }; + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + + + CRCE - ${param.title} + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+
+ + + + +
${message}
+
+ +
${message}
+
+
+ + +
diff --git a/modules/crce-webui/src/main/webapp/jsp/plugins.jsp b/modules/crce-webui/src/main/webapp/jsp/plugins.jsp new file mode 100644 index 00000000..ff12f87d --- /dev/null +++ b/modules/crce-webui/src/main/webapp/jsp/plugins.jsp @@ -0,0 +1,49 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + + +
+ + +
+
+ +
+ edit +
+
+
+
+
Description: ${plugin.pluginDescription}
+
Priority: ${plugin.pluginPriority} [edit]
+
Version: ${plugin.pluginVersion} [edit]
+
Keywords: +
    + +
  • ${keyword}
  • +
    +
+
+
+
+
+ + +
+
No plugins.
+
+
+ + + + +
+ + \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/store.jsp b/modules/crce-webui/src/main/webapp/jsp/store.jsp new file mode 100644 index 00000000..e122822d --- /dev/null +++ b/modules/crce-webui/src/main/webapp/jsp/store.jsp @@ -0,0 +1,178 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + + +
+ +
+ + +
${resource.satisfied} + + + + uspech1 + + + neuspech1 + + + + "> + +
+
Properties: [edit] +
    +
  • Id: ${resource.id}
  • +
  • Symbolic name: ${resource.symbolicName}
  • +
  • Size: ${resource.size}
  • +
  • Export Meta-Data: LINK
  • +
+
    + +
  • + ${newProperty.name} + + + + +
    ${property.name}${property.type}${property.value}
    +
  • +
    +
+
+
Categories: [edit] +
    + +
  • ${category}
  • +
    +
+
+
+
Capabilities: [add new] +
    + +
  • + ${capability.name} [edit] + + + + +
    ${property.name}${property.type}${property.value}
    + +
      + +
    • + ${newProperty.name} + + + + +
      ${property.name}${property.type}${property.value}
      +
    • +
      +
    + +
  • +
    +
+
+
Requirements: [edit] + + + + + ${requirement.satisfied} + + + + + + + + + + + ${requirement.satisfied} + + + + class="uspech" + + + class="neuspech" + + + + > + + + + + + + + + + + +
NameFilterMultipleOptionalExtend
Comment
Unsatisfied requirements:
${requirement.name}${requirement.filter}${requirement.multiple}${requirement.optional}${requirement.extend}
${requirement.comment}
+
+
+
+
+ + +
+
No resources in store.
+
+
+ + + + + + +
+ +
+
+
+ +
+
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/tags.jsp b/modules/crce-webui/src/main/webapp/jsp/tags.jsp new file mode 100644 index 00000000..5069d6c2 --- /dev/null +++ b/modules/crce-webui/src/main/webapp/jsp/tags.jsp @@ -0,0 +1,146 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + + +
+ +
+ + + Store: + + + Store: + + + + + + Buffer: + + + Buffer: + + + + +
+ + + + +
+ +
${resource.satisfied} + + + + uspech1 + + + neuspech1 + + + + "> + +
+
Properties: +
    +
  • Id: ${resource.id}
  • +
  • Symbolic name: ${resource.symbolicName}
  • +
  • Size: ${resource.size}
  • +
+
+
Categories: +
    + +
  • ${category}
  • +
    +
+
+
Capabilities: +
    + +
  • + ${capability.name} + + + + + + + + +
    ${property.name}${property.type}${property.value}
    +
  • +
    +
+
+
Requirements: + + + + + ${requirement.satisfied} + + + + class="uspech" + + + class="neuspech" + + + + > + + + + + + + + + + +
NameFilterMultipleOptionalExtend
Comment
${requirement.name}${requirement.filter}${requirement.multiple}${requirement.optional}${requirement.extend}
${requirement.comment}
+
+
+
+
+
+ + +
+ + \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/test.jsp b/modules/crce-webui/src/main/webapp/test.jsp new file mode 100644 index 00000000..d6d47d25 --- /dev/null +++ b/modules/crce-webui/src/main/webapp/test.jsp @@ -0,0 +1,142 @@ +<%@page import="cz.zcu.kiv.crce.plugin.Plugin"%> +<%@page import="cz.zcu.kiv.crce.metadata.Requirement"%> +<%@page import="cz.zcu.kiv.crce.metadata.Property"%> +<%@page import="cz.zcu.kiv.crce.metadata.Capability"%> +<%@page import="cz.zcu.kiv.crce.repository.Buffer"%> +<%@page import="cz.zcu.kiv.crce.webui.internal.Activator"%> +<%@page import="cz.zcu.kiv.crce.metadata.Resource"%> + +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + + <% + //String hello = (String) session.getAttribute("hello"); + Resource[] resources = (Resource[]) session.getAttribute("resources"); + Plugin[] plugins = (Plugin[]) session.getAttribute("plugins"); + Resource[] store = (Resource[]) session.getAttribute("store"); + if(/*hello!=null &&*/ resources!=null && plugins!=null && store!=null) + { + //out.print(hello); + out.print("Resources size : "+resources.length+" Plugin size: "+plugins.length+" Store length: "+store.length); + } + else out.print("DIED"); + %> + + + + + + + + + + + + + + + Software components storage + + + + +
+ +
+
logo
+
Software components storage
+ +
+
+ + +
+
+
+
+ + + +
+ + +
+ +
+
Id: ${resource.id}
+
Symbolic name: ${resource.symbolicName}
+
URI: ${resource.uri}
+
Relative URI: ${resource.relativeUri}
+
Size: ${resource.size}
+
Categories: +
    + +
  • ${category}
  • +
    +
+
+
Capabilities: +
    + +
  • ${capability.name}
  • +
    +
+
+
Requirements: +
    + +
  • ${requirement.name} - ${requirement.filter}
  • +
    +
+
+
+
+
+ + +
+ +
© ASWI project 2011
+ +
+ + + + + diff --git a/modules/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java b/modules/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java new file mode 100644 index 00000000..f3d39f55 --- /dev/null +++ b/modules/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java @@ -0,0 +1,40 @@ +package cz.zcu.kiv.crce.webui.internal; + +import static org.junit.Assert.*; + + +import java.io.IOException; +import java.net.MalformedURLException; + +import org.junit.Ignore; +import org.junit.Test; + +import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.html.HtmlPage; + + +@Ignore +public class ResourceServletTest { + + + @Test + public void testDoGetHttpServletRequestHttpServletResponse() { + WebClient webClient = new WebClient(); + HtmlPage currentPage; + try { + currentPage =(HtmlPage) webClient.getPage("http://localhost:8090/crce/resource"); + + String pageAsText = currentPage.asText(); + assertTrue("Page does not contains uri: cz.zcu.kiv.crce.repository.api", pageAsText.contains("cz.zcu.kiv.crce.repository.api")); + } catch (FailingHttpStatusCodeException e) { + fail("FHSCE: " + e.toString()); + } catch (MalformedURLException e) { + fail("MUE: " + e.toString()); + } catch (IOException e) { + fail("IOE: " + e.toString()); + } + } + + +} diff --git a/modules/pom.xml b/modules/pom.xml index 95f437d6..44736894 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -69,8 +69,8 @@ + crce-webui-v2 - crce-rest-v2 diff --git a/modules/provision/pom.xml b/modules/provision/pom.xml index 999711a5..42d93c82 100644 --- a/modules/provision/pom.xml +++ b/modules/provision/pom.xml @@ -36,7 +36,7 @@ - From 0487a1157f0c1d78f00f101317d6b301e22ec5e1 Mon Sep 17 00:00:00 2001 From: rpesek Date: Mon, 20 Aug 2018 12:45:33 +0200 Subject: [PATCH 19/85] Bug UI - Correction to check form filling Central Maven - when you enable search by group only --- core/crce-metadata-api/.project | 10 ++-- core/crce-metadata-dao-api/.project | 10 ++-- core/crce-metadata-impl/.project | 10 ++-- core/crce-metadata-indexer-api/.project | 4 +- core/crce-metadata-indexer-impl/.project | 4 +- core/crce-metadata-json-api/.project | 4 +- core/crce-metadata-json-impl/.project | 4 +- core/crce-metadata-service-api/.project | 10 ++-- core/crce-metadata-service-impl/.project | 10 ++-- core/crce-plugin-api/.project | 10 ++-- core/crce-repository-api/.project | 10 ++-- core/crce-repository-impl/.project | 10 ++-- core/crce-resolver-api/.project | 10 ++-- core/crce-resolver-impl/.project | 10 ++-- modules/crce-concurrency/.project | 4 +- modules/crce-external-repository/.classpath | 2 + .../META-INF/MANIFEST.MF | 2 +- .../crce_webui_v2/outer/CentralMavenForm.java | 46 ++++++++++++++----- 18 files changed, 98 insertions(+), 72 deletions(-) diff --git a/core/crce-metadata-api/.project b/core/crce-metadata-api/.project index dcddf63f..12b7d3a4 100644 --- a/core/crce-metadata-api/.project +++ b/core/crce-metadata-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-metadata-dao-api/.project b/core/crce-metadata-dao-api/.project index 0d413bc0..7b6f96fd 100644 --- a/core/crce-metadata-dao-api/.project +++ b/core/crce-metadata-dao-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-metadata-impl/.project b/core/crce-metadata-impl/.project index 98a8b9f1..851b7d39 100644 --- a/core/crce-metadata-impl/.project +++ b/core/crce-metadata-impl/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-metadata-indexer-api/.project b/core/crce-metadata-indexer-api/.project index ec473ab8..8bf2e807 100644 --- a/core/crce-metadata-indexer-api/.project +++ b/core/crce-metadata-indexer-api/.project @@ -11,12 +11,12 @@ - org.eclipse.m2e.core.maven2Builder + org.fusesource.ide.project.RiderProjectBuilder - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder diff --git a/core/crce-metadata-indexer-impl/.project b/core/crce-metadata-indexer-impl/.project index 7393a095..0daf5752 100644 --- a/core/crce-metadata-indexer-impl/.project +++ b/core/crce-metadata-indexer-impl/.project @@ -11,12 +11,12 @@ - org.eclipse.m2e.core.maven2Builder + org.fusesource.ide.project.RiderProjectBuilder - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder diff --git a/core/crce-metadata-json-api/.project b/core/crce-metadata-json-api/.project index 5cca3097..88425d52 100644 --- a/core/crce-metadata-json-api/.project +++ b/core/crce-metadata-json-api/.project @@ -11,12 +11,12 @@ - org.eclipse.m2e.core.maven2Builder + org.fusesource.ide.project.RiderProjectBuilder - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder diff --git a/core/crce-metadata-json-impl/.project b/core/crce-metadata-json-impl/.project index 1e296590..4cb3aeed 100644 --- a/core/crce-metadata-json-impl/.project +++ b/core/crce-metadata-json-impl/.project @@ -11,12 +11,12 @@ - org.eclipse.m2e.core.maven2Builder + org.fusesource.ide.project.RiderProjectBuilder - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder diff --git a/core/crce-metadata-service-api/.project b/core/crce-metadata-service-api/.project index b10ca1c7..70e77ad8 100644 --- a/core/crce-metadata-service-api/.project +++ b/core/crce-metadata-service-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-metadata-service-impl/.project b/core/crce-metadata-service-impl/.project index 16872220..a50b870e 100644 --- a/core/crce-metadata-service-impl/.project +++ b/core/crce-metadata-service-impl/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-plugin-api/.project b/core/crce-plugin-api/.project index ec21180e..b8fae5ac 100644 --- a/core/crce-plugin-api/.project +++ b/core/crce-plugin-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-repository-api/.project b/core/crce-repository-api/.project index b42166de..dbe9c738 100644 --- a/core/crce-repository-api/.project +++ b/core/crce-repository-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-repository-impl/.project b/core/crce-repository-impl/.project index 9bb71646..823a8880 100644 --- a/core/crce-repository-impl/.project +++ b/core/crce-repository-impl/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-resolver-api/.project b/core/crce-resolver-api/.project index 33c424b1..11cff5eb 100644 --- a/core/crce-resolver-api/.project +++ b/core/crce-resolver-api/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/core/crce-resolver-impl/.project b/core/crce-resolver-impl/.project index 16bc7094..4dec77e2 100644 --- a/core/crce-resolver-impl/.project +++ b/core/crce-resolver-impl/.project @@ -15,11 +15,6 @@ - - org.eclipse.m2e.core.maven2Builder - - - org.fusesource.ide.project.RiderProjectBuilder @@ -40,6 +35,11 @@ + + org.eclipse.m2e.core.maven2Builder + + + org.eclipse.jem.workbench.JavaEMFNature diff --git a/modules/crce-concurrency/.project b/modules/crce-concurrency/.project index bbee7626..dd8ac919 100644 --- a/modules/crce-concurrency/.project +++ b/modules/crce-concurrency/.project @@ -11,12 +11,12 @@ - org.eclipse.m2e.core.maven2Builder + org.fusesource.ide.project.RiderProjectBuilder - org.fusesource.ide.project.RiderProjectBuilder + org.eclipse.m2e.core.maven2Builder diff --git a/modules/crce-external-repository/.classpath b/modules/crce-external-repository/.classpath index 9fe6a19d..ca4002ec 100644 --- a/modules/crce-external-repository/.classpath +++ b/modules/crce-external-repository/.classpath @@ -15,11 +15,13 @@ + + diff --git a/modules/crce-external-repository/META-INF/MANIFEST.MF b/modules/crce-external-repository/META-INF/MANIFEST.MF index efcc7627..d0d886cc 100644 --- a/modules/crce-external-repository/META-INF/MANIFEST.MF +++ b/modules/crce-external-repository/META-INF/MANIFEST.MF @@ -1,5 +1,5 @@ Manifest-Version: 1.0 -Bnd-LastModified: 1534335826009 +Bnd-LastModified: 1534761518531 Build-Jdk: 1.8.0_181 Built-By: rpesek Bundle-Activator: cz.zcu.kiv.crce.crce_external_repository.internal.Acti diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java index b77daeec..48afcde2 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java @@ -66,20 +66,26 @@ public CentralMavenForm(MyUI myUI) { directIndexOption.addItems("Direct", "Index"); directIndexOption.setValue("Direct"); - if (myUI.getSession().getAttribute("mavenIndex") == null) { + if (myUI.getSession().getAttribute("mavenIndex") == null + || myUI.getSession().getAttribute("settingsUrl") != null + && ((SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).isEnableGroupSearch()) { directIndexOption.setItemEnabled("Index", false); directIndexOption.setDescription( - "The central maven repository index is not created. Check its creation in the settings menu"); + "The central maven repository index is not created or it is allowed to search only by group. Check the settings menu"); } group.setRequired(true); group.setRequiredError("The item can not be empty!"); - artifact.setRequired(true); - artifact.setRequiredError("The item can not be empty!"); - version.setRequired(true); - version.setRequiredError("The item can not be empty!"); - packaging.setRequired(true); - packaging.setRequiredError("The item can not be empty!"); + + if (myUI.getSession().getAttribute("settingsUrl") == null + || !((SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).isEnableGroupSearch()) { + artifact.setRequired(true); + artifact.setRequiredError("The item can not be empty!"); + version.setRequired(true); + version.setRequiredError("The item can not be empty!"); + packaging.setRequired(true); + packaging.setRequiredError("The item can not be empty!"); + } rangeOption.addItem("<="); rangeOption.addItem("="); @@ -112,8 +118,23 @@ public CentralMavenForm(MyUI myUI) { if (content.getComponentIndex(formPanelButtonLayout) != -1) { content.removeComponent(formPanelButtonLayout); } - if (group.getValue().trim().isEmpty() || artifact.getValue().trim().isEmpty() - || version.getValue().trim().isEmpty() || packaging.getValue().trim().isEmpty()) { + // check filling form + if (myUI.getSession().getAttribute("settingsUrl") == null + && (group.getValue().trim().isEmpty() || artifact.getValue().trim().isEmpty() + || version.getValue().trim().isEmpty() || packaging.getValue().trim().isEmpty())) { + Notification notif = new Notification("Incomplete assignment!", Notification.Type.WARNING_MESSAGE); + notif.setDelayMsec(5000); + notif.show(Page.getCurrent()); + } else if (myUI.getSession().getAttribute("settingsUrl") != null + && !((SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).isEnableGroupSearch() + && (group.getValue().trim().isEmpty() || artifact.getValue().trim().isEmpty() + || version.getValue().trim().isEmpty() || packaging.getValue().trim().isEmpty())) { + Notification notif = new Notification("Incomplete assignment!", Notification.Type.WARNING_MESSAGE); + notif.setDelayMsec(5000); + notif.show(Page.getCurrent()); + } else if (myUI.getSession().getAttribute("settingsUrl") != null + && ((SettingsUrl) myUI.getSession().getAttribute("settingsUrl")).isEnableGroupSearch() + && group.getValue().trim().isEmpty()) { Notification notif = new Notification("Incomplete assignment!", Notification.Type.WARNING_MESSAGE); notif.setDelayMsec(5000); notif.show(Page.getCurrent()); @@ -236,7 +257,9 @@ else if (group.getValue().charAt(0) == '*' || group.getValue().charAt(0) == '?' content.addComponent(formPanelButtonLayout); }); - tree.addCollapseListener(e -> { + tree.addCollapseListener(e -> + + { uploadButton.setVisible(false); }); @@ -286,6 +309,7 @@ else if (group.getValue().charAt(0) == '*' || group.getValue().charAt(0) == '?' }); content.setSpacing(true); + addComponent(content); } From 232ebdbaa84f1274fd2c82b2ca2b8f74b604c7f8 Mon Sep 17 00:00:00 2001 From: rpesek Date: Tue, 21 Aug 2018 13:11:28 +0200 Subject: [PATCH 20/85] Small modification of the webui module (Path form in the Settings menu) - unification of names: local and Aether repositories --- modules/crce-external-repository/META-INF/MANIFEST.MF | 2 +- .../java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/crce-external-repository/META-INF/MANIFEST.MF b/modules/crce-external-repository/META-INF/MANIFEST.MF index d0d886cc..42e2100f 100644 --- a/modules/crce-external-repository/META-INF/MANIFEST.MF +++ b/modules/crce-external-repository/META-INF/MANIFEST.MF @@ -1,5 +1,5 @@ Manifest-Version: 1.0 -Bnd-LastModified: 1534761518531 +Bnd-LastModified: 1534849615952 Build-Jdk: 1.8.0_181 Built-By: rpesek Bundle-Activator: cz.zcu.kiv.crce.crce_external_repository.internal.Acti diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java index 5db64ec6..f96249f7 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/SettingsForm.java @@ -28,7 +28,7 @@ public SettingsForm() { public SettingsForm(VaadinSession session) { TextField centralMavenUrl = new TextField("Central Maven url"); - TextField localAetherRepo = new TextField("Local Aether repository"); + TextField localAetherRepo = new TextField("Local Maven repository"); CheckBox enableDeleteLocalMaven = new CheckBox("Enable delete local Maven repo"); CheckBox enableGroupSearch = new CheckBox("Enable only group search"); From 7720fc46182a58261d10c9c5094de066e382460f Mon Sep 17 00:00:00 2001 From: rpesek Date: Fri, 19 Oct 2018 13:09:52 +0200 Subject: [PATCH 21/85] solution request - show current buffer contents while in upload In the forms for uploading artifacts from an external storage, the current list of items in the temporary storage (buffer) --- README.md | 6 +- .../META-INF/MANIFEST.MF | 83 +++++++++---------- modules/crce-webui-v2/pom.xml | 2 +- .../crce_webui_v2/outer/CentralMavenForm.java | 81 ++++++++++++++---- .../crce_webui_v2/outer/DefinedMavenForm.java | 77 +++++++++++++---- .../crce_webui_v2/outer/LoadFileForm.java | 50 +++++++++-- .../crce_webui_v2/outer/LocalMavenForm.java | 43 +++++++++- .../kiv/crce/crce_webui_v2/webui/MyUI.java | 2 +- 8 files changed, 254 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 10ffa4aa..6fe0d4f4 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ CRCE is an experimental repository, designed to support research into component- ## Prerequisities -- **JDK 7** set in `JAVA_HOME` environment variable before starting CRCE (there is a problem with running web UI on JDK 8, need to update dependencies), tested on 1.7.0_80 +- **JDK 8** set in `JAVA_HOME` environment variable before starting CRCE, tested on 1.8.0_181 - **MongoDB**, tested on v2.6.10, v3.4.10 - **Maven 3**, tested on 3.5.2 -On linux, switching to JDK 7 for development/build can be done via `sudo update-alternatives --config java`. +On linux, switching to JDK 8 for development/build can be done via `sudo update-alternatives --config java`. ## Build @@ -47,7 +47,7 @@ The cause of the latter is a badly loaded binary of mathematical solver which do Started up, the application is accessible at: -- web UI: http://localhost:8080/crce +- web UI: http://localhost:8080/crce-webui - REST web services: http://localhost:8080/rest/v2/ Updated (more or less) REST WS documentation is available at [Apiary](https://crceapi.docs.apiary.io/). diff --git a/modules/crce-external-repository/META-INF/MANIFEST.MF b/modules/crce-external-repository/META-INF/MANIFEST.MF index 42e2100f..67837d33 100644 --- a/modules/crce-external-repository/META-INF/MANIFEST.MF +++ b/modules/crce-external-repository/META-INF/MANIFEST.MF @@ -1,5 +1,5 @@ Manifest-Version: 1.0 -Bnd-LastModified: 1534849615952 +Bnd-LastModified: 1539946583549 Build-Jdk: 1.8.0_181 Built-By: rpesek Bundle-Activator: cz.zcu.kiv.crce.crce_external_repository.internal.Acti @@ -76,45 +76,44 @@ Embedded-Artifacts: lib/aether-api-1.13.1.jar;g="org.sonatype.aether";a= memory";v="3.6.2",lib/lucene-highlighter-3.6.2.jar;g="org.apache.lucene ";a="lucene-highlighter";v="3.6.2",lib/javax.annotation-api-1.2.jar;g=" javax.annotation";a="javax.annotation-api";v="1.2" -Export-Package: cz.zcu.kiv.crce.crce_external_repository.api;uses:="org. - apache.maven.index";version="1.0.0",org.apache.maven.index;uses:="org.a - pache.maven.index.artifact,org.apache.maven.index.context,org.apache.ma - ven.index.expr";version="1.0.0",org.apache.maven.index.archetype;uses:= - "org.apache.maven.index.context";version="1.0.0",org.apache.maven.index - .artifact;version="1.0.0",org.apache.maven.index.context;uses:="org.apa - che.maven.index,org.apache.maven.index.artifact";version="1.0.0",org.ap - ache.maven.index.creator;uses:="org.apache.maven.index,org.apache.maven - .index.context";version="1.0.0",org.apache.maven.index.expr;uses:="org. - apache.maven.index";version="1.0.0",org.apache.maven.index.fs;version=" - 1.0.0",org.apache.maven.index.incremental;uses:="org.apache.maven.index - .packer,org.apache.maven.index.updater";version="1.0.0",org.apache.mave - n.index.locator;uses:="org.apache.maven.index.artifact";version="1.0.0" - ,org.apache.maven.index.packer;uses:="org.apache.maven.index.context";v - ersion="1.0.0",org.apache.maven.index.search.grouping;uses:="org.apache - .maven.index";version="1.0.0",org.apache.maven.index.treeview;uses:="or - g.apache.maven.index,org.apache.maven.index.context";version="1.0.0",or - g.apache.maven.index.updater;uses:="org.apache.maven.index.context,org. - apache.maven.index.fs,org.apache.maven.index.incremental,org.apache.mav - en.wagon,org.apache.maven.wagon.authentication,org.apache.maven.wagon.e - vents,org.apache.maven.wagon.proxy";version="1.0.0",org.apache.maven.in - dex.util;uses:="org.apache.maven.index.context";version="1.0.0",org.apa - che.maven.index.util.zip;version="1.0.0",org.apache.maven.wagon;uses:=" - org.apache.maven.wagon.authentication,org.apache.maven.wagon.authorizat - ion,org.apache.maven.wagon.events,org.apache.maven.wagon.proxy,org.apac - he.maven.wagon.repository,org.apache.maven.wagon.resource";version="1.0 - .0",org.apache.maven.wagon.authentication;uses:="org.apache.maven.wagon - ";version="1.0.0",org.apache.maven.wagon.authorization;uses:="org.apach - e.maven.wagon";version="1.0.0",org.apache.maven.wagon.events;uses:="org - .apache.maven.wagon,org.apache.maven.wagon.resource";version="1.0.0",or - g.apache.maven.wagon.observers;uses:="org.apache.maven.wagon.events";ve - rsion="1.0.0",org.apache.maven.wagon.providers.http;uses:="org.apache.m - aven.wagon,org.apache.maven.wagon.authentication,org.apache.maven.wagon - .authorization,org.apache.maven.wagon.proxy,org.apache.maven.wagon.reso - urce";version="1.0.0",org.apache.maven.wagon.proxy;version="1.0.0",org. - apache.maven.wagon.repository;version="1.0.0",org.apache.maven.wagon.re - source;version="1.0.0",org.apache.maven.wagon.shared.http4;uses:="org.a - pache.maven.wagon,org.apache.maven.wagon.authorization,org.apache.maven - .wagon.repository,org.apache.maven.wagon.resource";version="1.0.0",java - x.inject;version="1.0.0" -Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))" +Export-Package: org.apache.maven.index;uses:="org.apache.maven.index.art + ifact,org.apache.maven.index.context,org.apache.maven.index.expr";versi + on="1.0.0",org.apache.maven.index.archetype;uses:="org.apache.maven.ind + ex.context";version="1.0.0",org.apache.maven.index.artifact;version="1. + 0.0",org.apache.maven.index.context;uses:="org.apache.maven.index,org.a + pache.maven.index.artifact";version="1.0.0",org.apache.maven.index.crea + tor;uses:="org.apache.maven.index,org.apache.maven.index.context";versi + on="1.0.0",org.apache.maven.index.expr;uses:="org.apache.maven.index";v + ersion="1.0.0",org.apache.maven.index.fs;version="1.0.0",org.apache.mav + en.index.incremental;uses:="org.apache.maven.index.packer,org.apache.ma + ven.index.updater";version="1.0.0",org.apache.maven.index.locator;uses: + ="org.apache.maven.index.artifact";version="1.0.0",org.apache.maven.ind + ex.packer;uses:="org.apache.maven.index.context";version="1.0.0",org.ap + ache.maven.index.search.grouping;uses:="org.apache.maven.index";version + ="1.0.0",org.apache.maven.index.treeview;uses:="org.apache.maven.index, + org.apache.maven.index.context";version="1.0.0",org.apache.maven.index. + updater;uses:="org.apache.maven.index.context,org.apache.maven.index.fs + ,org.apache.maven.index.incremental,org.apache.maven.wagon,org.apache.m + aven.wagon.authentication,org.apache.maven.wagon.events,org.apache.mave + n.wagon.proxy";version="1.0.0",org.apache.maven.index.util;uses:="org.a + pache.maven.index.context";version="1.0.0",org.apache.maven.index.util. + zip;version="1.0.0",org.apache.maven.wagon;uses:="org.apache.maven.wago + n.authentication,org.apache.maven.wagon.authorization,org.apache.maven. + wagon.events,org.apache.maven.wagon.proxy,org.apache.maven.wagon.reposi + tory,org.apache.maven.wagon.resource";version="1.0.0",org.apache.maven. + wagon.authentication;uses:="org.apache.maven.wagon";version="1.0.0",org + .apache.maven.wagon.authorization;uses:="org.apache.maven.wagon";versio + n="1.0.0",org.apache.maven.wagon.events;uses:="org.apache.maven.wagon,o + rg.apache.maven.wagon.resource";version="1.0.0",org.apache.maven.wagon. + observers;uses:="org.apache.maven.wagon.events";version="1.0.0",org.apa + che.maven.wagon.providers.http;uses:="org.apache.maven.wagon,org.apache + .maven.wagon.authentication,org.apache.maven.wagon.authorization,org.ap + ache.maven.wagon.proxy,org.apache.maven.wagon.resource";version="1.0.0" + ,org.apache.maven.wagon.proxy;version="1.0.0",org.apache.maven.wagon.re + pository;version="1.0.0",org.apache.maven.wagon.resource;version="1.0.0 + ",org.apache.maven.wagon.shared.http4;uses:="org.apache.maven.wagon,org + .apache.maven.wagon.authorization,org.apache.maven.wagon.repository,org + .apache.maven.wagon.resource";version="1.0.0",javax.inject;version="1.0 + .0",cz.zcu.kiv.crce.crce_external_repository.api;version="1.0.0" +Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))" Tool: Bnd-3.3.0.201609221906 diff --git a/modules/crce-webui-v2/pom.xml b/modules/crce-webui-v2/pom.xml index 4b9fe496..db6b0cda 100644 --- a/modules/crce-webui-v2/pom.xml +++ b/modules/crce-webui-v2/pom.xml @@ -12,7 +12,7 @@ crce-webui-v2 war - 1.3 + 1.4 CRCE - Web UI diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java index 48afcde2..20a72ae4 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/CentralMavenForm.java @@ -4,7 +4,9 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.List; +import com.vaadin.data.util.BeanItemContainer; import com.vaadin.server.FontAwesome; import com.vaadin.server.Page; import com.vaadin.shared.Position; @@ -12,6 +14,7 @@ import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Grid; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.NativeSelect; @@ -21,6 +24,7 @@ import com.vaadin.ui.TextField; import com.vaadin.ui.Tree; import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Grid.SelectionMode; import com.vaadin.ui.themes.ValoTheme; import cz.zcu.kiv.crce.crce_external_repository.api.ArtifactTree; @@ -28,12 +32,15 @@ import cz.zcu.kiv.crce.crce_external_repository.api.ResultSearchArtifactTree; import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_v2.repository.services.ResourceService; import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; import cz.zcu.kiv.crce.repository.RefusedArtifactException; @SuppressWarnings("serial") public class CentralMavenForm extends FormLayout { private Label caption = new Label("Central Maven repository"); + private Panel formPanel = new Panel("Content"); private TextField group = new TextField("Group Id"); private TextField artifact = new TextField("Artifact Id"); private TextField version = new TextField("Version"); @@ -46,6 +53,10 @@ public class CentralMavenForm extends FormLayout { private Panel treePanel = new Panel("Result list"); private Button uploadButton = new Button("Upload"); private Tree tree = new Tree(); + private VerticalLayout bufferLayout = new VerticalLayout(); + private Panel bufferPanel = new Panel("Buffer"); + private Grid bufferGrid = new Grid(); + private ResourceService resourceService; public CentralMavenForm() { HorizontalLayout content = new HorizontalLayout(); @@ -54,9 +65,10 @@ public CentralMavenForm() { public CentralMavenForm(MyUI myUI) { VerticalLayout userForm = new VerticalLayout(); - HorizontalLayout content = new HorizontalLayout(); HorizontalLayout versionLayout = new HorizontalLayout(); VerticalLayout formPanelButtonLayout = new VerticalLayout(); + HorizontalLayout contentForm = new HorizontalLayout(); + VerticalLayout content = new VerticalLayout(); caption.addStyleName(ValoTheme.LABEL_BOLD); @@ -101,22 +113,48 @@ public CentralMavenForm(MyUI myUI) { HorizontalLayout buttons = new HorizontalLayout(searchButton, clearButton); buttons.setSpacing(true); - userForm.addComponents(caption, group, artifact, versionLayout, packaging, directIndexOption, buttons); + userForm.addComponents(group, artifact, versionLayout, packaging, directIndexOption, buttons); userForm.setSpacing(true); - userForm.setMargin(new MarginInfo(false, true)); treePanel.setWidth("600px"); treePanel.setHeight("380px"); - content.addComponent(userForm); + contentForm.addComponent(userForm); + contentForm.setMargin(true); + formPanel.setContent(contentForm); + formPanel.setHeight("570px"); + + resourceService = new ResourceService(Activator.instance().getMetadataService()); + List resourceBeanList = resourceService.getAllResourceBeanFromBuffer(myUI.getSession().getSession()); + + HorizontalLayout bufferPanelLayout = new HorizontalLayout(); + bufferGrid.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, resourceBeanList)); + bufferGrid.getColumn("resource").setHidden(true); + bufferGrid.getColumn("size").setHidden(true); + bufferGrid.setColumnOrder("presentationName", "symbolicName", "version", "categories"); + bufferGrid.addStyleName("my-style"); + bufferGrid.setSelectionMode(SelectionMode.NONE); + bufferLayout.addComponent(bufferGrid); + bufferGrid.setSizeFull(); + bufferPanelLayout.setSizeFull(); + bufferPanelLayout.addComponent(bufferLayout); + bufferPanelLayout.setExpandRatio(bufferLayout, 1); + bufferPanel.setContent(bufferPanelLayout); + + if(!resourceBeanList.isEmpty()) { + bufferPanel.setVisible(true); + } + else { + bufferPanel.setVisible(false); + } // Add tree searchButton.addClickListener(e -> { // clear tree tree.removeAllItems(); // no function tree.clear(); // erasing any previous components shown - if (content.getComponentIndex(formPanelButtonLayout) != -1) { - content.removeComponent(formPanelButtonLayout); + if (contentForm.getComponentIndex(formPanelButtonLayout) != -1) { + contentForm.removeComponent(formPanelButtonLayout); } // check filling form if (myUI.getSession().getAttribute("settingsUrl") == null @@ -164,7 +202,7 @@ public CentralMavenForm(MyUI myUI) { treePanelLayout.setMargin(true); treePanel.setContent(treePanelLayout); formPanelButtonLayout.addComponents(treePanel, uploadButton); - formPanelButtonLayout.setMargin(true); + formPanelButtonLayout.setMargin(new MarginInfo(false, true)); formPanelButtonLayout.setSpacing(true); formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); uploadButton.setVisible(false); @@ -194,7 +232,7 @@ public CentralMavenForm(MyUI myUI) { treePanelLayout.setMargin(true); treePanel.setContent(treePanelLayout); formPanelButtonLayout.addComponents(treePanel, uploadButton); - formPanelButtonLayout.setMargin(true); + //formPanelButtonLayout.setMargin(true); formPanelButtonLayout.setSpacing(true); formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); uploadButton.setVisible(false); @@ -205,7 +243,7 @@ public CentralMavenForm(MyUI myUI) { treePanelLayout.setMargin(true); treePanel.setContent(treePanelLayout); formPanelButtonLayout.addComponents(treePanel); - formPanelButtonLayout.setMargin(true); + formPanelButtonLayout.setMargin(new MarginInfo(false, true)); } } // index search @@ -240,7 +278,7 @@ else if (group.getValue().charAt(0) == '*' || group.getValue().charAt(0) == '?' treePanelLayout.setMargin(true); treePanel.setContent(treePanelLayout); formPanelButtonLayout.addComponents(treePanel, uploadButton); - formPanelButtonLayout.setMargin(true); + formPanelButtonLayout.setMargin(new MarginInfo(false, true)); formPanelButtonLayout.setSpacing(true); formPanelButtonLayout.setComponentAlignment(uploadButton, Alignment.BOTTOM_CENTER); uploadButton.setVisible(false); @@ -250,16 +288,15 @@ else if (group.getValue().charAt(0) == '*' || group.getValue().charAt(0) == '?' treePanelLayout.setMargin(true); treePanel.setContent(treePanelLayout); formPanelButtonLayout.addComponents(treePanel); - formPanelButtonLayout.setMargin(true); + formPanelButtonLayout.setMargin(new MarginInfo(false, true)); } } } - content.addComponent(formPanelButtonLayout); + contentForm.addComponent(formPanelButtonLayout); + contentForm.setSpacing(true); }); - tree.addCollapseListener(e -> - - { + tree.addCollapseListener(e -> { uploadButton.setVisible(false); }); @@ -275,6 +312,11 @@ else if (group.getValue().charAt(0) == '*' || group.getValue().charAt(0) == '?' file = new File(url.toString()); InputStream input = url.openStream(); Activator.instance().getBuffer(myUI.getSession().getSession()).put(file.getName(), input); + bufferLayout.removeComponent(bufferGrid); + bufferGrid.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, + resourceService.getAllResourceBeanFromBuffer(myUI.getSession().getSession()))); + bufferLayout.addComponent(bufferGrid); + bufferPanel.setVisible(true); Notification notif = new Notification("Info", "Artefact from central maven upload sucess", Notification.Type.ASSISTIVE_NOTIFICATION); notif.setPosition(Position.TOP_RIGHT); @@ -299,17 +341,20 @@ else if (group.getValue().charAt(0) == '*' || group.getValue().charAt(0) == '?' // Clear user form clearButton.addClickListener(e -> { formPanelButtonLayout.removeAllComponents(); - content.removeAllComponents(); + contentForm.removeAllComponents(); group.clear(); artifact.clear(); version.clear(); packaging.clear(); tree.removeAllItems(); - content.addComponent(userForm); + contentForm.addComponent(userForm); }); + + content.addComponents(caption, formPanel, bufferPanel); content.setSpacing(true); - + content.setMargin(new MarginInfo(false, true)); + addComponent(content); } diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/DefinedMavenForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/DefinedMavenForm.java index a1e58bdd..7bac9e32 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/DefinedMavenForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/DefinedMavenForm.java @@ -5,8 +5,9 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.StandardOpenOption; -//import java.util.EnumSet; +import java.util.List; +import com.vaadin.data.util.BeanItemContainer; import com.vaadin.server.FontAwesome; import com.vaadin.server.Page; import com.vaadin.shared.Position; @@ -15,33 +16,35 @@ import com.vaadin.ui.Button; import com.vaadin.ui.CssLayout; import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Grid; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; -//import com.vaadin.ui.NativeSelect; import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; import com.vaadin.ui.TextField; import com.vaadin.ui.Tree; import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Grid.SelectionMode; import com.vaadin.ui.themes.ValoTheme; import cz.zcu.kiv.crce.crce_external_repository.api.ArtifactTree; import cz.zcu.kiv.crce.crce_external_repository.api.DefinedMaven; import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; -//import cz.zcu.kiv.crce.crce_webui_v2.other.TypePackaging; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_v2.repository.services.ResourceService; import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; import cz.zcu.kiv.crce.repository.RefusedArtifactException; -public class DefinedMavenForm extends FormLayout { +public class DefinedMavenForm extends FormLayout{ private static final long serialVersionUID = 4172878715304331198L; private transient DefinedMaven definedMaven; + private Panel formPanel = new Panel("Content"); private TextField definedUrl = new TextField(); private Label caption = new Label("Defined Maven repository"); private TextField group = new TextField("Group Id"); private TextField artifact = new TextField("Artifact Id"); private TextField version = new TextField("Version"); - // private NativeSelect packaging = new NativeSelect("Packaging"); private TextField packaging = new TextField("Packaging"); private Button searchButton = new Button("Search"); private Button clearButton = new Button("Clear"); @@ -50,7 +53,11 @@ public class DefinedMavenForm extends FormLayout { private Panel treePanel = new Panel("Result list"); private Label notFound = new Label("No artifact found"); private Tree tree; - + private VerticalLayout bufferLayout = new VerticalLayout(); + private Panel bufferPanel = new Panel("Buffer"); + private Grid bufferGrid = new Grid(); + private ResourceService resourceService; + public DefinedMavenForm() { HorizontalLayout content = new HorizontalLayout(); addComponent(content); @@ -70,16 +77,13 @@ public DefinedMavenForm(MyUI myUI) { HorizontalLayout buttonUploadResolveLayout = new HorizontalLayout(); HorizontalLayout treeLayout = new HorizontalLayout(); VerticalLayout formLayout = new VerticalLayout(); - HorizontalLayout content = new HorizontalLayout(); + HorizontalLayout contentForm = new HorizontalLayout(); + VerticalLayout content = new VerticalLayout(); caption.addStyleName(ValoTheme.LABEL_BOLD); definedUrl.setWidth("450px"); - // packaging.addItems(EnumSet.allOf(TypePackaging.class)); - // packaging.select(TypePackaging.jar); - // packaging.setNullSelectionAllowed(false); - group.setRequired(true); group.setRequiredError("The item can not be empty!"); artifact.setRequired(true); @@ -117,12 +121,47 @@ public DefinedMavenForm(MyUI myUI) { treePanelLayout.addComponents(fieldLayout, treePanelButtonLayout); treePanelLayout.setSpacing(true); - - formLayout.addComponents(caption, definedCss, treePanelLayout); + + formLayout.addComponents(definedCss, treePanelLayout); formLayout.setSpacing(true); - formLayout.setMargin(new MarginInfo(false, true)); - - content.addComponents(formLayout); + formLayout.setMargin(true); + formLayout.addComponents(definedCss, treePanelLayout); + + formPanel.setContent(formLayout); + formPanel.setHeight("500px"); + + contentForm.addComponents(formPanel); + + resourceService = new ResourceService(Activator.instance().getMetadataService()); + List resourceBeanList = resourceService.getAllResourceBeanFromBuffer(myUI.getSession().getSession()); + + HorizontalLayout bufferPanelLayout = new HorizontalLayout(); + bufferGrid.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, resourceBeanList)); + bufferGrid.getColumn("resource").setHidden(true); + bufferGrid.getColumn("size").setHidden(true); + bufferGrid.setColumnOrder("presentationName", "symbolicName", "version", "categories"); + bufferGrid.addStyleName("my-style"); + bufferGrid.setSelectionMode(SelectionMode.NONE); + bufferLayout.addComponent(bufferGrid); + bufferGrid.setSizeFull(); + bufferPanelLayout.setSizeFull(); + bufferPanelLayout.addComponent(bufferLayout); + bufferPanelLayout.setExpandRatio(bufferLayout, 1); + bufferPanel.setContent(bufferPanelLayout); + + if(!resourceBeanList.isEmpty()) { + bufferPanel.setVisible(true); + } + else { + bufferPanel.setVisible(false); + } + + content.addComponents(caption, contentForm, bufferPanel); + + contentForm.setSpacing(true); + contentForm.setSizeFull(); + content.setSpacing(true); + content.setMargin(new MarginInfo(false, true)); // Setting url defined repository setUrl.addClickListener(e -> { @@ -237,6 +276,11 @@ public DefinedMavenForm(MyUI myUI) { InputStream is = Files.newInputStream(file.toPath(), StandardOpenOption.READ); try { Activator.instance().getBuffer(myUI.getSession().getSession()).put(file.getName(), is); + bufferLayout.removeComponent(bufferGrid); + bufferGrid.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, + resourceService.getAllResourceBeanFromBuffer(myUI.getSession().getSession()))); + bufferLayout.addComponent(bufferGrid); + bufferPanel.setVisible(true); Notification notif = new Notification("Info", "Artifact to buffer upload sucess", Notification.Type.ASSISTIVE_NOTIFICATION); notif.setPosition(Position.TOP_RIGHT); @@ -281,7 +325,6 @@ public DefinedMavenForm(MyUI myUI) { } }); - content.setSpacing(true); addComponent(content); } diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LoadFileForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LoadFileForm.java index dc357130..3a942e1f 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LoadFileForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LoadFileForm.java @@ -9,13 +9,15 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.StandardOpenOption; +import java.util.List; +import com.vaadin.data.util.BeanItemContainer; import com.vaadin.server.Page; -import com.vaadin.server.VaadinSession; import com.vaadin.shared.Position; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.ui.Button; import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Grid; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; @@ -25,18 +27,26 @@ import com.vaadin.ui.Upload.SucceededEvent; import com.vaadin.ui.Upload.SucceededListener; import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Grid.SelectionMode; import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_v2.repository.services.ResourceService; +import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; import cz.zcu.kiv.crce.repository.RefusedArtifactException; @SuppressWarnings("serial") public class LoadFileForm extends FormLayout { - private VaadinSession session; + //private VaadinSession session; private Panel filePanel = new Panel("Upload artefact from local file system"); private Panel urlPanel = new Panel("Upload artefact from remote url"); + private Panel bufferPanel = new Panel("Buffer"); + private Grid bufferGrid = new Grid(); + private ResourceService resourceService; + private MyUI myUI; - public LoadFileForm(VaadinSession session){ - this.session = session; + public LoadFileForm(MyUI myUI){ + this.myUI = myUI; VerticalLayout content = new VerticalLayout(); HorizontalLayout fileLayout = new HorizontalLayout(); HorizontalLayout urlLayout = new HorizontalLayout(); @@ -61,7 +71,31 @@ public LoadFileForm(VaadinSession session){ fileLayout.setHeight("300px"); filePanel.setContent(fileLayout); - content.addComponents(filePanel, urlPanel); + resourceService = new ResourceService(Activator.instance().getMetadataService()); + List resourceBeanList = resourceService.getAllResourceBeanFromBuffer(myUI.getSession().getSession()); + + if(!resourceBeanList.isEmpty()) { + HorizontalLayout bufferPanelLayout = new HorizontalLayout(); + VerticalLayout bufferLayout = new VerticalLayout(); + bufferGrid.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, resourceBeanList)); + bufferGrid.getColumn("resource").setHidden(true); + bufferGrid.getColumn("size").setHidden(true); + bufferGrid.setColumnOrder("presentationName", "symbolicName", "version", "categories"); + bufferGrid.addStyleName("my-style"); + bufferGrid.setSelectionMode(SelectionMode.NONE); + bufferLayout.addComponent(bufferGrid); + bufferGrid.setSizeFull(); + bufferPanelLayout.setSizeFull(); + bufferPanelLayout.addComponent(bufferLayout); + bufferPanelLayout.setExpandRatio(bufferLayout, 1); + bufferPanel.setContent(bufferPanelLayout); + + content.addComponents(filePanel, urlPanel, bufferPanel); + } + else { + content.addComponents(filePanel, urlPanel); + } + content.setMargin(new MarginInfo(false, true, false, false)); content.setSpacing(true); @@ -71,11 +105,12 @@ public LoadFileForm(VaadinSession session){ URL url = new URL(urlText.getValue()); file = new File(url.toString()); InputStream input = url.openStream(); - Activator.instance().getBuffer(session.getSession()).put(file.getName(), input); + Activator.instance().getBuffer(myUI.getSession().getSession()).put(file.getName(), input); Notification notif = new Notification("Info", "Artefact from url upload sucess", Notification.Type.ASSISTIVE_NOTIFICATION); notif.setPosition(Position.TOP_RIGHT); notif.show(Page.getCurrent()); + myUI.setContentBodyLoadFile(); } catch (IOException | RefusedArtifactException ex) { new Notification("Could not open or load file from url", ex.getMessage(), Notification.Type.ERROR_MESSAGE) .show(Page.getCurrent()); @@ -102,12 +137,13 @@ public OutputStream receiveUpload(String filename, String mimeType) { public void uploadSucceeded(SucceededEvent event) { try { - Activator.instance().getBuffer(session.getSession()) + Activator.instance().getBuffer(myUI.getSession().getSession()) .put(file.getName(), Files.newInputStream(file.toPath(), StandardOpenOption.READ)); Notification notif = new Notification("Info", "Artefact from file upload sucess", Notification.Type.ASSISTIVE_NOTIFICATION); notif.setPosition(Position.TOP_RIGHT); notif.show(Page.getCurrent()); + myUI.setContentBodyLoadFile(); } catch (IOException | RefusedArtifactException e) { new Notification("Could not open or load file", e.getMessage(), Notification.Type.ERROR_MESSAGE) .show(Page.getCurrent()); diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LocalMavenForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LocalMavenForm.java index 88689adc..b39f51bd 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LocalMavenForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/outer/LocalMavenForm.java @@ -9,13 +9,17 @@ import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardOpenOption; import java.nio.file.attribute.BasicFileAttributes; +import java.util.List; +import com.vaadin.data.util.BeanItemContainer; import com.vaadin.server.Page; import com.vaadin.shared.Position; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Panel; @@ -27,6 +31,8 @@ import cz.zcu.kiv.crce.crce_external_repository.api.SettingsUrl; import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; import cz.zcu.kiv.crce.crce_webui_v2.outer.classes.LocalMaven; +import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_v2.repository.services.ResourceService; import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; import cz.zcu.kiv.crce.repository.RefusedArtifactException; @@ -35,6 +41,10 @@ public class LocalMavenForm extends FormLayout { private LocalMaven localMaven = new LocalMaven(); private Label caption = new Label("Local Maven repository"); private Panel formPanel = new Panel("Content"); + private VerticalLayout bufferLayout = new VerticalLayout(); + private Panel bufferPanel = new Panel("Buffer"); + private Grid bufferGrid = new Grid(); + private ResourceService resourceService; private Button uploadButton = new Button("Upload"); private Button removeButton = new Button("Remove"); @@ -73,7 +83,33 @@ public LocalMavenForm(MyUI myUI) { treeLayout.setMargin(true); formPanel.setContent(treeLayout); formPanel.setHeight("500px"); - formLayout.addComponents(caption, formPanel, buttons); + + resourceService = new ResourceService(Activator.instance().getMetadataService()); + List resourceBeanList = resourceService.getAllResourceBeanFromBuffer(myUI.getSession().getSession()); + + HorizontalLayout bufferPanelLayout = new HorizontalLayout(); + bufferGrid.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, resourceBeanList)); + bufferGrid.getColumn("resource").setHidden(true); + bufferGrid.getColumn("size").setHidden(true); + bufferGrid.setColumnOrder("presentationName", "symbolicName", "version", "categories"); + bufferGrid.addStyleName("my-style"); + bufferGrid.setSelectionMode(SelectionMode.NONE); + bufferLayout.addComponent(bufferGrid); + bufferGrid.setSizeFull(); + bufferPanelLayout.setSizeFull(); + bufferPanelLayout.addComponent(bufferLayout); + bufferPanelLayout.setExpandRatio(bufferLayout, 1); + bufferPanel.setContent(bufferPanelLayout); + + formLayout.addComponents(caption, formPanel, buttons, bufferPanel); + + if(!resourceBeanList.isEmpty()) { + bufferPanel.setVisible(true); + } + else { + bufferPanel.setVisible(false); + } + formLayout.setSpacing(true); formLayout.setComponentAlignment(buttons, Alignment.BOTTOM_CENTER); content.addComponents(formLayout); @@ -118,6 +154,11 @@ public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOEx InputStream is = Files.newInputStream(file.toPath(), StandardOpenOption.READ); try { Activator.instance().getBuffer(myUI.getSession().getSession()).put(file.getName(), is); + bufferLayout.removeComponent(bufferGrid); + bufferGrid.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, + resourceService.getAllResourceBeanFromBuffer(myUI.getSession().getSession()))); + bufferLayout.addComponent(bufferGrid); + bufferPanel.setVisible(true); Notification notif = new Notification("Info", "Artifact to buffer upload sucess", Notification.Type.ASSISTIVE_NOTIFICATION); notif.setPosition(Position.TOP_RIGHT); diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MyUI.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MyUI.java index 4676eda7..c2736ba8 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MyUI.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MyUI.java @@ -128,7 +128,7 @@ public void setContentBodyDefinedMaven(){ } public void setContentBodyLoadFile(){ - loadFileForm = new LoadFileForm(this.getSession()); + loadFileForm = new LoadFileForm(this); body.setContent(loadFileForm); } From 636c8e6839b4f14b67df5dac4821432fc9783776 Mon Sep 17 00:00:00 2001 From: rpesek Date: Wed, 24 Oct 2018 12:06:53 +0200 Subject: [PATCH 22/85] Fix - BuferForm, StoreForm in the module webui-v2 - clears items in the Buffer and displays the capabilities, requirements of artifacts in the Store - little improvements --- .../filebased/internal/BufferImpl.java | 2 +- .../internal/FilebasedStoreImpl.java | 4 +- .../META-INF/MANIFEST.MF | 4 +- modules/crce-webui-v2/pom.xml | 117 ------------------ .../repository/ArtefactDetailForm.java | 10 +- .../crce_webui_v2/repository/BufferForm.java | 1 + .../repository/NewCapabilityForm.java | 44 ------- .../repository/PluginEditForm.java | 11 +- .../repository/services/ResourceService.java | 11 ++ .../kiv/crce/crce_webui_v2/webui/MyUI.java | 11 +- 10 files changed, 30 insertions(+), 185 deletions(-) delete mode 100644 modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/NewCapabilityForm.java diff --git a/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/BufferImpl.java b/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/BufferImpl.java index e66271b6..2de915ea 100644 --- a/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/BufferImpl.java +++ b/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/BufferImpl.java @@ -421,6 +421,6 @@ private boolean isInBuffer(Resource resource) { if (!"file".equals(uri.getScheme())) { return false; } - return new File(uri).getPath().startsWith(baseDir.getAbsolutePath()); + return true; //new File(uri).getPath().startsWith(baseDir.getAbsolutePath()); } } diff --git a/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/FilebasedStoreImpl.java b/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/FilebasedStoreImpl.java index 668bc101..d787f0a9 100644 --- a/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/FilebasedStoreImpl.java +++ b/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/FilebasedStoreImpl.java @@ -285,7 +285,9 @@ public Resource getResource(String uid, boolean withDetails) { @Override public synchronized List getResources() { try { - return metadataDao.loadResources(repository, false); + // Edit rpesek - For webui-v2 retrieval of resources including details (capabilities, requirements) + // return metadataDao.loadResources(repository, false); + return metadataDao.loadResources(repository, true); } catch (IOException e) { logger.error("Could not load resources of repository {}.", baseDir.toURI(), e); } diff --git a/modules/crce-external-repository/META-INF/MANIFEST.MF b/modules/crce-external-repository/META-INF/MANIFEST.MF index 67837d33..73019f3c 100644 --- a/modules/crce-external-repository/META-INF/MANIFEST.MF +++ b/modules/crce-external-repository/META-INF/MANIFEST.MF @@ -1,6 +1,6 @@ Manifest-Version: 1.0 -Bnd-LastModified: 1539946583549 -Build-Jdk: 1.8.0_181 +Bnd-LastModified: 1540375086909 +Build-Jdk: 1.8.0_191 Built-By: rpesek Bundle-Activator: cz.zcu.kiv.crce.crce_external_repository.internal.Acti vator diff --git a/modules/crce-webui-v2/pom.xml b/modules/crce-webui-v2/pom.xml index db6b0cda..2893a0ad 100644 --- a/modules/crce-webui-v2/pom.xml +++ b/modules/crce-webui-v2/pom.xml @@ -48,71 +48,6 @@ pom import - @@ -138,58 +73,6 @@ com.vaadin vaadin-themes - cz.zcu.kiv.crce crce-metadata-osgi-bundle diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/ArtefactDetailForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/ArtefactDetailForm.java index 2eecdf6d..46a38a26 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/ArtefactDetailForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/ArtefactDetailForm.java @@ -31,8 +31,6 @@ public class ArtefactDetailForm extends FormLayout{ private Button buttonBackProperties = new Button("Back"); private Button buttonBackCapabilities = new Button("Back"); private Button buttonBackRequirements = new Button("Back"); - private Button buttonAddCapability = new Button("Add capability"); - private Button buttonAddRequirements = new Button("Add requirement"); private Grid gridCapabilities = new Grid(); private Grid gridRequirements = new Grid(); @@ -65,7 +63,7 @@ public ArtefactDetailForm(MyUI myUI, ResourceBean resourceBean, boolean isFromSt VerticalLayout capabilityContentLayout = new VerticalLayout(); VerticalLayout capabilityTabLayout = new VerticalLayout(); HorizontalLayout buttonCapabilityLayout = new HorizontalLayout(); - buttonCapabilityLayout.addComponents(buttonAddCapability, buttonBackCapabilities); + buttonCapabilityLayout.addComponents(buttonBackCapabilities); buttonCapabilityLayout.setSpacing(true); buttonBackCapabilities.setWidth("130px"); @@ -96,15 +94,11 @@ public ArtefactDetailForm(MyUI myUI, ResourceBean resourceBean, boolean isFromSt capabilityContentLayout.setSpacing(true); capabilityContentLayout.setMargin(new MarginInfo(true, false)); - buttonAddCapability.addClickListener(e ->{ - myUI.setContentNewCapabilityForm(resourceBean, isFromStore); - }); - // display requirement VerticalLayout requirementContentLayout = new VerticalLayout(); VerticalLayout requirementTabLayout = new VerticalLayout(); HorizontalLayout buttonRequirementLayout = new HorizontalLayout(); - buttonRequirementLayout.addComponents(buttonAddRequirements, buttonBackRequirements); + buttonRequirementLayout.addComponents(buttonBackRequirements); buttonRequirementLayout.setSpacing(true); buttonBackRequirements.setWidth("130px"); diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/BufferForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/BufferForm.java index 2c62df45..ce401b1e 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/BufferForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/BufferForm.java @@ -72,6 +72,7 @@ public BufferForm(MyUI myUI){ gridBuffer.setContainerDataSource(new BeanItemContainer<>(ResourceBean.class, resourceService.getFindResourceBeanFromBuffer(myUI.getSession().getSession(), idText.getValue()))); }); + Button clearButton = new Button(FontAwesome.TIMES); clearButton.addClickListener(e -> { myUI.setContentBodyBuffer(); diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/NewCapabilityForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/NewCapabilityForm.java deleted file mode 100644 index 43b4d82d..00000000 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/NewCapabilityForm.java +++ /dev/null @@ -1,44 +0,0 @@ -package cz.zcu.kiv.crce.crce_webui_v2.repository; - -import com.vaadin.event.ShortcutAction.KeyCode; -import com.vaadin.shared.ui.MarginInfo; -import com.vaadin.ui.Button; -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.themes.ValoTheme; - -import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; -import cz.zcu.kiv.crce.crce_webui_v2.webui.MyUI; - -@SuppressWarnings("serial") -public class NewCapabilityForm extends FormLayout{ - private Label labelForm = new Label("Add new capability"); - private Button buttonSave = new Button("Save"); - private Button buttonCancel = new Button("Cancel"); - public NewCapabilityForm(MyUI myUI, ResourceBean resourceBean, boolean isFromStore){ - VerticalLayout content = new VerticalLayout(); - HorizontalLayout buttonLayout = new HorizontalLayout(); - - labelForm.addStyleName(ValoTheme.LABEL_BOLD); - - buttonSave.setStyleName(ValoTheme.BUTTON_PRIMARY); - buttonSave.setClickShortcut(KeyCode.ENTER); - buttonLayout.addComponents(buttonSave, buttonCancel); - buttonLayout.setSpacing(true); - - buttonSave.addClickListener(e ->{ - - }); - - buttonCancel.addClickListener(e ->{ - myUI.setContentArtefactDetailForm(resourceBean, isFromStore); - }); - - content.addComponents(labelForm, buttonLayout); - content.setSpacing(true); - content.setMargin(new MarginInfo(true, false)); - addComponent(content); - } -} diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/PluginEditForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/PluginEditForm.java index 0ec98eac..ac164468 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/PluginEditForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/PluginEditForm.java @@ -23,7 +23,7 @@ public class PluginEditForm extends FormLayout{ private Label labelKeyWords = new Label("Plugin key words"); private Grid gridKeyWords = new Grid(); private TextField priority = new TextField("Priority"); - private TextField version = new TextField("Version"); + //private TextField version = new TextField("Version"); private Button editButton = new Button("Edit"); private Plugin plugin; public PluginEditForm(PluginsForm pluginsForm){ @@ -50,13 +50,14 @@ public PluginEditForm(PluginsForm pluginsForm){ priority.setRequiredError("Item can not be empty!"); priority.addValidator(new StringLengthValidator("Item must have " + nameMaxLenght + " characters!", 1, nameMaxLenght, false)); - version.setWidth("200px"); + /*version.setWidth("200px"); version.setRequired(true); version.setRequiredError("Item can not be empty!"); version.addValidator(new StringLengthValidator("Item must have " + nameMaxLenght + " characters!", 1, - nameMaxLenght, false)); + nameMaxLenght, false));*/ - editLayout.addComponents(priority, version, editButton); + //editLayout.addComponents(priority, version, editButton); + editLayout.addComponents(priority, editButton); editLayout.setSpacing(true); content.addComponents(keyWordLayout, editLayout); @@ -82,7 +83,7 @@ public void setPlugin(Plugin plugin) { gridKeyWords.setContainerDataSource(new BeanItemContainer<>(KeyWord.class, keyWordList)); } priority.setValue(plugin.getPluginPriority() + ""); - version.setValue(plugin.getPluginVersion().toString()); + //version.setValue(plugin.getPluginVersion().toString()); setVisible(true); } } \ No newline at end of file diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/services/ResourceService.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/services/ResourceService.java index 7ef61394..7b0bddf2 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/services/ResourceService.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/services/ResourceService.java @@ -89,6 +89,17 @@ public boolean removeResourceFromBuffer(WrappedSession wSession, Resource resour return result; } + public void clearBuffer(WrappedSession wSession) { + try { + for(Resource r : Activator.instance().getBuffer(wSession).getResources()) { + Activator.instance().getBuffer(wSession).remove(r); + } + } + catch (IOException e) { + e.printStackTrace(); + } + } + public List getFindResourceBeanFromBuffer(WrappedSession session, String stringFilter){ boolean passesFilter = false; ArrayList arrayList = new ArrayList<>(); diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MyUI.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MyUI.java index c2736ba8..92394dfe 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MyUI.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/webui/MyUI.java @@ -12,6 +12,7 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; +import cz.zcu.kiv.crce.crce_webui_v2.internal.Activator; import cz.zcu.kiv.crce.crce_webui_v2.outer.CentralMavenForm; import cz.zcu.kiv.crce.crce_webui_v2.outer.CheckMavenIndexForm; import cz.zcu.kiv.crce.crce_webui_v2.outer.DefinedMavenForm; @@ -19,10 +20,10 @@ import cz.zcu.kiv.crce.crce_webui_v2.outer.LocalMavenForm; import cz.zcu.kiv.crce.crce_webui_v2.repository.ArtefactDetailForm; import cz.zcu.kiv.crce.crce_webui_v2.repository.BufferForm; -import cz.zcu.kiv.crce.crce_webui_v2.repository.NewCapabilityForm; import cz.zcu.kiv.crce.crce_webui_v2.repository.PluginsForm; import cz.zcu.kiv.crce.crce_webui_v2.repository.StoreForm; import cz.zcu.kiv.crce.crce_webui_v2.repository.classes.ResourceBean; +import cz.zcu.kiv.crce.crce_webui_v2.repository.services.ResourceService; /** @@ -47,7 +48,6 @@ public class MyUI extends UI { private BufferForm bufferForm; private StoreForm storeForm; private ArtefactDetailForm artefactDetailForm; - private NewCapabilityForm newCapabilityForm; private PluginsForm pluginsForm; private SettingsForm settingsForm; private VerticalLayout content = new VerticalLayout(); @@ -101,6 +101,8 @@ public void logout() { } private void cleanupAfterLogout(){ + ResourceService resourceService = new ResourceService(Activator.instance().getMetadataService()); + resourceService.clearBuffer(getSession().getSession()); getSession().setAttribute("settingsUrl", null); getSession().getSession().invalidate(); Page.getCurrent().setLocation(VaadinServlet.getCurrent().getServletContext().getContextPath()); @@ -147,11 +149,6 @@ public void setContentArtefactDetailForm(ResourceBean resourceBean, boolean isFr body.setContent(artefactDetailForm); } - public void setContentNewCapabilityForm(ResourceBean resourceBean, boolean isFromStore){ - newCapabilityForm = new NewCapabilityForm(this, resourceBean, isFromStore); - body.setContent(newCapabilityForm); - } - public void setContentBodyPlugins(){ pluginsForm = new PluginsForm(this); body.setContent(pluginsForm); From 4598d88f1af5f1a8db9355b6327918cef2a5cae1 Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Wed, 24 Oct 2018 14:57:38 +0200 Subject: [PATCH 23/85] Added enterprise architect project. --- crce.eapx | Bin 0 -> 2478080 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 crce.eapx diff --git a/crce.eapx b/crce.eapx new file mode 100644 index 0000000000000000000000000000000000000000..17a804ff745b9496d13cc61ba1fae2cbe582c399 GIT binary patch literal 2478080 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 rjE;Vw?m)(#%G_e0Cd=wD>@{f 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%0D2uDZk)ya#Cr3KxTM@!b}8nZ>S8zF(5H1+(W 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 ?2W35)Nb|Ml29bM3sQ1q5<`UqC{ev5>663A-t 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

}xkyf>joy&0#)Ul2MSlR5y(@k~nIv>0=OB}bJ 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 literal 0 HcmV?d00001 From 5fe74018490c0894733ec987ad91cea1696dc175 Mon Sep 17 00:00:00 2001 From: rpesek Date: Thu, 25 Oct 2018 10:42:10 +0200 Subject: [PATCH 24/85] Added functionality - downloading artifacts from the Store --- .../filebased/internal/BufferImpl.java | 2 +- .../META-INF/MANIFEST.MF | 83 ++++++++++--------- .../crce_webui_v2/repository/StoreForm.java | 38 ++++++++- .../repository/services/ResourceService.java | 9 ++ 4 files changed, 87 insertions(+), 45 deletions(-) diff --git a/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/BufferImpl.java b/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/BufferImpl.java index 2de915ea..e7903997 100644 --- a/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/BufferImpl.java +++ b/core/crce-repository-impl/src/main/java/cz/zcu/kiv/crce/repository/filebased/internal/BufferImpl.java @@ -421,6 +421,6 @@ private boolean isInBuffer(Resource resource) { if (!"file".equals(uri.getScheme())) { return false; } - return true; //new File(uri).getPath().startsWith(baseDir.getAbsolutePath()); + return true; // rpesek edit: return new File(uri).getPath().startsWith(baseDir.getAbsolutePath()); } } diff --git a/modules/crce-external-repository/META-INF/MANIFEST.MF b/modules/crce-external-repository/META-INF/MANIFEST.MF index 73019f3c..d64f7035 100644 --- a/modules/crce-external-repository/META-INF/MANIFEST.MF +++ b/modules/crce-external-repository/META-INF/MANIFEST.MF @@ -1,5 +1,5 @@ Manifest-Version: 1.0 -Bnd-LastModified: 1540375086909 +Bnd-LastModified: 1540456417008 Build-Jdk: 1.8.0_191 Built-By: rpesek Bundle-Activator: cz.zcu.kiv.crce.crce_external_repository.internal.Acti @@ -76,44 +76,45 @@ Embedded-Artifacts: lib/aether-api-1.13.1.jar;g="org.sonatype.aether";a= memory";v="3.6.2",lib/lucene-highlighter-3.6.2.jar;g="org.apache.lucene ";a="lucene-highlighter";v="3.6.2",lib/javax.annotation-api-1.2.jar;g=" javax.annotation";a="javax.annotation-api";v="1.2" -Export-Package: org.apache.maven.index;uses:="org.apache.maven.index.art - ifact,org.apache.maven.index.context,org.apache.maven.index.expr";versi - on="1.0.0",org.apache.maven.index.archetype;uses:="org.apache.maven.ind - ex.context";version="1.0.0",org.apache.maven.index.artifact;version="1. - 0.0",org.apache.maven.index.context;uses:="org.apache.maven.index,org.a - pache.maven.index.artifact";version="1.0.0",org.apache.maven.index.crea - tor;uses:="org.apache.maven.index,org.apache.maven.index.context";versi - on="1.0.0",org.apache.maven.index.expr;uses:="org.apache.maven.index";v - ersion="1.0.0",org.apache.maven.index.fs;version="1.0.0",org.apache.mav - en.index.incremental;uses:="org.apache.maven.index.packer,org.apache.ma - ven.index.updater";version="1.0.0",org.apache.maven.index.locator;uses: - ="org.apache.maven.index.artifact";version="1.0.0",org.apache.maven.ind - ex.packer;uses:="org.apache.maven.index.context";version="1.0.0",org.ap - ache.maven.index.search.grouping;uses:="org.apache.maven.index";version - ="1.0.0",org.apache.maven.index.treeview;uses:="org.apache.maven.index, - org.apache.maven.index.context";version="1.0.0",org.apache.maven.index. - updater;uses:="org.apache.maven.index.context,org.apache.maven.index.fs - ,org.apache.maven.index.incremental,org.apache.maven.wagon,org.apache.m - aven.wagon.authentication,org.apache.maven.wagon.events,org.apache.mave - n.wagon.proxy";version="1.0.0",org.apache.maven.index.util;uses:="org.a - pache.maven.index.context";version="1.0.0",org.apache.maven.index.util. - zip;version="1.0.0",org.apache.maven.wagon;uses:="org.apache.maven.wago - n.authentication,org.apache.maven.wagon.authorization,org.apache.maven. - wagon.events,org.apache.maven.wagon.proxy,org.apache.maven.wagon.reposi - tory,org.apache.maven.wagon.resource";version="1.0.0",org.apache.maven. - wagon.authentication;uses:="org.apache.maven.wagon";version="1.0.0",org - .apache.maven.wagon.authorization;uses:="org.apache.maven.wagon";versio - n="1.0.0",org.apache.maven.wagon.events;uses:="org.apache.maven.wagon,o - rg.apache.maven.wagon.resource";version="1.0.0",org.apache.maven.wagon. - observers;uses:="org.apache.maven.wagon.events";version="1.0.0",org.apa - che.maven.wagon.providers.http;uses:="org.apache.maven.wagon,org.apache - .maven.wagon.authentication,org.apache.maven.wagon.authorization,org.ap - ache.maven.wagon.proxy,org.apache.maven.wagon.resource";version="1.0.0" - ,org.apache.maven.wagon.proxy;version="1.0.0",org.apache.maven.wagon.re - pository;version="1.0.0",org.apache.maven.wagon.resource;version="1.0.0 - ",org.apache.maven.wagon.shared.http4;uses:="org.apache.maven.wagon,org - .apache.maven.wagon.authorization,org.apache.maven.wagon.repository,org - .apache.maven.wagon.resource";version="1.0.0",javax.inject;version="1.0 - .0",cz.zcu.kiv.crce.crce_external_repository.api;version="1.0.0" -Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))" +Export-Package: cz.zcu.kiv.crce.crce_external_repository.api;uses:="org. + apache.maven.index";version="1.0.0",org.apache.maven.index;uses:="org.a + pache.maven.index.artifact,org.apache.maven.index.context,org.apache.ma + ven.index.expr";version="1.0.0",org.apache.maven.index.archetype;uses:= + "org.apache.maven.index.context";version="1.0.0",org.apache.maven.index + .artifact;version="1.0.0",org.apache.maven.index.context;uses:="org.apa + che.maven.index,org.apache.maven.index.artifact";version="1.0.0",org.ap + ache.maven.index.creator;uses:="org.apache.maven.index,org.apache.maven + .index.context";version="1.0.0",org.apache.maven.index.expr;uses:="org. + apache.maven.index";version="1.0.0",org.apache.maven.index.fs;version=" + 1.0.0",org.apache.maven.index.incremental;uses:="org.apache.maven.index + .packer,org.apache.maven.index.updater";version="1.0.0",org.apache.mave + n.index.locator;uses:="org.apache.maven.index.artifact";version="1.0.0" + ,org.apache.maven.index.packer;uses:="org.apache.maven.index.context";v + ersion="1.0.0",org.apache.maven.index.search.grouping;uses:="org.apache + .maven.index";version="1.0.0",org.apache.maven.index.treeview;uses:="or + g.apache.maven.index,org.apache.maven.index.context";version="1.0.0",or + g.apache.maven.index.updater;uses:="org.apache.maven.index.context,org. + apache.maven.index.fs,org.apache.maven.index.incremental,org.apache.mav + en.wagon,org.apache.maven.wagon.authentication,org.apache.maven.wagon.e + vents,org.apache.maven.wagon.proxy";version="1.0.0",org.apache.maven.in + dex.util;uses:="org.apache.maven.index.context";version="1.0.0",org.apa + che.maven.index.util.zip;version="1.0.0",org.apache.maven.wagon;uses:=" + org.apache.maven.wagon.authentication,org.apache.maven.wagon.authorizat + ion,org.apache.maven.wagon.events,org.apache.maven.wagon.proxy,org.apac + he.maven.wagon.repository,org.apache.maven.wagon.resource";version="1.0 + .0",org.apache.maven.wagon.authentication;uses:="org.apache.maven.wagon + ";version="1.0.0",org.apache.maven.wagon.authorization;uses:="org.apach + e.maven.wagon";version="1.0.0",org.apache.maven.wagon.events;uses:="org + .apache.maven.wagon,org.apache.maven.wagon.resource";version="1.0.0",or + g.apache.maven.wagon.observers;uses:="org.apache.maven.wagon.events";ve + rsion="1.0.0",org.apache.maven.wagon.providers.http;uses:="org.apache.m + aven.wagon,org.apache.maven.wagon.authentication,org.apache.maven.wagon + .authorization,org.apache.maven.wagon.proxy,org.apache.maven.wagon.reso + urce";version="1.0.0",org.apache.maven.wagon.proxy;version="1.0.0",org. + apache.maven.wagon.repository;version="1.0.0",org.apache.maven.wagon.re + source;version="1.0.0",org.apache.maven.wagon.shared.http4;uses:="org.a + pache.maven.wagon,org.apache.maven.wagon.authorization,org.apache.maven + .wagon.repository,org.apache.maven.wagon.resource";version="1.0.0",java + x.inject;version="1.0.0" +Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))" Tool: Bnd-3.3.0.201609221906 diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/StoreForm.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/StoreForm.java index 411b970b..3751ed94 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/StoreForm.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/StoreForm.java @@ -1,9 +1,17 @@ package cz.zcu.kiv.crce.crce_webui_v2.repository; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + import com.vaadin.data.util.BeanItemContainer; import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.server.FileDownloader; import com.vaadin.server.FontAwesome; import com.vaadin.server.Page; +import com.vaadin.server.StreamResource; +import com.vaadin.server.StreamResource.StreamSource; import com.vaadin.shared.Position; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.ui.Alignment; @@ -31,7 +39,7 @@ public class StoreForm extends FormLayout{ private TextField idText = new TextField(); private Grid gridStore = new Grid(); private PopupView popup; - private transient ResourceBean resourceBeanSelect; + private transient ResourceBean resourceBeanSelect = null; private ResourceService resourceService; public StoreForm(MyUI myUI){ @@ -45,6 +53,7 @@ public StoreForm(MyUI myUI){ buttonDetail.setWidth("100px"); Button buttonRemove = new Button("Remove"); buttonRemove.setWidth("100px"); + Button buttonDownload = new Button("Download"); buttonDetail.setStyleName(ValoTheme.BUTTON_PRIMARY); buttonDetail.setClickShortcut(KeyCode.ENTER); @@ -96,7 +105,7 @@ public StoreForm(MyUI myUI){ popup = new PopupView(null, panel); popup.setWidth("150px"); - buttonLayout.addComponents(buttonDetail, buttonRemove); + buttonLayout.addComponents(buttonDetail, buttonRemove, buttonDownload); buttonLayout.setSpacing(true); buttonLayout.setVisible(false); @@ -109,12 +118,17 @@ public StoreForm(MyUI myUI){ gridStore.addSelectionListener(e ->{ buttonLayout.setVisible(true); resourceBeanSelect = (ResourceBean)e.getSelected().iterator().next(); + File srcFile = new File(resourceService.getUri(resourceBeanSelect.getResource())); + StreamResource res = createFileResource(srcFile); + res.setFilename(resourceService.getFileName(resourceBeanSelect.getResource())); + FileDownloader fd = new FileDownloader(res); + fd.extend(buttonDownload); }); buttonDetail.addClickListener(e ->{ myUI.setContentArtefactDetailForm(resourceBeanSelect, true); }); - + buttonRemove.addClickListener(e ->{ popup.setPopupVisible(true); yesRemoveButton.addClickListener(ev -> { @@ -135,4 +149,22 @@ public StoreForm(MyUI myUI){ addComponent(content); } + + @SuppressWarnings("serial") + private StreamResource createFileResource(File file) { + StreamResource sr = new StreamResource(new StreamSource() { + @Override + public InputStream getStream() { + try { + return new FileInputStream(file); + } + catch (IOException e) { + e.printStackTrace(); + } + return null; + } + }, null); + sr.setCacheTime(0); + return sr; + } } diff --git a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/services/ResourceService.java b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/services/ResourceService.java index 7b0bddf2..d0272026 100644 --- a/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/services/ResourceService.java +++ b/modules/crce-webui-v2/src/main/java/cz/zcu/kiv/crce/crce_webui_v2/repository/services/ResourceService.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.io.Serializable; +import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -67,6 +68,14 @@ public long getSize() { return metadataService.getSize(resource); } + public URI getUri(Resource resource) { + return metadataService.getUri(resource); + } + + public String getFileName(Resource resource) { + return metadataService.getFileName(resource); + } + public List getAllResourceBeanFromBuffer(WrappedSession session){ List resources = new ArrayList(); for(Resource resource : Activator.instance().getBuffer(session).getResources()){ From f5a4595763d109c726cd720aa0e79e4eb748667d Mon Sep 17 00:00:00 2001 From: Radek Vais Date: Sat, 3 Nov 2018 18:26:46 +0100 Subject: [PATCH 25/85] DaoMongoDb - read connection string from environment settings --- .../crce/metadata/dao/mongodb/DbContext.java | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/DbContext.java b/core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/DbContext.java index c2599b61..a0752f50 100644 --- a/core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/DbContext.java +++ b/core/crce-metadata-dao-mongodb/src/main/java/cz/zcu/kiv/crce/metadata/dao/mongodb/DbContext.java @@ -1,8 +1,9 @@ package cz.zcu.kiv.crce.metadata.dao.mongodb; -import java.net.UnknownHostException; - import com.mongodb.MongoClient; +import com.mongodb.MongoClientURI; + +import java.net.UnknownHostException; /** * Context class responsible for connection management to MongoDB. @@ -20,17 +21,37 @@ public class DbContext { */ public static final String DEFAULT_DB_NAME = "crce"; + /** + * Default connection string for mongo database. + */ + private static final String DEFAULT_CONNECTION = "mongodb://localhost:27017"; + + /** + * Name of environment variable to store connection string. + */ + private static final String ENV_CONNECTION = "mongo_connection"; + + /** + * Field for cache client instance + */ private static MongoClient client; /** * Singleton instance of Mongo connection driver. Client holds its own connection pool and therefore - * should be used as singleton within the application - */ + * should be used as singleton within the application. + * Method try to read environment property which contains connection string {@link DbContext#ENV_CONNECTION} + * for database. + * @see MongoClientURI + * */ public static MongoClient getConnection() throws UnknownHostException { if (client == null) { - client = new MongoClient("localhost", 27017); + String connectionString = DEFAULT_CONNECTION; + if(System.getenv().containsKey(ENV_CONNECTION)) { + connectionString = System.getenv().get(ENV_CONNECTION); + } + MongoClientURI connectionParams = new MongoClientURI(connectionString); + client = new MongoClient(connectionParams); } - return client; } From 756d1d561328e259d3734155b1b0557bd7dc344c Mon Sep 17 00:00:00 2001 From: "U-WINKIV\\valesz" Date: Tue, 6 Nov 2018 13:21:23 +0100 Subject: [PATCH 26/85] Added script for listing artifact and their parents --- crce-artifact-finder-script.py | 45 ++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100755 crce-artifact-finder-script.py diff --git a/crce-artifact-finder-script.py b/crce-artifact-finder-script.py new file mode 100755 index 00000000..ea415776 --- /dev/null +++ b/crce-artifact-finder-script.py @@ -0,0 +1,45 @@ +# This script will walk directory tree of crce project and +# prints artifact ids of all poms it will find in following format: +# filepath: parentArtifactId -> currentArtifactId for artifacts with parent +# filepath: currentArtifactId for artifacts without parent +# Implemented method is compatible with Python 2.2 - 3.4 + +import fnmatch +import os +import xml.etree.ElementTree as ET + +# format for printing artifacts with parent +# filepath: parentArtifactId -> currentArtifactId +artifactWithParentFormat = '%s: %s -> %s' + +# format for printing artifacts without parent +# filepath: currentArtifactId +artifactFormat = '%s: %s' + +# base path to crce +pathToCrce = 'c:\\users\\valesz\\documents\\crce' + +# pom namespace +pomNs = '{http://maven.apache.org/POM/4.0.0}' + +# this array will contain only folders where the pom is stored +# e.g. c:\tmp instead of c:\tmp\pom.xml +matches = [] +for root, dirnames, filenames in os.walk(pathToCrce): + for filename in fnmatch.filter(filenames, '*pom.xml'): + matches.append(root) + +# parse poms and print results +for pathToPom in matches: + tree = ET.parse(pathToPom+'//pom.xml') + root = tree.getroot() + aIdElem = root.find(pomNs+'artifactId') + currentArtifactId = aIdElem.text + + # check if the current pom has parent defined + parentElem = root.find(pomNs+'parent') + if parentElem is None: + print artifactFormat % (pathToPom, currentArtifactId) + else: + parentAId = parentElem.find(pomNs+'artifactId').text + print artifactWithParentFormat % (pathToPom, parentAId, currentArtifactId) \ No newline at end of file From ef7cf3bd81c415a9b144c9782c00e065734c3e8c Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Tue, 6 Nov 2018 13:42:06 +0100 Subject: [PATCH 27/85] Outupt of crce-artifact-finder-script.py added --- artifact-list.txt | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100755 artifact-list.txt diff --git a/artifact-list.txt b/artifact-list.txt new file mode 100755 index 00000000..fa1c63a6 --- /dev/null +++ b/artifact-list.txt @@ -0,0 +1,49 @@ +c:\users\valesz\documents\crce: crce-reactor +c:\users\valesz\documents\crce\build: crce-parent -> shared-build-settings +c:\users\valesz\documents\crce\build\compiled: shared-build-settings -> compiled-bundle-settings +c:\users\valesz\documents\crce\build\wrappers: shared-build-settings -> wrapper-bundle-settings +c:\users\valesz\documents\crce\core: crce-core-reactor +c:\users\valesz\documents\crce\core\crce-core: crce-parent -> crce-core +c:\users\valesz\documents\crce\core\crce-metadata-api: compiled-bundle-settings -> crce-metadata-api +c:\users\valesz\documents\crce\core\crce-metadata-dao-api: compiled-bundle-settings -> crce-metadata-dao-api +c:\users\valesz\documents\crce\core\crce-metadata-dao-impl: compiled-bundle-settings -> crce-metadata-dao-impl +c:\users\valesz\documents\crce\core\crce-metadata-dao-mongodb: compiled-bundle-settings -> crce-metadata-dao-mongodb +c:\users\valesz\documents\crce\core\crce-metadata-impl: compiled-bundle-settings -> crce-metadata-impl +c:\users\valesz\documents\crce\core\crce-metadata-indexer-api: compiled-bundle-settings -> crce-metadata-indexer-api +c:\users\valesz\documents\crce\core\crce-metadata-indexer-impl: compiled-bundle-settings -> crce-metadata-indexer-impl +c:\users\valesz\documents\crce\core\crce-metadata-json-api: compiled-bundle-settings -> crce-metadata-json-api +c:\users\valesz\documents\crce\core\crce-metadata-json-impl: compiled-bundle-settings -> crce-metadata-json-impl +c:\users\valesz\documents\crce\core\crce-metadata-service-api: compiled-bundle-settings -> crce-metadata-service-api +c:\users\valesz\documents\crce\core\crce-metadata-service-impl: compiled-bundle-settings -> crce-metadata-service-impl +c:\users\valesz\documents\crce\core\crce-plugin-api: compiled-bundle-settings -> crce-plugin-api +c:\users\valesz\documents\crce\core\crce-repository-api: compiled-bundle-settings -> crce-repository-api +c:\users\valesz\documents\crce\core\crce-repository-impl: compiled-bundle-settings -> crce-repository-impl +c:\users\valesz\documents\crce\core\crce-resolver-api: compiled-bundle-settings -> crce-resolver-api +c:\users\valesz\documents\crce\core\crce-resolver-impl: compiled-bundle-settings -> crce-resolver-impl +c:\users\valesz\documents\crce\modules: crce-modules-parent -> crce-modules-reactor +c:\users\valesz\documents\crce\modules\crce-compatibility-api: crce-modules-parent -> crce-compatibility-api +c:\users\valesz\documents\crce\modules\crce-compatibility-dao-api: crce-modules-parent -> crce-compatibility-dao-api +c:\users\valesz\documents\crce\modules\crce-compatibility-dao-mongodb: crce-modules-parent -> crce-compatibility-dao-mongodb +c:\users\valesz\documents\crce\modules\crce-concurrency: crce-modules-parent -> crce-concurrency +c:\users\valesz\documents\crce\modules\crce-handler-metrics: crce-modules-parent -> crce-handler-metrics +c:\users\valesz\documents\crce\modules\crce-integration-tests: crce-modules-parent -> crce-integration-tests +c:\users\valesz\documents\crce\modules\crce-metadata-osgi-bundle: crce-modules-parent -> crce-metadata-osgi-bundle +c:\users\valesz\documents\crce\modules\crce-optimizer-functions: crce-modules-parent -> crce-optimizer-functions +c:\users\valesz\documents\crce\modules\crce-repository-maven-impl: crce-modules-parent -> crce-repository-maven-impl +c:\users\valesz\documents\crce\modules\crce-rest: crce-modules-parent -> crce-rest +c:\users\valesz\documents\crce\modules\crce-rest-v2: crce-modules-parent -> crce-rest-v2 +c:\users\valesz\documents\crce\modules\crce-restimpl-indexer: crce-modules-parent -> crce-restimpl-indexer +c:\users\valesz\documents\crce\modules\crce-target: crce-modules-parent -> crce-target +c:\users\valesz\documents\crce\modules\crce-vo: crce-modules-parent -> crce-vo +c:\users\valesz\documents\crce\modules\crce-webservices-indexer: crce-modules-parent -> crce-webservices-indexer +c:\users\valesz\documents\crce\modules\crce-webui: crce-modules-parent -> crce-webui +c:\users\valesz\documents\crce\modules\pom: compiled-bundle-settings -> crce-modules-parent +c:\users\valesz\documents\crce\modules\provision: crce-modules-parent -> provision +c:\users\valesz\documents\crce\pom: crce-parent +c:\users\valesz\documents\crce\third-party\httpclient: wrapper-bundle-settings -> org.apache.httpcomponents.httpclient +c:\users\valesz\documents\crce\third-party\httpcore: wrapper-bundle-settings -> org.apache.httpcomponents.httpcore +c:\users\valesz\documents\crce\third-party\jna-platform: wrapper-bundle-settings -> net.java.dev.jna.jna-platform +c:\users\valesz\documents\crce\third-party\lpsolve: compiled-bundle-settings -> com.datumbox.lpsolve +c:\users\valesz\documents\crce\third-party\plexus-component-annotations: wrapper-bundle-settings -> org.codehaus.plexus.plexus-component-annotations +c:\users\valesz\documents\crce\third-party\plexus-interpolation: wrapper-bundle-settings -> org.codehaus.plexus.plexus-interpolation +c:\users\valesz\documents\crce\third-party\plexus-utils: wrapper-bundle-settings -> org.codehaus.plexus.plexus-utils From 1ebb66fccb6e3ce8704369154926228a1a9147bd Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Tue, 6 Nov 2018 13:52:04 +0100 Subject: [PATCH 28/85] Added temporal EA project with analysis of artifact structure in crce --- crce-tmp.EAP | Bin 0 -> 1738752 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 crce-tmp.EAP diff --git a/crce-tmp.EAP b/crce-tmp.EAP new file mode 100755 index 0000000000000000000000000000000000000000..53f563e3de9b1dcb67a1beb641afea2a2ea92933 GIT binary patch literal 1738752 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

+da?^ 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:mQOI2OfO2pl}HQPx7q=pj2 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 Date: Tue, 6 Nov 2018 22:32:24 +0100 Subject: [PATCH 29/85] Cleanup. Added detailed diagram of modules structure. --- crce-tmp.EAP => crce.eap | Bin 1738752 -> 1777664 bytes crce.eapx | Bin 2478080 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) rename crce-tmp.EAP => crce.eap (90%) mode change 100755 => 100644 delete mode 100644 crce.eapx diff --git a/crce-tmp.EAP b/crce.eap old mode 100755 new mode 100644 similarity index 90% rename from crce-tmp.EAP rename to crce.eap index 53f563e3de9b1dcb67a1beb641afea2a2ea92933..1beed7b3d2c789549602c43445e7e14ac4855b9a GIT binary patch delta 66851 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 S_h@!tCWG<&a#WWKs{aR%ts2(= delta 41477 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 diff --git a/crce.eapx b/crce.eapx deleted file mode 100644 index 17a804ff745b9496d13cc61ba1fae2cbe582c399..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2478080 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 rjE;Vw?m)(#%G_e0Cd=wD>@{f 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%0D2uDZk)ya#Cr3KxTM@!b}8nZ>S8zF(5H1+(W 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 ?2W35)Nb|Ml29bM3sQ1q5<`UqC{ev5>663A-t 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

}xkyf>joy&0#)Ul2MSlR5y(@k~nIv>0=OB}bJ zQ1+oP0~cYj`BbljajUq>F6MUTnfW{@Mp)}&D2Z6*RE!)Uen;mXw5y#L3-g#dd zH0t#rd?|?Bprai$F64@3>(V6{m)?0yryGnr*KWM4nCqOF#%Q%tOSR%Xb}F>>Qo+LS zWr|vXY^+qRsQZ!BWy$9?jqX69{bh$>*(__DySUbRt~a*t7M)36iz6$~M{h;Izgko=M`VX62$dG0!O)h)hEmp^2P}E zo~3u1qeBCiZsZ(XhebY}eLP}pFm83Wtke~dY$NZSvaF4A)9kKe`~R?UqB+?(iv4!| zqY=;uXaqC@Wh0;`m$jT+7Me_YC!7T*muWOG-$66^)5BohJx#{?rK)_$~u1Qf|`vBRa4`tq^|mr^_!z5 zo8mdUm+BI>3qs(;X5zh-6^vRAS@k4SYJpP7$*pF4fOW|A3Z)`9Lu9}TQY)p9lpD+r zCDrJd_D5FW3K2Avs*U_2^elD5vn=pRx&QAqW!?YR&{*pIe;+LM{=X04yufq+-&0nS za#05-)$|?(Sf~1#d#|54PO33;T&!{f#e4kBaZ-($<6;%&{@BkPC)JoaE>>agkNnJW zQjMA8Vio58(9awv)tEUhR$=Z*KXaT^W9GP6g}LALGsj6aW{!(hn0uq2IZmoEb6l*# z+;91r_q3 z!rc9S<~XUw%yF>_bHje-IH{)0ndY#4|6kasZ+uz(aeezAc7XIxbrGo5ws+9Bus@W+ z@<#4tc$CALAVnNGZ5@i`v2{&$m*u&vSF+(~P+cEsmpv#@4k?EBf~nQ^Y^=5dC}>TfS{6#HWU?i2M^!4iO)ny% z*l^KNLcNGzqMD}`#+{q3Eb_I|&ed*&b4?2ejXrMe>@`d&WV}*Hyj<5{sX?X2>^L!G zuX|OIfC-@nsCN6bWmwmmIMwl%aqX} z%HW_n@^%-x#v*07!5R)S8?WG8*42qk^~lb9F8e1z*A$QnaFG$7zfu>d$EamQEGvcV z{ZQY1FsUHzb-c8*&mgk*D~){+!;L&rzhwon(ikfH`|Ci3OBStDM5}zqJLX+&5LrX=I#5@Vks?vv4 zM+;UVv@jvHR)SYSF=b+!`|b6A#Heq5Nz=d8zgX`8K*ID-#R$-}a^5`u=Ju<%OfPMM zSZG4%oiql=#Va&*bOk^>4BbQnuM@cIH;Va61`S85d6Pd_+wx<1fnj3=B4-*>v(r^8 z6hSDZTmf@;k*RIqe5o)|=PH;#tCT2RyC*&09A#VtI=3&hF!@MIV;CkHsCGzoT?F4C0PQ z^=*QI8xS;z{Gy=ZQ7h;2g z{z%h&|BSP(t%?d$7A2#@@O+u~1OiV+)(ORUDHNleV7KE8E#P8NC6b?d9#nj9Kd@lF z)wFPSd!kJrgl7RseuFqzFwGw}IR5{yZh23%9x3?@;J7!TkbvbgFK?@oy_ieExg+)nCx(U@4-;s-vgm{j6Fp4hz=pVdt> zHBJLb zs*5}lcp3(`IDJMv=Dz2zX!X1!0l03j~8?0u~w?}b-* ztiS@1-y~M1H{+1JkjWq0>~XMO5~Lt|y_N0J1~POG?$K@*J6NLL&iZ&kU>~&Q5Lms+ z_GsOk4>E%EvQ6x4KFAEE?ZTSo>rH3<|AqRl@Y`r)(?91D0;C)N0SpzMp1G%7=g(BE zpspK1HTeXXVrI}hNxitMJLph?bQVpSOj~(TCtj)b?B$qwQBU(7bTN6ij*#T_&=ojz zm43t+xVQOS9x(=5pPqxmm%LDEMZ;HBcg&qJb5ZnRIaeGKCTg?j$1={YcUBwN?7XF| z`Vo{iq)~T#9R{)0)|TZRviO&~#h0_oEr#7kE5#STl^nDN9bJ`un4_-Z=)i?bkQk$ndE!B(0&v!bJK&k=%15MdU?*}be=7pT!gx?fApLQw89Fy**?!-}~ z2Sb;)D6rD2UMaJply>}HrwCb)2vmySaZ#FdqUZo-v^|lAsoMfRspf-~mLpwG#DQ0#7zLSw}hNZnRa^g(Ps4eH=@J1Sp(Qf5bhRSCl4*IU}r zF4ED9r$m|3sHxCK-D;Jq3NCG}(0YaRzEj?3gT}5Bn?-H*VNjpKzmmK?N~CX^A2z_E z_}Oo~y6t4!MBDdb{}TIHY#_Efc5Cb}TAyrvuHye$Y@M%vBF62Qgf1<$8A@y29<~XUw%yF>_b63L!g(5vF$Z=AQnd4#==GOX|_q3!d%4994FP7IWAUV?w43?dwMG;)tEUhR$=ZZ ze&#r-#>{cC3UmMEXO5F<%p4c1F!%rYnd77yGsnd$%zfL>94FP7IWAUV?puE5IH|_W zaj^<>|I5!DC)JoaE>>ag>we}qsm9E4u?llv@iWIsHD->BRhavdpE*vdF>_q3!rVXl znd77yGsnd$%>A98IZmoEb6l*#+~4|{>agLw@Essm9E4 zu?lk>%3fLEa8gZ~GtDgqpa0hzM_Yd!%{Kl=Q*|WhKwv(K8J-p+!f>fZ6hWj{c_c8+*Vys@>WpVwI-9;& z|8)4RIBn8D8i8{I0n(z+f|WBK?^4IrA=tb03gKNkfnG>jh$4KFeQ6Gq1~5MF!&o(p zo=T>NWTlihE<^NB3cN;^OPnhQV>|bEvh;Cg%f+s^Efj(1GC@u12pYD=p)DxN9sRIp zsu>Dlm=;k&!WgD^(-;=AhEYQrT3sBl+zC)jG>d_Wh2K2bz((6^u?h&hl(}OH8WS4~h~u;r9k0Ic5d8Woz(Fp5}MrcoST2LDU+X59%4U@Br}J@-Jtt zU)QK~uLeFew|US2j@lBAD}bP=RyuyB?Plq zCuU?mDOIi7S!fL%hvaY}C2!TcCuZbx$v4G#$-h(~k17i}U3S}EHNWpc2d5>KjG@iY z6kD4F&Q#R{2AZ2zfuys@Sv}b+G>lfy?=eWS-94)mIS*cxR9jbgdz4r|sNxxZ`Kj`F2%Ys2A6dQ=enn)*!2l2MG># zhLIo3jz655AV={sf7Y7~#!F3#zmXqHrV~^1iHszfTRFj-apv+$++snr<`NUriK*1e ziJX%;HsDy}|8MV0;2gQiJ4-X;Is3qX4aPAR24C1UuKQ4{71g1#EK8%&R1YynLe$;r z8Q~tOtya%?Y&RH#gF`S7a}%zRK$2YoAq)Hn<_MQJrl-fwu`w(d$il`zNPzGQfyGSk z|EohSX{2uTFrG1S)z?xzRloP@)&G0%)jPi9&o=)U^JL=1Et``xV`eVIHquqhIn1A6 zrG=ikdT4I8a;Q=}Rd!s3ov=S;9`^G3W$}AYtj;7h{ckTXpP|j8bCpwIDsuQ4vkS5p z|AtV}t8Fj#H`wrdSfR#oGAIAJY_DVt=-cv`*-F5a+)Q!dP|> zj&yJiL;^@s2FLB*H|@N5M?Cl$q{dnY9ck~I!7`k8JT8(3MS7x~UUt=vl#@0K2_>l{ z@`aR>Oy?4AA)U-6w47#Z#a!yD;TVqFuiARY?PK^{kIxIY-hoBA9p%;1;k9G za!MhaOen>CsbnVXw3#Z}{gcL0#bQEJ%zPr5Ev8a-BAZX-a++zEk_qIc^uO!UGg3vj zRCG0`l+$u4EuG7zOIk9Q&uMO{lyF_M?_H0blPVPx>0Hju7L&zPGUw)trG(?SN-|qW zW^K37H|g?4DL0Wy70pC4UCgHncFxHab52$%rJQ^=mr5o2C%rJ`rt`^s%1tG5N~)Bl zvKG>|R?3-0$0?PPeUly^N-H_Ll+KqlGohsl*;F>|7V^oo=Gr-1adNr-NuQifX|9uY zTqgluBoaz4n=66QsZuHDYAAf)q|47pr=22rkWQJ!LaJCwXGf+Vo@s;icZlkm6X0om!6VF*&Nh3EtfB* zN(nQYv4;3q{*S zYfI>dfTEbCzDbvc(ay64EmtVy6(r50LMKzEt)P>@^OsU<-1S^j zOO^6y*dAZ=xneezu#>1C8k%0#P4rK?G-4)Ef5At^$>;Hvbh3E`^{|xEP~fD}zre@N zL)W61g`83{b6P5;rShd>-p!%s(DF8#@)`*5FiZIy;uO;+Zk=_|aPq)B>6FrL7NyYo z!^D_w0-dLmD!GMZ3N<)aEEP*hR4y%_chOb#Pda34nrmiDilU_O!0AL@NhFKKtf`sB zqLM7-`zAd;jM|&E5v7!NOjN`|&Mp@6rDWE1as^GX`&a+vr`svFlm?#QOFosffo)Df zr)b+*(@ol`{&o0R%yvt8P0`%6nYPhO;D_mG>3q>t^62UkYqXq;&rVVY)d+OLIO<42lUS*MD}pbbi5c?37us(@Bi@ zvWcYQsxjB)ZBO9#g{74rEk zW@af@F=>jK%O)|!b4@dsPPjQm>pzTJ+FmGN;$XY!f~H}80@KpGQ^=LD&f&Nz{OUhE zUw(1{iv#BvKJHT~B*mbVm5*TEg!l%f<;xnu$J z7)%hbWRlb{Bh&gXSS;-*Vs2SX6>?cDjij<}+DT|>6OVv#e!fsxW7@U6y_ip@Q>8+( zltzKU5C;=nFe;Tm88Bg8V})f$NhziQ5@uakDoJ7XUBKdy;(}#G8lsyx=&QpH?8ujG=Ll`2`RN4dzSZ-I|*ag{^~%@ogwWtntN19O~G0!s;K z1o?v5zrai9Vz!;bT2~g0EsdoMmoQ3W^}t1i$fuM2E8@~7H>GJ>AzjGf4{R(rS}}=s z<6y-k?IhP&VOiSjV$CZ}%Ro8Ii4$5Oo69MRrWA2=)I)oX+38LfEyi`Q{)5(&%BD=L zlhAD1Os4Z@B5STuC7$Nmly_DsVj(Gog)qk~VU}BTO)NXoqGf-CpN=IJ6AKiYQ_R~~ zI!I-UW*&=$SORcR4ed1+EOxj~$;sPUw_qnqSTHH%5>7gc$++n%SOP5ePkKD&Vm(H| ziXc`Haw!w5s#?jk(^%TH(E(t&rf-3l&%k}#I<8Z(b6)8d>LLfpQLf{F3KrD8Q`EKx}Bg~IRzB0Tt^s!y<-udbsw{4%> zR^Ix&bJQ*I&F60V$$u#{bSM-1hp%t#he=9?LUay~<Yd#GO~2`)_wS~&AG0OW z0JGOt{m@*!2KgC3Se>m*$0rwR)3cTMe5Ki})(*_CoVaDWQkyQXoZxqJJksoK)aUB+ zm1z#)T=}s74_scDoUKl+oVe9+GMeD<8P?7?Dl6#~oi){r%8I%n%Df{vrmQZ0k?E#) zGDL4;ULVk_nUm=*=B1$9JURjez&f*^$uXBQ^@mrONuZ)L!@)DI2Ti>?^7VHBl8?OQ z!LR>$8#I*MfS^|gG<#<&H!sY`7n;@CQ-DKvL`&pFmQy&Jl{7(RbxqV+S+*ouFm;{N z_{G0sy6N{BqTgj+84x{qH{Ax+$_6wyiEf0(|I|rvgbFe1!Ex_>w>{hs4z~{+)mpRC zn5)m0o7H-4!?i@pIK0TK4yzfq#7dkz!)lzOv1Ud#WP#&Nlam)e%XHJ*7^2^2UK7yo zK>V$nUdh}7y4j<70CVF>u)rXqcdQ4?LvQ`iS2qgFRM@2Aw=*hi}y3#^oI=5+n6^7^jhX*dJS_2=ys28^{jn$HzH{7 z4+PJVJG8G149|6Y28MT&fr0B_v!@Ii*~vhW)Esm-6lE!rTrJ5R8yd`HxLv*f7@%nJTMfwS~)(4b~96N z9NI7(j-X~7!{k^&uuwC2Sz>h?HA50O-BdK$)^zDH>rVpNxWLkf4-LI-C=|YR=zQ&e zKKjtWaAcd!x%gDQvGJ-QOM->IRADt$)L3b1MnEgkHI}#3jIF7PuG;eA$Cz&N+r;lM zFAwNe=43kRyS;?_ypN&?0j(-3l4wn>Jb)ylYu)6o+ z*9iLEUNf@)bjv?b&3Nx$e%?C=AbKbNO=H$E04X<)uAG=SSZz$l=gN&He)I){hust! zizI6p$)vntO5128!;7{hqPduyC8Loj9INS$$!2tc7cEETWX@Uq4AV_-VTfMW8iP=m zxk|TtqmWy?7ccc7WW%itng~ZD+x*c841{<`2oC)qFv4>P%xk};9Ur*4SdFPl{7`** zVYV_KZ&b=t&3a=Ec=`;|4B5z_zhG@y!0WdnajYTB7_&*1DvP$n8b7nTP*=hsTl@JAZ!~h4 zA-V~*rFv2W3LDOPpzL1$?9#?SK?6FK?nIYWSu#bDwPXSB-RZK9o`f@510z;68&lvj zna8X<38b#qebK!9`Cq%g9~w6^Zs$1OJqRRdf>WKHKK1#Hq~rZ7sAw>}ftLF zzWsTlaD+gFK!iYqK!iYqK!iYqK!iYq!0AEYB2U;hoX}IAW0=VPJ}yiLH+TF39JFRr_XVosH3D|@d)Xz$(w^Sh^R9v6bpQAFG8R&S|{>t6Kh zrYILAU6`A*C@I~U_PQu*FYHaD>DT`GiZNR)hyO5|%`jMO#dfhdQmF??Gp%3r5c?`q zK@s;=C?Q?L)O4Z$U%@7U8P%YMRFrktrXEfGuoD9~k6n|>PVJB_n z#B6=)#>({gOnG*`GFETU+M&1WfUJ*Hr<(_HuGS{YjUYx1+0O^zsrqcaG0yU1ll9p! zhZ$T%k|v$-pZbjD2NuG>!C4e^VTSTONMBR4^c0gv==W?D-=mwDw6({d!ar-%d7JKt zy&y)5>%ZyIe%QiIF#^oHtvve3GcNL`vf<)KuL^WKD$b7={^;kc6{v03vUBnp)ty$| zu{l#xMU`g_?8mZ_Bu!#}O}1DuV@cSMlx&%o&Q9Io)~!2sPZ ze-0w`5#;83w+my2*U483ITmXMIneGi?KhBXCGvsiz@onuRm~`@Ukx zqlaHc@=#Xy_EN|53V%5C#!n@8^?B20e)uU7-8-9Fq~kBH=(zeDq@p8_QNRQ z0h}jsCSOtHhRVN-f%_fyo^c8|Oe1x>f04Z?YaO`}CkT`7*bV~`kj%|fvkRE>O*oiI z*!3x6mS!U~0V^$FhJ!HXTYGOj5KN&aD)Zj#izZP8>|-?%fu?Yc%KW@jv=FOMZZ@hn z8&l2d;R^lpNcGTcxmKAEuJB{mmoYo4wIcZO^VM4AH@w+Xm;+t0W*f*Nh~ZDWxUmV$ zKWi`vS8wbI?k+B`~+FnzdOo2pD_eCuWY zG?Q;#b}HrOLL-=cu3m24CyamS#gjn})@*rxzB*H_Gzgcy6ZG8nwf2ES<74iGnfC*L z2qpC9oX@MyS0`sHfU;4YTxeG8O0!%IXW7NMeU;_}jF(Yf0hVS1`-K%BYMLR3kDM=0 zRy?lkZ2@I-n_royHTrIzZZjSJaF$7K=xavz zjXr(!>mz?W@{$p5~-$H&K`#lzO0LuGA1yWVC!oo_RFTc1bM#$_xvR8c@X!ULztvP zpV@X#S+FGNpmp7oN_81ZNIP(^!RLFwSXrS>yNgy+^0E%2GLGWSziEdQbJy{Xg41oj zj$1wl=VSQXgD~ypkrVphku$2IX|iaH&D1eHx5~5C$wt-tF@MWAFJSACHXm`C#S|0g zY7OC>craN=cqjr*Y3PUuEl49K3mhx_dsY;Rw@8F(LLlt?hqeW0kit&BKCXBb^X5$D`9U8?aNGS=l^=_z- zU1g?%&<&>n@-PZeaVo=K0A)8;|Ln*0Bl45N52&M>i zDO2l8Nip7zEAxu@0bV!4grofqIMi9DEQj8zArThrOR3&L6G)T#tP{h%- z?utb*9F#D;=YJq2RY~eJ!<34yYmRDn-IHS2ZTH-cFkPe6K}yx;1X~l;u9Otx9c}mg zZG@>DRN^3|VsVzq%iR@=V*Gns%8wyT&rT=>DNT;Ub4uOVQj9DrQ}~=i2ov7KnII)Z z=s6WlzN@qpqk-7pM=kgTxbmY%S5~NLP;CfOLXB2ZxsEP|>JY_vIZ)YzA9MI*5T@Ee z6*?@frAZl6=zdO$L3N1yU3?24szX#Gar;(EDCwHOsH?OT<1&;syyy3jk{T5XAEtB+ zOBMNy-j$MKycw}?LrLF+A5TJ<8ZtdeP+BN@W<=RoO&NNz)W{#q;@{IB1s=+(3C|57a?oCZ1QdFj9-drDni_(XL+UXD*4BrTKr%*qM3 zzCbElY$|SJvAS9d6s95i1iku7Z3@b5q4Ioq-d~%at4z^)?)1uujvwv~coVwM$5)0z z845vE$l`QMhAIZ+JD?gXDNvHtNGZeC6vtL{%j6Uj;vS?T7k*c3^G#ZWUO5ql9C$r= zT8TKpFeZif`Qa;KSHylT_M{Hl8he!a3G+jb{)YL>HR*j!NN;6A3bhXJV(#+P`77|| zD>83+<>!YV{q=9&wT&-&E!itd+ZVN6s)>Ufj~m`VZ(BBaXt^tv!9fL4nqhSZTHU+| z#VSE_GzWT_Ay<43g&gVR&3SFSIq$6UhI+#8gRcF`@kZhV!xnj)bp+UCkS2MBH8=+v z#G+}~rlG2KMi_`UPif=LQ_d=H=v~u&P>)W18ug~sE<^+#LJxZv&iS^!3;*)|Pv_1) zZGK^r^_5QJk7f7ffaNcXpep`V_%!Wx;VN&8zWEA$Ve=2i;#AkR4S}N z>hTsdd?nFwpesLE6Faw!jpqhzbYpJp+SphJ@v+Ne&x&2>(T|yb>_eYoi2kBQf5e3J z2Mp00JR(iNxv=|V!|sn>{M`q!G3?g5|JVIHjCWSp*o#|WQ$~>`#gqk@h9PBa4k1I* zV9LSZxeU*%8GH@Y+J@WMG#s!=jEP{1&yw)_+}Jj_hxs`}^!FY!e3tb3-VmEwZz&pO zbsy9MsV5|M(HryxzNWwjDrj|}*7jI7v0l9KT9QO9NzItLVrUMl%hZy}U=h^B6_z() zSprj1%w?55 z8bJF`{;iIbxHS*i+zcecG>0pr8jMr=Ndh=kV z(TX_Js2_?q4}#ULBxhi(=voEpGhJ(9pWk(whGN5xhQV^SW`W_{B-*4Y!4Qwg!+Hd7 za?)U3=Z-dp?+6&a7+Z|p6svU53uC3&^|6dc7sY-CUuXU4`%FmRU_yF`A$q{0&oiHA zJ`i@Dtu`4lteu&}>|Pb2Jx&-7(}!JW{GOdxpH|k8xr$!RklG*2Qee?XWOb1TJ2(|@ zGR>4(M~BM2rrKl*XQ1}CwT&HH19niiIEwbxPCsLQ03&MO^61{S7WTf@yDEHV{Sou# z7X2*1|%QF`A(d1 zsdaR-V>bk|PHul>KxVZi#i6XRZsYT9&Ya%q8TASnD}}uQItH&`eTuVt_wL>`p|hEK z-LvR5+THn#Gchh|s{d=ExOW`WJ{c-iP7e0^MT!?yB{F> z&d7I;f9LpnM_x4YqT}a}oPYem;RlyrJ^bord)Qt+F?8bC$A>>~_VlR-a zeAyRJFCM9R{|N-=XDj1->NU3Y3**@+7bp}&xJ30OYDZDefIjqz*JH+FGkxa&pB}w! z^tJ~QqlpKIeme5g<3BzAv61FT^SCe~9RK0)50^hU{K4hf;o0Tq4nKGKJ44?&_Wq&w zADbSUK6c5_CC9$G>zhjcqe2!yYAU}>ke)ECB4L8&%_HXx<`aSgg}Hqgg}JASw}!;o*k5-UG|ma zT1lvq&f#(S8z%mREG&QgnRj~Uj-t;qFJ3vZ>X!|sw->4nSnY!SuFzI@5BIQZJ7(h) z(Xe&+MU_<>#;sLVf;6I~z%Q!mh>`}?P52G^Yo?og{jt|GzZX#Gwa!1koOv0%*PZOG zuG=x&C4Eq#%ON6k{^94o_XweK>&5l&(m6=xoqTU~ZCH@c*xF3>z(Rw@d2!o>=%;5G z4!hlPcv!ObS(!E9f)-%lS$E|`p)y@vfN#j~+}pPuB!o?egJKyR?Lv7;7b>i7NGkj< zWgxB(d{v%X{8y%%e9ya|YB>U2ReYe(pEB=(l zl+LA}1X*~dFdc<`fBrB*7oLM;-f0a_RPp-cOJGxPt@@=v3b>a?DwtT%VBR{z8j8uY zlBiFyhMCb||JqVbcuo~mojWDpcCUmBKyoYF?#8XtBbCm?gXimRZ*6d% zl3!-uyXu1HHnSTVvNu6TyWRzXLD$-$x$m9v;{?rfzWE0a^=@=VqgkDS<3lJ0lM%*- zFZVs~1%eiMl2hW96As*458}WY`Yw)cI5sQmHXPqgl_8AJi}3em8Ae7xGm}Mb(bqp{ z|Naw(=-r;1H*)nB`rvIp-{YyN{0?(F$oIV)^i1Cf9axh+4La7VKOa4O_fZ1p$lX7? zr5hyQwE~%X?C5UrDoAg+!I#GG#-VoyBf$@%Y3MwByK&?ta%PJBt7cf$fx?K)%VSS8H_R4PMkQqmeXUJiA{|N7@lRECti?|- z-E5*Q!VWiZZB78q-}%diA!V3Wvj{3FnY7*-2Uj@Kh~B2OV#587gFo z#7XwzrfbJKwQ0z4O~UzJ33<@4suu)jJ;C-t48o9OM+8A_O7? zA_O7?A_O7?A_O`S*ygFMk|{O%ybeQZX}>?D#%vufl*h%fOc8eeS{CD6`qi@K247mf z!>zn;T%H>%!Ii-?V4Pz!Q}pvDLvHkWJ@OWN=H0R>x8c0W)Ej+Xi@b%NdACaH=N;Pr z8=%}|>Ww~G{HQ)@@9MH-HEpy+Q?fc zZ)h@mRv^d{1o84&J@bZ#b>A49hlv>)Y?+@MAaAm3MIWkzPwts_C*Casbpzy0QyuzH-scXGcguv`0D03UD}4y> zOMB+siHRASjT<0uGJr!L!h57=-ktS(BYD#tnm&Zd1wHfb#JgpjZ-8>s$_;%UM&4KV z%)8af*K6}DCq$7?u&AVCUOX@i#h=aiGtyf8XTg%iFt^gU>e}d~N1v}E@2dvMJG|4$5Mu9uR}*kjD2~b8>RA?rF-{^Qy7SH*ciw;J{r_$I^0r^!_TjA`zVE~LRkwcioa@i|Wc$(_0EmtVfe3+L z2?Sg$HHR*{o*#rVt!o)(^_q>9(hOnMece7>+E<)_ zhFHEpx$dJ}_aSuMzO0MyJbnKX#o>7>4!+M&dH5diNc<{192JKBr*OLK}SpOg=n zE@+RNr#f4uSuD5D-f26$a?A7FHc}Y zy6>9@18}qsL7^HX%3fEmoPLg-WYfBL1zNXr<oHCLp)Pe@$uDA&sJ$zv8@6jyjp>J@vFUo ziCzmky?uQw_A;2R^p9cYpCSMMyrG}({Ok^O`vu#!ZvEDlFK@ng(}!b!a<-=?y61z2 zO0k~k#%FH$_v`zKZj|A2cjd$$Y%#P1S*nNNZgt}V8?vK`oB+utL4^@!eG1}Dwqmoq zWa$!bXE=qk2N3GAMxbAZuCTZW|-ds?d=fQ(6Q6uAL}9U;cq{!FB0TB__QFQ zY9>4asj$hfD)^exE07U%OqSzxUNsC;vBbv?3Gx6$$9hQokB>ja?pG!AKBd0LWj z8?Gi9Ly;6ka@dT*J1hipbry1QDhr`g_~8%?i_`4I|H*XIyCDJhZsskX#1lz9`LbZ0 z->+s!{_Uk69rYxhI^}wF&wRg+kF!U7aLtfv~hXtSKINDzVJ98{#mk22kKH$!x%_ptQ9zHDUY_syP5?pcU@ z&7yt37_`5u#n3im2n8+U)6q+6(tYnc41$8$_1S;&&VE$y`y?nVI3(FH45}eof}^Rd z<2Yz86&0qz1x{vpO%zO1;7R^%5j$zOhj;b_qUW29g{da?K)JDHhUmj>6q*nw(NQ8_ zvbOWP$-D$a(q9K*MeK#3c8Jo9?(LS+J!x4wJbFR2_;;6&6ExvDj7#TrWNz00OF}K{ zB^akWs-d8Au(k}pEYdV5vT(Yju^iksSwKt>9eeR)L-cQAi0<|TMM?hpj+2O*4mrDT zcytINjulk(Krk*gi9JEx+vKIk>Xy!?-|e!tpS<_ppT853yzt)p9;Gv-2@lvXMkVPj z_8-3{-Yn1GxR!YK+T#D{cL9z>PEk;WB%z|RxAhXV2i$HQ-WdESkB zO?K6N0pVM`cHXUjK~BKvSP!{pzWxJ0K1Jl_+c??#}bg8s6VQqr(Vs=$Mbl(C`OBH`t$b3D&x;5h_dlr#lyL>AA9b<@MB zbPqHCtF`^t*?s&qR9-#^e*y0W`5lSxf~6Z;k~E=XJ!o&g<>DV~0NTBc3ftZTTrq#; zHKCn&bOxxZ_1f&wczJpnn3v~U=If`bUN6v~PUULy7}1z!;UcGbH0)tIkUyPW1FxC7 zVaq0);Y9Qg{EW;R1_x~|-4IOKu`NLq7P(kAZI2N#f!~#%Ge7R2e}SukufT%?jRlsN z&wxJRx&7$w8ZeUZj_y|&U2K1a{q#p~o*^zk6XO4McMbk4>?BPHDaNGF*^nlLoDpP` zGvF8s9uOh<54R|$o{?D%szxF&z<$1M4lrrz)`IZm+iAkImL>#A5Ye$-ef+_{{o8Ir z;@j-9L1!-!zG$1?pFXyYhJT|`o}0sa#(&Mk;bIl8=?<**Lhn7y;U!6@IU{SUGU~{* z2pthlf&00Pp=p|6qs0n~UtqfF9SqSMA-&{N=uV>j{3_`3kv1REVQ-+^KJvqOFZPx# ztN#C{NB(B$>Rqqj@!f6i)=zEu)E7SWg}<^1fubjsMxpkDreC3kN&EF);jjjVLj;OL z4k%8WTR-v#aw~izIlQ5XEYu?5!f(0)g-AyO@KOlpZ9`skZWfI>b^U#o(CiyI+d0H4=lFBVLU1* zlc>uXI7EW)BUzR*x~N+NxyiV)jSp7_e7GcbN$mXC&JJQ?~Ev2UR^4{hVq z+CTM{4nUukfe4=Nh!)fWCG=UkinYXyCgWY8z=0yX+48D3P+PgQt*u--a9jBR26O$% zUy7n{Ujffo!h1Co@%%Y8Ei=40bScwv9u*Ed+BraLFyYE&`}JPoZmt}}tNjdfMYl7m zX{r`0WS|WW)p{uB**sn+wjf)osu&7CSP%B>Hm*GTta2qB0<|MfE2miO80hHc3ME=O zafX~)_IlsY3*XW$4lj22V-m4IM9a^H2F*#4vqi~LY(p}fff~=V+Sv50fK6w|8)7eZ z(C9OSe?4A>@j6FZXWAPgcq2=yY)TpO21}a00^G3amTt3xgUP+d!!MgPSQEOqjW-tu zyg57mlu4ey`=D#RnpSr_`u(`!4IHe)5jdP%>jI2CNSZLinzXR$XcSy06-6UYpXl9W4BJ!@CLSaMZYMK?`Tx71jW-vZMc%|> zuNw*F|FJgmpid8v{#mcrP&W&s-w^^40ucfc0ucfc0ucfc0ucfc0ucghB4EJ2V}q%~ zBG~~*qs3vRt?KQpHt>B2zw68lzAe~pv!Fg0$F(}*EI_!gf?xBHUn8-t1@F9o5M8|j zzbH(vB%HD)< z?rP~)P8jh)ug`dPPy^A0`23V79=On`#IKlIXfz_BtO%gXTOWJyjmJ~vyQ!riO2`Ra59+0>f{J;RcL9BI5`H4@?& z4PamvMG+$eA_O7?A_O7?A_O7? zA_O7?A_O7?A_UGN0%=(CnSkiXK75K0rP$*MmQ-Ld+JQg@33`Mg7-a}sjKNCve&#yZ zlpcqQyn#3lY)^BH2JsV{VOLJ1-HFV;OmS>a`A}tibv{0J?S2?!8f@x4md@<4gKWAp zge{vfr{rbsHp{i?a$_1cRAz8FFC-G=Z*#5GEekfMTAWzyX~T~O`~O>*(&&3(0g&yb z=5!Vr8r?cVAVMHQAVMHQAVMHQAVMHQAVMHQ;EW?Mj2+oqEkzJub(Lp1LmGoP43i^nv(l*4n@8s=um@L}t&oHG_*|n7dvVR95X@efoUKlAaKy%> zH@$%Ddyp}eTL&^Ex^f~}gFWUHS$%sI%`N4?@YFes#`28_f) zIUUvn)M*&9F%?#kG#H3g71$>vlW2Bjro1rQw0#wWwMvXq4rIj`@odhNR8i$&@z8;l z2}yz(Fiy5uF=I)vcqG{}FD<^Gc|VNtJ`Xg}qCDI@1y3>TJ%yctK?)IOLQR;FhMCYw zi8Vz-VFd$rEi2DVXlx3T1gj8mN&r*iRUL-6O%L6P&F7f)8O?} z8_bU8HEmqE=B#q%ynqw!r;G99mowN5E%}-10qEMFq2^-98O>2F0qr9L1Ep(CL+c(J$>f|U3^|zZvTclE1IAn$yEJw|Y`B9q!^ZiK11slW zZ28v+{cLoe$q9r{zQ-Nk>yGcS=}vf&As;f6Cs_v$J;$^&hM4lWG9};7-t6fzFn?7W kJFW`YabfJj*l28X2mOrs0sQlQ%cFZwvtjdZ-nEVY|5Y95g#Z8m From 14c698c9e7b30b8036d84b8582b7cc4f86824a4c Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Wed, 7 Nov 2018 12:08:24 +0100 Subject: [PATCH 30/85] Added component model proposal to EA. --- crce.eap | Bin 1777664 -> 1787904 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/crce.eap b/crce.eap index 1beed7b3d2c789549602c43445e7e14ac4855b9a..fd88ea55e00123f68f1153d38a6a1db7b6e17c90 100644 GIT binary patch delta 48821 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 R(CT1Si|R&HtOKe4{{o!IkUanZ delta 18762 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 From d42d0d84d7d615e974815fd48a998ce4f224381c Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Sat, 10 Nov 2018 19:33:34 +0100 Subject: [PATCH 31/85] #2: Fixed inner dependencies of shared-build-settings and core modules. --- build/pom.xml | 2 +- core/crce-core/pom.xml | 2 +- core/crce-metadata-api/pom.xml | 2 +- core/crce-metadata-dao-api/pom.xml | 4 ++-- core/crce-metadata-dao-impl/pom.xml | 2 +- core/crce-metadata-impl/pom.xml | 4 ++-- core/crce-metadata-indexer-api/pom.xml | 6 +++--- core/crce-metadata-indexer-impl/pom.xml | 10 +++++----- core/crce-metadata-json-api/pom.xml | 4 ++-- core/crce-metadata-json-impl/pom.xml | 6 +++--- core/crce-metadata-service-api/pom.xml | 4 ++-- core/crce-metadata-service-impl/pom.xml | 4 ++-- core/crce-plugin-api/pom.xml | 2 +- core/crce-repository-api/pom.xml | 6 +++--- core/crce-repository-impl/pom.xml | 10 +++++----- core/crce-resolver-api/pom.xml | 4 ++-- core/crce-resolver-impl/pom.xml | 2 +- modules/pom.xml | 4 ++-- 18 files changed, 39 insertions(+), 39 deletions(-) diff --git a/build/pom.xml b/build/pom.xml index 64f28433..0676f4c3 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce crce-parent - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/core/crce-core/pom.xml b/core/crce-core/pom.xml index 1811c2a2..96942736 100644 --- a/core/crce-core/pom.xml +++ b/core/crce-core/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce crce-parent - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/core/crce-metadata-api/pom.xml b/core/crce-metadata-api/pom.xml index 303c5ec3..858efb00 100644 --- a/core/crce-metadata-api/pom.xml +++ b/core/crce-metadata-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/core/crce-metadata-dao-api/pom.xml b/core/crce-metadata-dao-api/pom.xml index 483bcd54..8026450a 100644 --- a/core/crce-metadata-dao-api/pom.xml +++ b/core/crce-metadata-dao-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1-SNAPSHOT + 2.1.2-SNAPSHOT @@ -35,7 +35,7 @@ ${project.groupId} crce-metadata-api - 3.0.0 + 3.0.1-SNAPSHOT diff --git a/core/crce-metadata-dao-impl/pom.xml b/core/crce-metadata-dao-impl/pom.xml index 84a14837..46ca58d3 100644 --- a/core/crce-metadata-dao-impl/pom.xml +++ b/core/crce-metadata-dao-impl/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/core/crce-metadata-impl/pom.xml b/core/crce-metadata-impl/pom.xml index 1f6c4228..c1264597 100644 --- a/core/crce-metadata-impl/pom.xml +++ b/core/crce-metadata-impl/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT @@ -46,7 +46,7 @@ ${project.groupId} crce-metadata-json-api - 2.1.0 + 2.1.1-SNAPSHOT true diff --git a/core/crce-metadata-indexer-api/pom.xml b/core/crce-metadata-indexer-api/pom.xml index 3524afeb..4db512f2 100644 --- a/core/crce-metadata-indexer-api/pom.xml +++ b/core/crce-metadata-indexer-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT @@ -32,12 +32,12 @@ ${project.groupId} crce-plugin-api - 2.1.0 + 2.1.1-SNAPSHOT ${project.groupId} crce-metadata-api - 3.0.0 + 3.0.1-SNAPSHOT diff --git a/core/crce-metadata-indexer-impl/pom.xml b/core/crce-metadata-indexer-impl/pom.xml index 4e115979..001698a1 100644 --- a/core/crce-metadata-indexer-impl/pom.xml +++ b/core/crce-metadata-indexer-impl/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT @@ -32,22 +32,22 @@ ${project.groupId} crce-plugin-api - 2.1.0 + 2.1.1-SNAPSHOT ${project.groupId} crce-metadata-api - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} crce-metadata-service-api - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} crce-metadata-indexer-api - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/core/crce-metadata-json-api/pom.xml b/core/crce-metadata-json-api/pom.xml index 60b02a3c..19aaf406 100644 --- a/core/crce-metadata-json-api/pom.xml +++ b/core/crce-metadata-json-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1-SNAPSHOT + 2.1.2-SNAPSHOT @@ -32,7 +32,7 @@ ${project.groupId} crce-metadata-api - 2.1.0 + 3.0.1-SNAPSHOT diff --git a/core/crce-metadata-json-impl/pom.xml b/core/crce-metadata-json-impl/pom.xml index ed874835..67ee2c99 100644 --- a/core/crce-metadata-json-impl/pom.xml +++ b/core/crce-metadata-json-impl/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT @@ -55,12 +55,12 @@ ${project.groupId} crce-metadata-api - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} crce-metadata-json-api - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/core/crce-metadata-service-api/pom.xml b/core/crce-metadata-service-api/pom.xml index 9205a403..0394144f 100644 --- a/core/crce-metadata-service-api/pom.xml +++ b/core/crce-metadata-service-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT @@ -32,7 +32,7 @@ ${project.groupId} crce-metadata-api - 3.0.0 + 3.0.1-SNAPSHOT diff --git a/core/crce-metadata-service-impl/pom.xml b/core/crce-metadata-service-impl/pom.xml index 64ccfaad..11c9d7aa 100644 --- a/core/crce-metadata-service-impl/pom.xml +++ b/core/crce-metadata-service-impl/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT @@ -44,7 +44,7 @@ ${project.groupId} crce-metadata-api - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} diff --git a/core/crce-plugin-api/pom.xml b/core/crce-plugin-api/pom.xml index 7a20350d..0807fda7 100644 --- a/core/crce-plugin-api/pom.xml +++ b/core/crce-plugin-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1-SNAPSHOT + 2.1.2-SNAPSHOT diff --git a/core/crce-repository-api/pom.xml b/core/crce-repository-api/pom.xml index df6f9e58..e5acf97f 100644 --- a/core/crce-repository-api/pom.xml +++ b/core/crce-repository-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT @@ -35,12 +35,12 @@ ${project.groupId} crce-metadata-api - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} crce-plugin-api - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/core/crce-repository-impl/pom.xml b/core/crce-repository-impl/pom.xml index dc50f4aa..cd7abe86 100644 --- a/core/crce-repository-impl/pom.xml +++ b/core/crce-repository-impl/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT @@ -58,12 +58,12 @@ ${project.groupId} crce-metadata-api - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} crce-metadata-service-api - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} @@ -73,7 +73,7 @@ ${project.groupId} crce-plugin-api - 2.1.0 + 2.1.1-SNAPSHOT ${project.groupId} @@ -88,7 +88,7 @@ ${project.groupId} crce-metadata-indexer-api - 2.1.0 + 2.1.1-SNAPSHOT diff --git a/core/crce-resolver-api/pom.xml b/core/crce-resolver-api/pom.xml index 1f77b8a8..27a1591d 100644 --- a/core/crce-resolver-api/pom.xml +++ b/core/crce-resolver-api/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT @@ -35,7 +35,7 @@ ${project.groupId} crce-metadata-api - 3.0.0 + 3.0.1-SNAPSHOT diff --git a/core/crce-resolver-impl/pom.xml b/core/crce-resolver-impl/pom.xml index 6e0e1cb1..d7f071a4 100644 --- a/core/crce-resolver-impl/pom.xml +++ b/core/crce-resolver-impl/pom.xml @@ -6,7 +6,7 @@ cz.zcu.kiv.crce compiled-bundle-settings - 2.1.1 + 2.1.2-SNAPSHOT diff --git a/modules/pom.xml b/modules/pom.xml index cf477759..9dd10c95 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -68,13 +68,13 @@ - crce-handler-metrics + crce-webui crce-rest-v2 - crce-optimizer-functions + crce-compatibility-api crce-compatibility-dao-api From 7aab60aa6c7117afa239f2f47a9cee718d3d7a5e Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Wed, 14 Nov 2018 18:50:19 +0100 Subject: [PATCH 32/85] #2: Inner dependencies of modules in module folder fixed. --- core/crce-core/pom.xml | 8 ++++---- modules/crce-metadata-osgi-bundle/pom.xml | 2 +- modules/crce-vo/pom.xml | 4 ++-- modules/crce-webservices-indexer/pom.xml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/crce-core/pom.xml b/core/crce-core/pom.xml index 96942736..7f0f1bb8 100644 --- a/core/crce-core/pom.xml +++ b/core/crce-core/pom.xml @@ -47,22 +47,22 @@ ${project.groupId} crce-metadata-indexer-impl - 2.1.0 + 2.1.1-SNAPSHOT ${project.groupId} crce-metadata-indexer-api - 2.1.0 + 2.1.1-SNAPSHOT ${project.groupId} crce-metadata-json-api - 2.1.0 + 2.1.1-SNAPSHOT ${project.groupId} crce-metadata-json-impl - 3.0.0 + 3.0.1-SNAPSHOT ${project.groupId} diff --git a/modules/crce-metadata-osgi-bundle/pom.xml b/modules/crce-metadata-osgi-bundle/pom.xml index b7e57f99..b3f19feb 100644 --- a/modules/crce-metadata-osgi-bundle/pom.xml +++ b/modules/crce-metadata-osgi-bundle/pom.xml @@ -63,7 +63,7 @@ cz.zcu.kiv.crce crce-metadata-impl - 3.0.0 + 3.0.1-SNAPSHOT test diff --git a/modules/crce-vo/pom.xml b/modules/crce-vo/pom.xml index b9dffd8e..4a930d5c 100644 --- a/modules/crce-vo/pom.xml +++ b/modules/crce-vo/pom.xml @@ -18,7 +18,7 @@ ${namespace}.vo ${namespace}.vo - 3.0.0 + 3.0.1-SNAPSHOT @@ -36,7 +36,7 @@ cz.zcu.kiv.crce crce-metadata-service-api - 3.0.0 + 3.0.1-SNAPSHOT diff --git a/modules/crce-webservices-indexer/pom.xml b/modules/crce-webservices-indexer/pom.xml index 0f2ae495..eb67cc73 100644 --- a/modules/crce-webservices-indexer/pom.xml +++ b/modules/crce-webservices-indexer/pom.xml @@ -43,7 +43,7 @@ ${project.groupId} crce-concurrency - 2.1.0-SNAPSHOT + 2.2.0-SNAPSHOT jar From 8b5259b8868f27439f091681cef634169148cf0a Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Sat, 1 Dec 2018 22:24:06 +0100 Subject: [PATCH 33/85] #6: Added default implementation of Compatibility, Diff and CompatibilityFactory interfaces. Added tests. --- .../compatibility/CompatibilityFactory.java | 8 +- .../impl/DefaultCompatibilityFactoryImpl.java | 27 +++ .../impl/DefaultCompatibilityImpl.java | 167 ++++++++++++++++++ .../compatibility/impl/DefaultDiffImpl.java | 115 ++++++++++++ .../DefaultCompatibilityImplTest.java | 72 ++++++++ 5 files changed, 385 insertions(+), 4 deletions(-) create mode 100644 modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityFactoryImpl.java create mode 100644 modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityImpl.java create mode 100644 modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultDiffImpl.java create mode 100644 modules/crce-compatibility-api/src/test/java/cz.zcu.kiv.crce.compatibility/DefaultCompatibilityImplTest.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityFactory.java b/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityFactory.java index a8070374..5b432d0e 100644 --- a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityFactory.java +++ b/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityFactory.java @@ -1,9 +1,9 @@ package cz.zcu.kiv.crce.compatibility; -import java.util.List; - import cz.zcu.kiv.crce.metadata.type.Version; +import java.util.List; + /** * Factory interface for Compatibility. * @@ -15,7 +15,7 @@ public interface CompatibilityFactory { /** * - * Factory method for complete initialization of Compability implementation. + * Factory method for complete initialization of Compatibility implementation. * * @param id unique id * @param resourceName compared resource name (crce.identity) @@ -32,7 +32,7 @@ Compatibility createCompatibility(String id, String resourceName, Version resour /** * - * Factory method for complete initialization of Compability implementation. Base name is set to the same + * Factory method for complete initialization of Compatibility implementation. Base name is set to the same * value as resource name. * * @param id unique id diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityFactoryImpl.java b/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityFactoryImpl.java new file mode 100644 index 00000000..45afe423 --- /dev/null +++ b/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityFactoryImpl.java @@ -0,0 +1,27 @@ +package cz.zcu.kiv.crce.compatibility.impl; + +import cz.zcu.kiv.crce.compatibility.*; +import cz.zcu.kiv.crce.metadata.type.Version; + +import java.util.List; + +/** + * Factory which creates default implementations of Compatibility interfaces. + */ +public class DefaultCompatibilityFactoryImpl implements CompatibilityFactory { + + @Override + public Compatibility createCompatibility(String id, String resourceName, Version resourceVersion, String baseName, Version baseVersion, Difference diffValue, List diffValues, Contract contract) { + return new DefaultCompatibilityImpl(id, resourceName, resourceVersion, baseName, baseVersion, diffValue, diffValues, contract); + } + + @Override + public Compatibility createCompatibility(String id, String resourceName, Version resourceVersion, Version baseVersion, Difference diffValue, List diffValues, Contract contract) { + return new DefaultCompatibilityImpl(id, resourceName, resourceVersion, resourceName, baseVersion, diffValue, diffValues, contract); + } + + @Override + public Diff createEmptyDiff() { + return new DefaultDiffImpl(); + } +} diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityImpl.java b/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityImpl.java new file mode 100644 index 00000000..f82d5a5a --- /dev/null +++ b/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityImpl.java @@ -0,0 +1,167 @@ +package cz.zcu.kiv.crce.compatibility.impl; + +import cz.zcu.kiv.crce.compatibility.Compatibility; +import cz.zcu.kiv.crce.compatibility.Contract; +import cz.zcu.kiv.crce.compatibility.Diff; +import cz.zcu.kiv.crce.compatibility.Difference; +import cz.zcu.kiv.crce.metadata.type.Version; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; + +/** + * Default implementation of Compatibility interface. Serves as a starting point + * for other implementations. + */ +public class DefaultCompatibilityImpl implements Compatibility { + + private String id; + private String resourceName; + private Version resourceVersion; + private String baseResourceName; + private Version baseResourceVersion; + private Difference diffValue; + private List diffDetails; + private Contract contract; + + /** + * Default constructor. Leaves all fields empty. + */ + public DefaultCompatibilityImpl() { + } + + /** + * Fully initialized instance. + * @param id + * @param resourceName + * @param resourceVersion + * @param baseResourceName + * @param baseResourceVersion + * @param diffValue + * @param diffDetails + * @param contract + */ + public DefaultCompatibilityImpl(String id, String resourceName, Version resourceVersion, String baseResourceName, Version baseResourceVersion, Difference diffValue, List diffDetails, Contract contract) { + this.id = id; + this.resourceName = resourceName; + this.resourceVersion = resourceVersion; + this.baseResourceName = baseResourceName; + this.baseResourceVersion = baseResourceVersion; + this.diffValue = diffValue; + this.diffDetails = diffDetails; + this.contract = contract; + } + + @Override + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Nonnull + @Override + public String getResourceName() { + return resourceName; + } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + @Nonnull + @Override + public Version getResourceVersion() { + return resourceVersion; + } + + public void setResourceVersion(Version resourceVersion) { + this.resourceVersion = resourceVersion; + } + + @Nullable + @Override + public String getBaseResourceName() { + return baseResourceName; + } + + public void setBaseResourceName(String baseResourceName) { + this.baseResourceName = baseResourceName; + } + + @Nonnull + @Override + public Version getBaseResourceVersion() { + return baseResourceVersion; + } + + public void setBaseResourceVersion(Version baseResourceVersion) { + this.baseResourceVersion = baseResourceVersion; + } + + @Nonnull + @Override + public Difference getDiffValue() { + return diffValue; + } + + public void setDiffValue(Difference diffValue) { + this.diffValue = diffValue; + } + + @Nullable + @Override + public List getDiffDetails() { + return diffDetails; + } + + public void setDiffDetails(List diffDetails) { + this.diffDetails = diffDetails; + } + + @Nonnull + @Override + public Contract getContract() { + return contract; + } + + public void setContract(Contract contract) { + this.contract = contract; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + DefaultCompatibilityImpl that = (DefaultCompatibilityImpl) o; + + if (baseResourceName != null ? !baseResourceName.equals(that.baseResourceName) : that.baseResourceName != null) + return false; + if (baseResourceVersion != null ? !baseResourceVersion.equals(that.baseResourceVersion) : that.baseResourceVersion != null) + return false; + if (diffDetails != null ? !diffDetails.equals(that.diffDetails) : that.diffDetails != null) return false; + if (diffValue != that.diffValue) return false; + if (contract != that.contract) return false; + if (resourceName != null ? !resourceName.equals(that.resourceName) : that.resourceName != null) return false; + if (resourceVersion != null ? !resourceVersion.equals(that.resourceVersion) : that.resourceVersion != null) + return false; + + return true; + } + + @Override + public int hashCode() { + int result = resourceName != null ? resourceName.hashCode() : 0; + result = 31 * result + (resourceVersion != null ? resourceVersion.hashCode() : 0); + result = 31 * result + (baseResourceName != null ? baseResourceName.hashCode() : 0); + result = 31 * result + (baseResourceVersion != null ? baseResourceVersion.hashCode() : 0); + result = 31 * result + (diffValue != null ? diffValue.hashCode() : 0); + result = 31 * result + (diffDetails != null ? diffDetails.hashCode() : 0); + result = 31 * result + (contract != null ? contract.hashCode() : 0); + return result; + } +} diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultDiffImpl.java b/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultDiffImpl.java new file mode 100644 index 00000000..e465914a --- /dev/null +++ b/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultDiffImpl.java @@ -0,0 +1,115 @@ +package cz.zcu.kiv.crce.compatibility.impl; + +import cz.zcu.kiv.crce.compatibility.Diff; +import cz.zcu.kiv.crce.compatibility.Difference; +import cz.zcu.kiv.crce.compatibility.DifferenceLevel; +import cz.zcu.kiv.crce.compatibility.DifferenceRole; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; + +/** + * Default implementation of Diff interface. Serves as a starting point for future + * implementations. + */ +public class DefaultDiffImpl implements Diff { + + private String name; + private Difference value; + private DifferenceLevel level; + private DifferenceRole role; + private List children; + private String namespace; + private String syntax; + + public DefaultDiffImpl() { + this.children = new ArrayList<>(); + this.name = ""; + this.value = Difference.UNK; + this.level = DifferenceLevel.UNKNOWN; + } + + @Nonnull + @Override + public DifferenceLevel getLevel() { + return level; + } + + @Override + public void setLevel(@Nonnull DifferenceLevel level) { + this.level = level; + } + + @Nonnull + @Override + public String getName() { + return name; + } + + @Override + public void setName(@Nonnull String name) { + this.name = name; + } + + @Nonnull + @Override + public Difference getValue() { + return value; + } + + @Override + public void setValue(@Nonnull Difference value) { + this.value = value; + } + + @Nonnull + @Override + public List getChildren() { + return children; + } + + @Override + public void addChild(@Nonnull Diff child) { + this.children.add(child); + } + + @Override + public void addChildren(@Nonnull List children) { + this.children.addAll(children); + } + + @Nullable + @Override + public DifferenceRole getRole() { + return role; + } + + @Override + public void setRole(@Nullable DifferenceRole role) { + this.role = role; + } + + @Nullable + @Override + public String getNamespace() { + return namespace; + } + + @Override + public void setNamespace(@Nullable String namespace) { + this.namespace = namespace; + } + + @Nullable + @Override + public String getSyntax() { + return syntax; + } + + @Override + public void setSyntax(@Nullable String syntax) { + this.syntax = syntax; + } +} diff --git a/modules/crce-compatibility-api/src/test/java/cz.zcu.kiv.crce.compatibility/DefaultCompatibilityImplTest.java b/modules/crce-compatibility-api/src/test/java/cz.zcu.kiv.crce.compatibility/DefaultCompatibilityImplTest.java new file mode 100644 index 00000000..32842b09 --- /dev/null +++ b/modules/crce-compatibility-api/src/test/java/cz.zcu.kiv.crce.compatibility/DefaultCompatibilityImplTest.java @@ -0,0 +1,72 @@ +package cz.zcu.kiv.crce.compatibility; + +import cz.zcu.kiv.crce.compatibility.impl.DefaultCompatibilityFactoryImpl; +import cz.zcu.kiv.crce.compatibility.impl.DefaultDiffImpl; +import cz.zcu.kiv.crce.metadata.type.Version; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Test of default implementation of {@link Compatibility} interface. + */ +public class DefaultCompatibilityImplTest { + + private static CompatibilityFactory factory; + + @BeforeClass + public static void beforeClass() { + factory = new DefaultCompatibilityFactoryImpl(); + } + + /** + * Test that factory returns correct compatibility. + */ + @Test + public void factoryTest() { + final String id = "id"; + final String resourceName = "resourceName"; + final Version resourceVersion = new Version(1,0,0); + final String baseName = "baseName"; + final Version baseVersion = new Version(1,0,0); + final Difference diffValue = Difference.NON; + final List diffValues = new ArrayList<>(); + diffValues.add(new DefaultDiffImpl()); + final Contract contract = Contract.SYNTAX; + + // create compatibilities + Compatibility c1 = factory.createCompatibility(id, + resourceName, resourceVersion, baseName, + baseVersion, diffValue, diffValues, contract); + + Compatibility c2 = factory.createCompatibility(id, + resourceName, resourceVersion, baseVersion, + diffValue, diffValues, contract); + + // checks + checkCompatibility(c1, id, resourceName, resourceVersion, baseName, + baseVersion, diffValue, diffValues, contract); + checkCompatibility(c2, id, resourceName, resourceVersion, resourceName, + baseVersion, diffValue, diffValues, contract); + } + + /** + * Checks that the compatibility is not null and all necessary fields are set correctly. + */ + private void checkCompatibility(Compatibility toCheck, String id, String resourceName, Version resourceVersion, String baseName, + Version baseVersion, Difference diffValue, List diffValues, Contract contract) { + assertNotNull("Compatibility is null!", toCheck ); + assertEquals("Wrong id!", id, toCheck.getId()); + assertEquals("Wrong resource name!", resourceName, toCheck.getResourceName()); + assertEquals("Wrong base name!", baseName, toCheck.getBaseResourceName()); + assertEquals("Wrong base version!", baseVersion, toCheck.getBaseResourceVersion()); + assertEquals("Wrong difference value!", diffValue, toCheck.getDiffValue()); + assertEquals("Wrong number of difference values!", diffValues.size(), toCheck.getDiffDetails().size()); + assertEquals("Wrong contract!", contract, toCheck.getContract()); + } +} From ff2546228659f90e8ecd986a3e2889a8cca528b7 Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Sat, 1 Dec 2018 22:24:22 +0100 Subject: [PATCH 34/85] Added updated EA project. --- crce.eap | Bin 1787904 -> 1804288 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/crce.eap b/crce.eap index fd88ea55e00123f68f1153d38a6a1db7b6e17c90..7f1b21428a371ce3ff8cb3f4b048bfb11a057641 100644 GIT binary patch delta 7001 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 P+T^dX*|wM_9j^X=oQzp{ delta 5386 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 Date: Sun, 2 Dec 2018 22:00:43 +0100 Subject: [PATCH 35/85] #5: Added test for OsgiManifestBundleIndexer. --- .../internal/OsgiManifestBundleIndexer.java | 56 ++++--------- .../OsgiManifestBundleIndexerTest.java | 79 ++++++++++++++++++ .../src/test/resources/test.jar | Bin 0 -> 274 bytes 3 files changed, 97 insertions(+), 38 deletions(-) create mode 100644 modules/crce-metadata-osgi-bundle/src/test/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexerTest.java create mode 100644 modules/crce-metadata-osgi-bundle/src/test/resources/test.jar diff --git a/modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexer.java b/modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexer.java index 0e3e01c4..82b41eba 100644 --- a/modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexer.java +++ b/modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexer.java @@ -35,55 +35,34 @@ */ package cz.zcu.kiv.crce.metadata.osgi.internal; +import cz.zcu.kiv.crce.metadata.*; +import cz.zcu.kiv.crce.metadata.impl.SimpleAttributeType; +import cz.zcu.kiv.crce.metadata.indexer.AbstractResourceIndexer; import cz.zcu.kiv.crce.metadata.namespace.NsCrceIdentity; -import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiPackage; -import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiFragment; -import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiBundle; -import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiExecutionEnvironment; -import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiIdentity; -import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiService; - -import java.io.*; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLStreamHandler; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import java.util.jar.JarFile; -import java.util.jar.Manifest; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipInputStream; - +import cz.zcu.kiv.crce.metadata.osgi.namespace.*; +import cz.zcu.kiv.crce.metadata.service.MetadataService; +import cz.zcu.kiv.crce.metadata.type.Version; import org.apache.felix.utils.manifest.Attribute; import org.apache.felix.utils.manifest.Clause; import org.apache.felix.utils.manifest.Directive; import org.apache.felix.utils.manifest.Parser; import org.apache.felix.utils.version.VersionCleaner; import org.apache.felix.utils.version.VersionRange; - import org.osgi.framework.Constants; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import cz.zcu.kiv.crce.metadata.AttributeType; -import cz.zcu.kiv.crce.metadata.Capability; -import cz.zcu.kiv.crce.metadata.Operator; -import cz.zcu.kiv.crce.metadata.Requirement; -import cz.zcu.kiv.crce.metadata.Resource; -import cz.zcu.kiv.crce.metadata.MetadataFactory; -import cz.zcu.kiv.crce.metadata.impl.SimpleAttributeType; -import cz.zcu.kiv.crce.metadata.indexer.AbstractResourceIndexer; -import cz.zcu.kiv.crce.metadata.service.MetadataService; -import cz.zcu.kiv.crce.metadata.type.Version; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.*; +import java.util.*; +import java.util.jar.JarFile; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; +import java.util.zip.ZipException; +import java.util.zip.ZipInputStream; /** * This is original class DataModelHelperImpl adopted from org.apache.felix.bundlerepository. @@ -190,6 +169,7 @@ public Resource fillResource(final URL bundleUrl, Resource resource) throws IOEx @Override public String getHeader(String name) throws IOException { String value = manifest.getMainAttributes().getValue(name); + // #5: this will only index properties in manifest which start with '%' symbol if (value != null && value.startsWith("%")) { if (localization == null) { localization = new Properties(); diff --git a/modules/crce-metadata-osgi-bundle/src/test/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexerTest.java b/modules/crce-metadata-osgi-bundle/src/test/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexerTest.java new file mode 100644 index 00000000..92798846 --- /dev/null +++ b/modules/crce-metadata-osgi-bundle/src/test/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexerTest.java @@ -0,0 +1,79 @@ +package cz.zcu.kiv.crce.metadata.osgi.internal; + +import cz.zcu.kiv.crce.metadata.Capability; +import cz.zcu.kiv.crce.metadata.MetadataFactory; +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.metadata.indexer.AbstractResourceIndexer; +import cz.zcu.kiv.crce.metadata.internal.MetadataFactoryImpl; +import cz.zcu.kiv.crce.metadata.internal.ResourceImpl; +import cz.zcu.kiv.crce.metadata.service.MetadataService; +import cz.zcu.kiv.crce.metadata.service.internal.MetadataServiceImpl; +import jdk.nashorn.internal.ir.annotations.Ignore; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.lang.reflect.Field; +import java.net.URISyntaxException; +import java.util.List; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Simple test to check that {@link OsgiManifestBundleIndexer} is capable + * of indexing generic jars. + */ +public class OsgiManifestBundleIndexerTest { + + private static AbstractResourceIndexer indexer; + private static MetadataService metadataService; + + @BeforeClass + public static void beforeClass() throws NoSuchFieldException, IllegalAccessException { + indexer = new OsgiManifestBundleIndexer(); + final MetadataFactory metadataFactory = new MetadataFactoryImpl(); + metadataService = new MetadataServiceImpl(); + + // set needed fields via reflection + Field field = MetadataServiceImpl.class.getDeclaredField("metadataFactory"); + field.setAccessible(true); + field.set(metadataService, metadataFactory); + + field = OsgiManifestBundleIndexer.class.getDeclaredField("metadataFactory"); + field.setAccessible(true); + field.set(indexer, metadataFactory); + field = OsgiManifestBundleIndexer.class.getDeclaredField("metadataService"); + field.setAccessible(true); + field.set(indexer, metadataService); + + } + + /** + * Test jar contains only a manifest file with following parameters: + * Manifest-Version: 1.0 + * Test-property: test + */ + @Test + @Ignore // OsgiManifestBundleIndexer currently only index osgi bundles + public void testIndexGenericJar() throws FileNotFoundException, URISyntaxException { + // jar name in resource folder + final String jarName = "/test.jar"; + final File testJar = new File(OsgiManifestBundleIndexerTest.class.getResource(jarName).toURI()); + final String testPropName = "Test-property"; + final String expTestPropValue = "test"; + Resource r = new ResourceImpl("test-resource"); + + // make sure that the test jar really exists + assertTrue("Test jar does not exist!", testJar.exists()); + + indexer.index(new FileInputStream(testJar), r); + + // test that jar was indexed correctly + List capabilityList = r.getRootCapabilities(); + assertFalse("No capabilities indexed for test jar!", capabilityList.isEmpty()); + } + +} diff --git a/modules/crce-metadata-osgi-bundle/src/test/resources/test.jar b/modules/crce-metadata-osgi-bundle/src/test/resources/test.jar new file mode 100644 index 0000000000000000000000000000000000000000..e51395a6fbd772ea79563d1508679ca092d75029 GIT binary patch literal 274 zcmWIWW@Zs#U}9ikh*;g^3#8zH6Ug#)4RO@<^mEe>fGXo)Pyj0P$nuoc0!r%uu?Vs< zUq?SrH`m}0JzuxazGqJRc;EEJQZIeHZ>$la|*-G zJuwUc-i%BlKyz?80%!pc2tX)gC&9E~cN9oHBZC5vR0m?XPmr7#;LXYglmc4J#83&O In?W1~00ts3Bme*a literal 0 HcmV?d00001 From f9af90559a8a3ce695e739593887e8b0a0c950f1 Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Mon, 3 Dec 2018 14:43:32 +0100 Subject: [PATCH 36/85] EA model update. --- crce.eap | Bin 1804288 -> 1804288 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/crce.eap b/crce.eap index 7f1b21428a371ce3ff8cb3f4b048bfb11a057641..c24941a24ba62d7c3cb79b3dd7bad33d2f7b18c4 100644 GIT binary patch delta 12506 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 From aba11b4d76c6dedc34ac9a12393d9c05229af2ad Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Mon, 3 Dec 2018 15:13:33 +0100 Subject: [PATCH 37/85] #5: Fixed Ignore dependency. --- .../osgi/internal/OsgiManifestBundleIndexerTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/crce-metadata-osgi-bundle/src/test/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexerTest.java b/modules/crce-metadata-osgi-bundle/src/test/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexerTest.java index 92798846..e6bc9cc8 100644 --- a/modules/crce-metadata-osgi-bundle/src/test/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexerTest.java +++ b/modules/crce-metadata-osgi-bundle/src/test/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexerTest.java @@ -8,8 +8,8 @@ import cz.zcu.kiv.crce.metadata.internal.ResourceImpl; import cz.zcu.kiv.crce.metadata.service.MetadataService; import cz.zcu.kiv.crce.metadata.service.internal.MetadataServiceImpl; -import jdk.nashorn.internal.ir.annotations.Ignore; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import java.io.File; @@ -62,8 +62,8 @@ public void testIndexGenericJar() throws FileNotFoundException, URISyntaxExcepti // jar name in resource folder final String jarName = "/test.jar"; final File testJar = new File(OsgiManifestBundleIndexerTest.class.getResource(jarName).toURI()); - final String testPropName = "Test-property"; - final String expTestPropValue = "test"; +// final String testPropName = "Test-property"; +// final String expTestPropValue = "test"; Resource r = new ResourceImpl("test-resource"); // make sure that the test jar really exists @@ -74,6 +74,7 @@ public void testIndexGenericJar() throws FileNotFoundException, URISyntaxExcepti // test that jar was indexed correctly List capabilityList = r.getRootCapabilities(); assertFalse("No capabilities indexed for test jar!", capabilityList.isEmpty()); + assertFalse("No child capabilities indexed for test jar!", capabilityList.get(0).getChildren().isEmpty()); } } From d1ed6f191bd924ebf6025f9509923c9c3d8848cc Mon Sep 17 00:00:00 2001 From: Radek Vais Date: Mon, 3 Dec 2018 12:55:10 +0100 Subject: [PATCH 38/85] Cajova-Houba/crce#4 move crce-concurrency from modules to core --- {modules => core}/crce-concurrency/osgi.bnd | 0 {modules => core}/crce-concurrency/pom.xml | 8 ++++---- .../cz/zcu/kiv/crce/concurrency/internal/Activator.java | 0 .../cz/zcu/kiv/crce/concurrency/internal/TaskRunner.java | 0 .../cz/zcu/kiv/crce/concurrency/model/ChainableTask.java | 0 .../main/java/cz/zcu/kiv/crce/concurrency/model/Task.java | 0 .../java/cz/zcu/kiv/crce/concurrency/model/TaskState.java | 0 .../kiv/crce/concurrency/service/TaskRunnerService.java | 0 .../service/internal/TaskRunnerServiceImpl.java | 0 .../src/main/resources/OSGi-INF/service.xml | 0 .../zcu/kiv/crce/concurrency/internal/TaskRunnerTest.java | 0 core/pom.xml | 2 ++ modules/pom.xml | 1 - 13 files changed, 6 insertions(+), 5 deletions(-) rename {modules => core}/crce-concurrency/osgi.bnd (100%) rename {modules => core}/crce-concurrency/pom.xml (82%) rename {modules => core}/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/internal/Activator.java (100%) rename {modules => core}/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/internal/TaskRunner.java (100%) rename {modules => core}/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/ChainableTask.java (100%) rename {modules => core}/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/Task.java (100%) rename {modules => core}/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/TaskState.java (100%) rename {modules => core}/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/service/TaskRunnerService.java (100%) rename {modules => core}/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/service/internal/TaskRunnerServiceImpl.java (100%) rename {modules => core}/crce-concurrency/src/main/resources/OSGi-INF/service.xml (100%) rename {modules => core}/crce-concurrency/src/test/java/cz/zcu/kiv/crce/concurrency/internal/TaskRunnerTest.java (100%) diff --git a/modules/crce-concurrency/osgi.bnd b/core/crce-concurrency/osgi.bnd similarity index 100% rename from modules/crce-concurrency/osgi.bnd rename to core/crce-concurrency/osgi.bnd diff --git a/modules/crce-concurrency/pom.xml b/core/crce-concurrency/pom.xml similarity index 82% rename from modules/crce-concurrency/pom.xml rename to core/crce-concurrency/pom.xml index 48c4f427..0da7bebd 100644 --- a/modules/crce-concurrency/pom.xml +++ b/core/crce-concurrency/pom.xml @@ -4,10 +4,10 @@ 4.0.0 - ../pom - cz.zcu.kiv.crce - crce-modules-parent - 2.1.1-SNAPSHOT + cz.zcu.kiv.crce + compiled-bundle-settings + 2.1.2-SNAPSHOT + crce-concurrency diff --git a/modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/internal/Activator.java b/core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/internal/Activator.java similarity index 100% rename from modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/internal/Activator.java rename to core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/internal/Activator.java diff --git a/modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/internal/TaskRunner.java b/core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/internal/TaskRunner.java similarity index 100% rename from modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/internal/TaskRunner.java rename to core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/internal/TaskRunner.java diff --git a/modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/ChainableTask.java b/core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/ChainableTask.java similarity index 100% rename from modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/ChainableTask.java rename to core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/ChainableTask.java diff --git a/modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/Task.java b/core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/Task.java similarity index 100% rename from modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/Task.java rename to core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/Task.java diff --git a/modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/TaskState.java b/core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/TaskState.java similarity index 100% rename from modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/TaskState.java rename to core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/model/TaskState.java diff --git a/modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/service/TaskRunnerService.java b/core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/service/TaskRunnerService.java similarity index 100% rename from modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/service/TaskRunnerService.java rename to core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/service/TaskRunnerService.java diff --git a/modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/service/internal/TaskRunnerServiceImpl.java b/core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/service/internal/TaskRunnerServiceImpl.java similarity index 100% rename from modules/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/service/internal/TaskRunnerServiceImpl.java rename to core/crce-concurrency/src/main/java/cz/zcu/kiv/crce/concurrency/service/internal/TaskRunnerServiceImpl.java diff --git a/modules/crce-concurrency/src/main/resources/OSGi-INF/service.xml b/core/crce-concurrency/src/main/resources/OSGi-INF/service.xml similarity index 100% rename from modules/crce-concurrency/src/main/resources/OSGi-INF/service.xml rename to core/crce-concurrency/src/main/resources/OSGi-INF/service.xml diff --git a/modules/crce-concurrency/src/test/java/cz/zcu/kiv/crce/concurrency/internal/TaskRunnerTest.java b/core/crce-concurrency/src/test/java/cz/zcu/kiv/crce/concurrency/internal/TaskRunnerTest.java similarity index 100% rename from modules/crce-concurrency/src/test/java/cz/zcu/kiv/crce/concurrency/internal/TaskRunnerTest.java rename to core/crce-concurrency/src/test/java/cz/zcu/kiv/crce/concurrency/internal/TaskRunnerTest.java diff --git a/core/pom.xml b/core/pom.xml index 3963545d..539732d6 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -29,6 +29,8 @@ crce-repository-impl crce-resolver-impl + crce-concurrency + crce-core diff --git a/modules/pom.xml b/modules/pom.xml index 9dd10c95..53c4d148 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -79,7 +79,6 @@ crce-compatibility-api crce-compatibility-dao-api crce-compatibility-dao-mongodb - crce-concurrency crce-vo From 243f5d03cf326e2effbd3ddaf49c16d01814a3cf Mon Sep 17 00:00:00 2001 From: Radek Vais Date: Mon, 3 Dec 2018 19:53:56 +0100 Subject: [PATCH 39/85] Cajova-Houba/crce#7 move provision to /provision --- modules/crce-default-modules/pom.xml | 85 ++++++++++++ modules/pom.xml | 5 +- provision/pom.xml | 158 +++++++++++++++++++++++ {modules => provision}/provision/pom.xml | 13 +- 4 files changed, 255 insertions(+), 6 deletions(-) create mode 100644 modules/crce-default-modules/pom.xml create mode 100644 provision/pom.xml rename {modules => provision}/provision/pom.xml (95%) diff --git a/modules/crce-default-modules/pom.xml b/modules/crce-default-modules/pom.xml new file mode 100644 index 00000000..8928538b --- /dev/null +++ b/modules/crce-default-modules/pom.xml @@ -0,0 +1,85 @@ + + + + 4.0.0 + + + cz.zcu.kiv.crce + crce-parent + 2.1.1-SNAPSHOT + + + + crce-default-modules + 2.1.1-SNAPSHOT + pom + + CRCE - Default modules + + + https://github.com/ReliSA/crce/tree/master/core/crce-core + https://github.com/ReliSA/crce.git + scm:git:git@github.com:ReliSA/crce.git + HEAD + + + + + ${project.groupId} + crce-metadata-osgi-bundle + 2.1.1-SNAPSHOT + + + ${project.groupId} + crce-webui + 2.1.1-SNAPSHOT + war + + + ${project.groupId} + crce-rest-v2 + 2.1.1-SNAPSHOT + war + + + ${project.groupId} + crce-compatibility-api + 2.1.1-SNAPSHOT + + + ${project.groupId} + crce-compatibility-dao-api + 2.1.1-SNAPSHOT + + + ${project.groupId} + crce-compatibility-dao-mongodb + 2.1.1-SNAPSHOT + + + ${project.groupId} + crce-vo + 2.1.1-SNAPSHOT + + + ${project.groupId} + crce-webservices-indexer + 2.1.1-SNAPSHOT + + + + + + + relisa-global + ReliSA Global Proxy repository + http://relisa-dev.kiv.zcu.cz:8081/nexus/content/groups/public + + + maven.kalwi.eu.releases + kalwi.eu releases repository + http://maven.kalwi.eu/repo/releases + + + + diff --git a/modules/pom.xml b/modules/pom.xml index 53c4d148..2a8327a5 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -57,8 +57,7 @@ pom - provision - + crce-metadata-osgi-bundle @@ -84,6 +83,8 @@ crce-webservices-indexer + + crce-default-modules diff --git a/provision/pom.xml b/provision/pom.xml new file mode 100644 index 00000000..25c538a3 --- /dev/null +++ b/provision/pom.xml @@ -0,0 +1,158 @@ + + + + 4.0.0 + + + pom + cz.zcu.kiv.crce + shared-build-settings + 2.1.2-SNAPSHOT + + + provision-reactor + 2.1.2-SNAPSHOT + + CRCE - Provision - Reactor + + pom + + + 8080 + 8443 + false + UTF-8 + false + 2000 + ../conf + .*\\.cfg + ../conf/logback.xml + + javax.inject,javax.jmdns,javax.jms,javax.mail,javax.mail.internet,javax.microedition.io + + + sun.*,com.sun.* + + + + 1.7.7 + 1.1.2 + + + + https://github.com/ReliSA/crce/tree/master/build + https://github.com/ReliSA/crce.git + scm:git:git@github.com:ReliSA/crce.git + HEAD + + + + provision + + + + + + + + + ${project.groupId} + crce-core + 3.0.0-SNAPSHOT + pom + + + + ${project.groupId} + crce-default-modules + 2.1.1-SNAPSHOT + pom + + + + + + javax.ws.rs + javax.ws.rs-api + 2.0 + + + org.glassfish.jersey.containers + jersey-container-servlet-core + 2.9.1 + + + org.glassfish.jersey.media + jersey-media-multipart + 2.9.1 + + + org.glassfish.jersey.media + jersey-media-json-jackson + 2.9.1 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${version.com.fasterxml.jackson} + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + ${version.com.fasterxml.jackson} + + + + + + + + + org.ops4j + maven-pax-plugin + + + --vmOptions=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=65505 + + --platform=felix + + --repositories=http://uk.maven.org/maven2,http://relisa-dev.kiv.zcu.cz:8081/nexus/content/groups/public,http://repository.ops4j.org/maven2 + + + mvn:org.slf4j/slf4j-api/${version.org.slf4j}@1 + mvn:org.slf4j/osgi-over-slf4j/${version.org.slf4j}@1 + mvn:org.slf4j/log4j-over-slf4j/${version.org.slf4j}@1 + mvn:org.slf4j/jcl-over-slf4j/${version.org.slf4j}@1 + mvn:org.slf4j/jul-to-slf4j/${version.org.slf4j}@1 + mvn:ch.qos.logback/logback-core/${version.logback}@1 + mvn:ch.qos.logback/logback-classic/${version.logback}@1 + + + + + + + + + + relisa-global + ReliSA Global Proxy repository + http://relisa-dev.kiv.zcu.cz:8081/nexus/content/groups/public + + + maven.kalwi.eu.releases + kalwi.eu releases repository + http://maven.kalwi.eu/repo/releases + + + tmatesoft + https://maven.tmatesoft.com/content/repositories/releases/ + + + + diff --git a/modules/provision/pom.xml b/provision/provision/pom.xml similarity index 95% rename from modules/provision/pom.xml rename to provision/provision/pom.xml index ba2cb3b1..ea6ea58d 100644 --- a/modules/provision/pom.xml +++ b/provision/provision/pom.xml @@ -4,10 +4,9 @@ 4.0.0 - ../pom - cz.zcu.kiv.crce - crce-modules-parent - 2.1.1-SNAPSHOT + cz.zcu.kiv.crce + provision-reactor + 2.1.2-SNAPSHOT provision @@ -172,6 +171,12 @@ cz.zcu.kiv.crce crce-core pom + + + + cz.zcu.kiv.crce + crce-default-modules + pom From a3b9f6fa98d5bdccb24ac0b692f45b1982db5f39 Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Mon, 3 Dec 2018 20:19:28 +0100 Subject: [PATCH 40/85] #3: Added dockerfile for building CRCE image. --- docker-dev/Dockerfile | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docker-dev/Dockerfile diff --git a/docker-dev/Dockerfile b/docker-dev/Dockerfile new file mode 100644 index 00000000..c39a9bbd --- /dev/null +++ b/docker-dev/Dockerfile @@ -0,0 +1,19 @@ +# Use java 7 jdk which is compatible with CRCE +FROM java:7-jdk + +# Prepare environment +RUN mkdir /felix +WORKDIR /felix + +# Download and upack Felix +# 4.6.1 is compatible with Java 1.7 +ADD https://archive.apache.org/dist/felix/org.apache.felix.main.distribution-4.6.1.tar.gz ./apache-felix.tar.gz +RUN tar xvfz apache-felix.tar.gz && rm apache-felix.tar.gz +RUN cd felix-framework-4.6.1 +RUN FELIX_PATH=$(pwd) + +# Add CRCE modules to Felix autodeploy dir +ADD ../modules/runner/bundles/* ./bundle/ + +# Run Felix +CMD cd ${FELIX_PATH} && java -jar ./bin/felix.jar \ No newline at end of file From 19da360106a5d7267eb6cc7bf3d86e6df71c4c78 Mon Sep 17 00:00:00 2001 From: Radek Vais Date: Wed, 5 Dec 2018 09:27:24 +0100 Subject: [PATCH 41/85] Cajova-Houba/crce#7 move felix configuration to provision --- modules/crce-default-modules/pom.xml | 5 +- modules/pom.xml | 5 - provision/.gitignore | 6 + .../conf.default/cz.zcu.kiv.crce.metadata.cfg | 22 ++-- .../cz.zcu.kiv.crce.metadata.dao.cfg | 12 +- .../cz.zcu.kiv.crce.metadata.json.cfg | 30 ++--- ...cu.kiv.crce.repository.filebased-store.cfg | 16 +-- ...cz.zcu.kiv.crce.repository.maven-local.cfg | 0 .../conf.default/logback.xml | 106 +++++++++--------- .../org.apache.ace.obr.servlet.cfg | 4 +- .../org.apache.ace.obr.storage.file.cfg | 4 +- .../org.apache.felix.fileinstall-deploy.cfg | 12 +- ...ebconsole.internal.servlet.OsgiManager.cfg | 6 +- provision/pom.xml | 12 +- 14 files changed, 122 insertions(+), 118 deletions(-) create mode 100644 provision/.gitignore rename {modules => provision}/conf.default/cz.zcu.kiv.crce.metadata.cfg (97%) rename {modules => provision}/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg (96%) rename {modules => provision}/conf.default/cz.zcu.kiv.crce.metadata.json.cfg (97%) rename {modules => provision}/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg (95%) rename {modules => provision}/conf.default/cz.zcu.kiv.crce.repository.maven-local.cfg (100%) rename {modules => provision}/conf.default/logback.xml (96%) rename {modules => provision}/conf.default/org.apache.ace.obr.servlet.cfg (97%) rename {modules => provision}/conf.default/org.apache.ace.obr.storage.file.cfg (96%) rename {modules => provision}/conf.default/org.apache.felix.fileinstall-deploy.cfg (96%) rename {modules => provision}/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg (95%) diff --git a/modules/crce-default-modules/pom.xml b/modules/crce-default-modules/pom.xml index 8928538b..6219b5e7 100644 --- a/modules/crce-default-modules/pom.xml +++ b/modules/crce-default-modules/pom.xml @@ -4,10 +4,10 @@ 4.0.0 + crce-modules-parent cz.zcu.kiv.crce - crce-parent 2.1.1-SNAPSHOT - + ../pom crce-default-modules @@ -60,6 +60,7 @@ ${project.groupId} crce-vo 2.1.1-SNAPSHOT + pom ${project.groupId} diff --git a/modules/pom.xml b/modules/pom.xml index 2a8327a5..ae4c2446 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -33,11 +33,6 @@ 8443 false UTF-8 - false - 2000 - ../conf - .*\\.cfg - ../conf/logback.xml javax.inject,javax.jmdns,javax.jms,javax.mail,javax.mail.internet,javax.microedition.io diff --git a/provision/.gitignore b/provision/.gitignore new file mode 100644 index 00000000..bbbe5f9a --- /dev/null +++ b/provision/.gitignore @@ -0,0 +1,6 @@ +#ignore local configuration +/conf/ + +#ignore pax generated runner files +/runner/ + diff --git a/modules/conf.default/cz.zcu.kiv.crce.metadata.cfg b/provision/conf.default/cz.zcu.kiv.crce.metadata.cfg similarity index 97% rename from modules/conf.default/cz.zcu.kiv.crce.metadata.cfg rename to provision/conf.default/cz.zcu.kiv.crce.metadata.cfg index 6e3a357b..7d3a04ac 100644 --- a/modules/conf.default/cz.zcu.kiv.crce.metadata.cfg +++ b/provision/conf.default/cz.zcu.kiv.crce.metadata.cfg @@ -1,11 +1,11 @@ -# Specifies whether JSON serializer should be used in toString method -# of metadata entities to produce a string representation of the entity. -# Possible values: true (default) / false -json-to-string.enabled=true - -# The same as 'json.pretty-print' but for toString case -# when json-to-string.enabled is true. -# Possible values: -# true - with line breaks and indentation (better to read), -# false (default) - without line breaks and indentation (less space). -json-to-string.pretty-print=false +# Specifies whether JSON serializer should be used in toString method +# of metadata entities to produce a string representation of the entity. +# Possible values: true (default) / false +json-to-string.enabled=true + +# The same as 'json.pretty-print' but for toString case +# when json-to-string.enabled is true. +# Possible values: +# true - with line breaks and indentation (better to read), +# false (default) - without line breaks and indentation (less space). +json-to-string.pretty-print=false diff --git a/modules/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg b/provision/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg similarity index 96% rename from modules/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg rename to provision/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg index 17d02f2b..2da1d2f1 100644 --- a/modules/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg +++ b/provision/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg @@ -1,6 +1,6 @@ -jdbc.driver=org.h2.Driver -jdbc.url=jdbc:h2:file:metadata/crce;MODE=PostgreSQL;AUTO_SERVER=TRUE;AUTO_SERVER_PORT=9090 -jdbc.username=sa -jdbc.password= - -mybatis.config= +jdbc.driver=org.h2.Driver +jdbc.url=jdbc:h2:file:metadata/crce;MODE=PostgreSQL;AUTO_SERVER=TRUE;AUTO_SERVER_PORT=9090 +jdbc.username=sa +jdbc.password= + +mybatis.config= diff --git a/modules/conf.default/cz.zcu.kiv.crce.metadata.json.cfg b/provision/conf.default/cz.zcu.kiv.crce.metadata.json.cfg similarity index 97% rename from modules/conf.default/cz.zcu.kiv.crce.metadata.json.cfg rename to provision/conf.default/cz.zcu.kiv.crce.metadata.json.cfg index 94abde0f..4f11605e 100644 --- a/modules/conf.default/cz.zcu.kiv.crce.metadata.json.cfg +++ b/provision/conf.default/cz.zcu.kiv.crce.metadata.json.cfg @@ -1,15 +1,15 @@ -# Specifies whether JSON serializer should produce -# JSON data with or without line breaks and indentation. -# Possible values: -# true - with line breaks and indentation (better to read), -# false (default) - without line breaks and indentation (less space). -json.pretty-print=true - -# Expand values of complex attribute types (List, Version) to JSON object, for example: -# "value" : {"major" : 2, "minor" : 1, "micro" : 0} -# If disabled, then values will be serialized in simple string form, for exmple: -# "value" : "2.1.0" -# Possible values: -# true - enabled, -# false - disabled. -json.expand-attribute-values=false +# Specifies whether JSON serializer should produce +# JSON data with or without line breaks and indentation. +# Possible values: +# true - with line breaks and indentation (better to read), +# false (default) - without line breaks and indentation (less space). +json.pretty-print=true + +# Expand values of complex attribute types (List, Version) to JSON object, for example: +# "value" : {"major" : 2, "minor" : 1, "micro" : 0} +# If disabled, then values will be serialized in simple string form, for exmple: +# "value" : "2.1.0" +# Possible values: +# true - enabled, +# false - disabled. +json.expand-attribute-values=false diff --git a/modules/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg b/provision/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg similarity index 95% rename from modules/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg rename to provision/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg index c8acce87..ad079ec2 100644 --- a/modules/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg +++ b/provision/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg @@ -1,8 +1,8 @@ -# URI of repository's central store or absolute/relative file path -# -# Examples: -# store.uri=file:/C:/store -# store.uri=C:\\store -# store.uri=store - -store.uri=store +# URI of repository's central store or absolute/relative file path +# +# Examples: +# store.uri=file:/C:/store +# store.uri=C:\\store +# store.uri=store + +store.uri=store diff --git a/modules/conf.default/cz.zcu.kiv.crce.repository.maven-local.cfg b/provision/conf.default/cz.zcu.kiv.crce.repository.maven-local.cfg similarity index 100% rename from modules/conf.default/cz.zcu.kiv.crce.repository.maven-local.cfg rename to provision/conf.default/cz.zcu.kiv.crce.repository.maven-local.cfg diff --git a/modules/conf.default/logback.xml b/provision/conf.default/logback.xml similarity index 96% rename from modules/conf.default/logback.xml rename to provision/conf.default/logback.xml index 5a2649b5..36fe585b 100644 --- a/modules/conf.default/logback.xml +++ b/provision/conf.default/logback.xml @@ -1,53 +1,53 @@ - - - - - - - - %d{YYYY-MM-dd HH:mm:ss.SSS} %-5level {%thread} [%logger{36}] %msg%n - - - - - logs/crce-debug.log - - %d{YYYY-MM-dd HH:mm:ss.SSS} %-5level {%thread} [%logger{36}] %msg%n - - - - - logs/crce.log - - INFO - - - %d{YYYY-MM-dd HH:mm:ss.SSS} %-5level {%thread} [%logger{36}] %msg%n - - - - - logs/crce-error.log - - ERROR - - - %d{YYYY-MM-dd HH:mm:ss.SSS} %-5level {%thread} [%logger{36}] %msg%n - - - - - - - - - - - - - - - - - + + + + + + + + %d{YYYY-MM-dd HH:mm:ss.SSS} %-5level {%thread} [%logger{36}] %msg%n + + + + + logs/crce-debug.log + + %d{YYYY-MM-dd HH:mm:ss.SSS} %-5level {%thread} [%logger{36}] %msg%n + + + + + logs/crce.log + + INFO + + + %d{YYYY-MM-dd HH:mm:ss.SSS} %-5level {%thread} [%logger{36}] %msg%n + + + + + logs/crce-error.log + + ERROR + + + %d{YYYY-MM-dd HH:mm:ss.SSS} %-5level {%thread} [%logger{36}] %msg%n + + + + + + + + + + + + + + + + + diff --git a/modules/conf.default/org.apache.ace.obr.servlet.cfg b/provision/conf.default/org.apache.ace.obr.servlet.cfg similarity index 97% rename from modules/conf.default/org.apache.ace.obr.servlet.cfg rename to provision/conf.default/org.apache.ace.obr.servlet.cfg index d5c872bb..da3e9f5b 100644 --- a/modules/conf.default/org.apache.ace.obr.servlet.cfg +++ b/provision/conf.default/org.apache.ace.obr.servlet.cfg @@ -1,2 +1,2 @@ -# mapping of ACE OBR servlet -org.apache.ace.server.servlet.endpoint=/obr +# mapping of ACE OBR servlet +org.apache.ace.server.servlet.endpoint=/obr diff --git a/modules/conf.default/org.apache.ace.obr.storage.file.cfg b/provision/conf.default/org.apache.ace.obr.storage.file.cfg similarity index 96% rename from modules/conf.default/org.apache.ace.obr.storage.file.cfg rename to provision/conf.default/org.apache.ace.obr.storage.file.cfg index 4f4be5cc..3d33beaa 100644 --- a/modules/conf.default/org.apache.ace.obr.storage.file.cfg +++ b/provision/conf.default/org.apache.ace.obr.storage.file.cfg @@ -1,2 +1,2 @@ -# path to ACE OBR Storage dir -fileLocation=store +# path to ACE OBR Storage dir +fileLocation=store diff --git a/modules/conf.default/org.apache.felix.fileinstall-deploy.cfg b/provision/conf.default/org.apache.felix.fileinstall-deploy.cfg similarity index 96% rename from modules/conf.default/org.apache.felix.fileinstall-deploy.cfg rename to provision/conf.default/org.apache.felix.fileinstall-deploy.cfg index d4485deb..73c880f4 100644 --- a/modules/conf.default/org.apache.felix.fileinstall-deploy.cfg +++ b/provision/conf.default/org.apache.felix.fileinstall-deploy.cfg @@ -1,6 +1,6 @@ -felix.fileinstall.dir=deploy -felix.fileinstall.poll=5000 - -#felix.fileinstall.debug=-1 -#felix.fileinstall.filter=.*\\.cfg -#felix.fileinstall.bundles.new.start=false +felix.fileinstall.dir=deploy +felix.fileinstall.poll=5000 + +#felix.fileinstall.debug=-1 +#felix.fileinstall.filter=.*\\.cfg +#felix.fileinstall.bundles.new.start=false diff --git a/modules/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg b/provision/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg similarity index 95% rename from modules/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg rename to provision/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg index 1ef7eef7..e045469e 100644 --- a/modules/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg +++ b/provision/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg @@ -1,3 +1,3 @@ -# Felix Webconsole configuration -username=admin -password=admin +# Felix Webconsole configuration +username=admin +password=admin diff --git a/provision/pom.xml b/provision/pom.xml index 25c538a3..6d65d2c2 100644 --- a/provision/pom.xml +++ b/provision/pom.xml @@ -18,21 +18,23 @@ pom - 8080 - 8443 - false - UTF-8 - false 2000 ../conf .*\\.cfg ../conf/logback.xml + + + 8080 + 8443 + false + UTF-8 javax.inject,javax.jmdns,javax.jms,javax.mail,javax.mail.internet,javax.microedition.io sun.*,com.sun.* + From ff2f063da3e1b98331acc72d9c6128e96016b038 Mon Sep 17 00:00:00 2001 From: Radek Vais Date: Wed, 5 Dec 2018 14:48:46 +0100 Subject: [PATCH 43/85] Cajova-Houba/crce#7 rename root folder provision to deploy --- {provision => deploy}/.gitignore | 0 {provision => deploy}/conf.default/cz.zcu.kiv.crce.metadata.cfg | 0 .../conf.default/cz.zcu.kiv.crce.metadata.dao.cfg | 0 .../conf.default/cz.zcu.kiv.crce.metadata.json.cfg | 0 .../conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg | 0 .../conf.default/cz.zcu.kiv.crce.repository.maven-local.cfg | 0 {provision => deploy}/conf.default/logback.xml | 0 {provision => deploy}/conf.default/org.apache.ace.obr.servlet.cfg | 0 .../conf.default/org.apache.ace.obr.storage.file.cfg | 0 .../conf.default/org.apache.felix.fileinstall-deploy.cfg | 0 .../org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg | 0 {provision => deploy}/pom.xml | 0 {provision => deploy}/provision/pom.xml | 0 13 files changed, 0 insertions(+), 0 deletions(-) rename {provision => deploy}/.gitignore (100%) rename {provision => deploy}/conf.default/cz.zcu.kiv.crce.metadata.cfg (100%) rename {provision => deploy}/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg (100%) rename {provision => deploy}/conf.default/cz.zcu.kiv.crce.metadata.json.cfg (100%) rename {provision => deploy}/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg (100%) rename {provision => deploy}/conf.default/cz.zcu.kiv.crce.repository.maven-local.cfg (100%) rename {provision => deploy}/conf.default/logback.xml (100%) rename {provision => deploy}/conf.default/org.apache.ace.obr.servlet.cfg (100%) rename {provision => deploy}/conf.default/org.apache.ace.obr.storage.file.cfg (100%) rename {provision => deploy}/conf.default/org.apache.felix.fileinstall-deploy.cfg (100%) rename {provision => deploy}/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg (100%) rename {provision => deploy}/pom.xml (100%) rename {provision => deploy}/provision/pom.xml (100%) diff --git a/provision/.gitignore b/deploy/.gitignore similarity index 100% rename from provision/.gitignore rename to deploy/.gitignore diff --git a/provision/conf.default/cz.zcu.kiv.crce.metadata.cfg b/deploy/conf.default/cz.zcu.kiv.crce.metadata.cfg similarity index 100% rename from provision/conf.default/cz.zcu.kiv.crce.metadata.cfg rename to deploy/conf.default/cz.zcu.kiv.crce.metadata.cfg diff --git a/provision/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg b/deploy/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg similarity index 100% rename from provision/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg rename to deploy/conf.default/cz.zcu.kiv.crce.metadata.dao.cfg diff --git a/provision/conf.default/cz.zcu.kiv.crce.metadata.json.cfg b/deploy/conf.default/cz.zcu.kiv.crce.metadata.json.cfg similarity index 100% rename from provision/conf.default/cz.zcu.kiv.crce.metadata.json.cfg rename to deploy/conf.default/cz.zcu.kiv.crce.metadata.json.cfg diff --git a/provision/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg b/deploy/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg similarity index 100% rename from provision/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg rename to deploy/conf.default/cz.zcu.kiv.crce.repository.filebased-store.cfg diff --git a/provision/conf.default/cz.zcu.kiv.crce.repository.maven-local.cfg b/deploy/conf.default/cz.zcu.kiv.crce.repository.maven-local.cfg similarity index 100% rename from provision/conf.default/cz.zcu.kiv.crce.repository.maven-local.cfg rename to deploy/conf.default/cz.zcu.kiv.crce.repository.maven-local.cfg diff --git a/provision/conf.default/logback.xml b/deploy/conf.default/logback.xml similarity index 100% rename from provision/conf.default/logback.xml rename to deploy/conf.default/logback.xml diff --git a/provision/conf.default/org.apache.ace.obr.servlet.cfg b/deploy/conf.default/org.apache.ace.obr.servlet.cfg similarity index 100% rename from provision/conf.default/org.apache.ace.obr.servlet.cfg rename to deploy/conf.default/org.apache.ace.obr.servlet.cfg diff --git a/provision/conf.default/org.apache.ace.obr.storage.file.cfg b/deploy/conf.default/org.apache.ace.obr.storage.file.cfg similarity index 100% rename from provision/conf.default/org.apache.ace.obr.storage.file.cfg rename to deploy/conf.default/org.apache.ace.obr.storage.file.cfg diff --git a/provision/conf.default/org.apache.felix.fileinstall-deploy.cfg b/deploy/conf.default/org.apache.felix.fileinstall-deploy.cfg similarity index 100% rename from provision/conf.default/org.apache.felix.fileinstall-deploy.cfg rename to deploy/conf.default/org.apache.felix.fileinstall-deploy.cfg diff --git a/provision/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg b/deploy/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg similarity index 100% rename from provision/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg rename to deploy/conf.default/org.apache.felix.webconsole.internal.servlet.OsgiManager.cfg diff --git a/provision/pom.xml b/deploy/pom.xml similarity index 100% rename from provision/pom.xml rename to deploy/pom.xml diff --git a/provision/provision/pom.xml b/deploy/provision/pom.xml similarity index 100% rename from provision/provision/pom.xml rename to deploy/provision/pom.xml From 942a6acfb90dd7c5b80d7d2fc4c8e13ccd129095 Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Sun, 9 Dec 2018 18:17:58 +0100 Subject: [PATCH 44/85] EA model update. --- crce.eap | Bin 1804288 -> 1804288 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/crce.eap b/crce.eap index c24941a24ba62d7c3cb79b3dd7bad33d2f7b18c4..12446a776d8d6dfe5b62a5ee95110b43d5dc3651 100644 GIT binary patch delta 144 zcmWm5w+(|p06QCK-pEm)Jd~`u F;R0eBGxq=h delta 142 zcmWm5u@QnW06@_rKnM_s5fv2*D#xR? Date: Sun, 9 Dec 2018 22:05:45 +0100 Subject: [PATCH 45/85] #3: Dockerfile updated and moved from docker-dev because direct building does not support adding files from parent directories (../something). --- docker-dev/Dockerfile => Dockerfile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) rename docker-dev/Dockerfile => Dockerfile (73%) diff --git a/docker-dev/Dockerfile b/Dockerfile similarity index 73% rename from docker-dev/Dockerfile rename to Dockerfile index c39a9bbd..a80de102 100644 --- a/docker-dev/Dockerfile +++ b/Dockerfile @@ -9,11 +9,10 @@ WORKDIR /felix # 4.6.1 is compatible with Java 1.7 ADD https://archive.apache.org/dist/felix/org.apache.felix.main.distribution-4.6.1.tar.gz ./apache-felix.tar.gz RUN tar xvfz apache-felix.tar.gz && rm apache-felix.tar.gz -RUN cd felix-framework-4.6.1 -RUN FELIX_PATH=$(pwd) +ENV FELIX_PATH /felix/felix-framework-4.6.1 # Add CRCE modules to Felix autodeploy dir -ADD ../modules/runner/bundles/* ./bundle/ +ADD ./deploy/runner/bundles/* ${FELIX_PATH}/bundle/ # Run Felix -CMD cd ${FELIX_PATH} && java -jar ./bin/felix.jar \ No newline at end of file +CMD cd ${FELIX_PATH} && java -jar ./bin/felix.jar From 120586aee8ba9849900987aa87b429a48489230b Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Mon, 10 Dec 2018 17:43:45 +0100 Subject: [PATCH 46/85] #8: EA model updated. getIndexedAttributes() method added to ResourceIndexer. --- .../indexer/AbstractResourceIndexer.java | 5 +- .../metadata/indexer/ResourceIndexer.java | 19 +++-- crce.eap | Bin 1804288 -> 1804288 bytes .../internal/OsgiManifestBundleIndexer.java | 4 + .../crce/metadata/osgi/namespace/NsMap.java | 70 ++++++++++++++++++ 5 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/namespace/NsMap.java diff --git a/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java b/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java index 843e74d3..dfd50e3c 100644 --- a/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java +++ b/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java @@ -1,10 +1,10 @@ package cz.zcu.kiv.crce.metadata.indexer; +import cz.zcu.kiv.crce.plugin.AbstractPlugin; + import java.util.Collections; import java.util.List; -import cz.zcu.kiv.crce.plugin.AbstractPlugin; - /** * Abstract implementation of ResourceIndexer which can be extended * by other implementations. @@ -31,4 +31,5 @@ public List getPluginKeywords() { public String getPluginDescription() { return "ResourceIndexer plugin implementation"; } + } diff --git a/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/ResourceIndexer.java b/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/ResourceIndexer.java index 5e1b251f..f1369ecf 100644 --- a/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/ResourceIndexer.java +++ b/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/ResourceIndexer.java @@ -1,13 +1,14 @@ package cz.zcu.kiv.crce.metadata.indexer; -import java.io.InputStream; -import java.util.List; - -import javax.annotation.ParametersAreNonnullByDefault; - +import cz.zcu.kiv.crce.metadata.AttributeType; import cz.zcu.kiv.crce.metadata.Resource; import cz.zcu.kiv.crce.plugin.Plugin; +import javax.annotation.ParametersAreNonnullByDefault; +import java.io.InputStream; +import java.util.List; +import java.util.Map; + /** * Resource indexer indexes content of an artifact and stores obtained metadata * into Resource object. @@ -56,4 +57,12 @@ public interface ResourceIndexer extends Plugin { * @return */ List getRequiredCategories(); + + /** + * Returns a map of namespaces and relevant attributes this components indexes. + * + * @return Collection of attributes this component is capable of indexing. Each collection + * is mapped to its respective namespace. + */ + Map> getIndexedAttributes(); } diff --git a/crce.eap b/crce.eap index 12446a776d8d6dfe5b62a5ee95110b43d5dc3651..920e2ace4faf9fe65ff626c862e2344e990235f8 100644 GIT binary patch delta 4069 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 getProvidedCategories() { return result; } + public Map> getIndexedAttributes() { + return NsMap.getAttributeMap(); + } + public Resource fillResource(final URL bundleUrl, Resource resource) throws IOException { fillResource(new Headers() { private final Manifest manifest; diff --git a/modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/namespace/NsMap.java b/modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/namespace/NsMap.java new file mode 100644 index 00000000..bfda2074 --- /dev/null +++ b/modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/namespace/NsMap.java @@ -0,0 +1,70 @@ +package cz.zcu.kiv.crce.metadata.osgi.namespace; + +import cz.zcu.kiv.crce.metadata.AttributeType; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Singleton class which holds information about namespaces and attributes + * this indexer is capable of indexing. + */ +public class NsMap implements Serializable { + + /** + * Map of namespace -> indexable attribtues. + */ + private static Map> attributeMap; + + public static Map> getAttributeMap() { + if (attributeMap == null) { + initMap(); + } + + return attributeMap; + } + + private static void initMap() { + attributeMap = new HashMap<>(); + attributeMap.put(NsOsgiBundle.NAMESPACE__OSGI_BUNDLE, Arrays.asList( + (AttributeType)NsOsgiBundle.ATTRIBUTE__MANIFEST_VERSION, + NsOsgiBundle.ATTRIBUTE__PRESENTATION_NAME, + NsOsgiBundle.ATTRIBUTE__SYMBOLIC_NAME, + NsOsgiBundle.ATTRIBUTE__VERSION + )); + + attributeMap.put(NsOsgiExecutionEnvironment.NAMESPACE__OSGI_EXECUTION_ENVIRONMENT, Arrays.asList( + (AttributeType)NsOsgiExecutionEnvironment.ATTRIBUTE__EXECUTION_ENVIRONMENT + )); + + attributeMap.put(NsOsgiFragment.NAMESPACE__OSGI_FRAGMENT, Arrays.asList( + (AttributeType)NsOsgiFragment.ATTRIBUTE__HOST, + NsOsgiFragment.ATTRIBUTE__VERSION + )); + + attributeMap.put(NsOsgiIdentity.NAMESPACE__OSGI_IDENTITY, Arrays.asList( + (AttributeType)NsOsgiIdentity.ATTRIBUTE__CATEGORY, + NsOsgiIdentity.ATTRIBUTE__COPYRIGHT, + NsOsgiIdentity.ATTRIBUTE__DESCRIPTION, + NsOsgiIdentity.ATTRIBUTE__DOCUMENTATION_URI, + NsOsgiIdentity.ATTRIBUTE__LICENSES, + NsOsgiIdentity.ATTRIBUTE__NAME, + NsOsgiIdentity.ATTRIBUTE__PRESENTATION_NAME, + NsOsgiIdentity.ATTRIBUTE__SOURCE_URI, + NsOsgiIdentity.ATTRIBUTE__SYMBOLIC_NAME, + NsOsgiIdentity.ATTRIBUTE__VERSION + )); + + attributeMap.put(NsOsgiPackage.NAMESPACE__OSGI_PACKAGE, Arrays.asList( + (AttributeType)NsOsgiPackage.ATTRIBUTE__NAME, + NsOsgiPackage.ATTRIBUTE__VERSION + )); + + attributeMap.put(NsOsgiService.NAMESPACE__OSGI_SERVICE, Arrays.asList( + (AttributeType)NsOsgiService.ATTRIBUTE__NAME + )); + } +} From 08f5320fedb781aaccc9571df3c39f3f3059fe40 Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Wed, 12 Dec 2018 11:42:46 +0100 Subject: [PATCH 47/85] #8: Added default implementation of getIndexedAttributes() to AbstractResourceIndexer. --- .../crce/metadata/indexer/AbstractResourceIndexer.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java b/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java index dfd50e3c..6f512f0c 100644 --- a/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java +++ b/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java @@ -1,9 +1,13 @@ package cz.zcu.kiv.crce.metadata.indexer; +import cz.zcu.kiv.crce.metadata.AttributeType; +import cz.zcu.kiv.crce.metadata.Resource; import cz.zcu.kiv.crce.plugin.AbstractPlugin; +import java.io.InputStream; import java.util.Collections; import java.util.List; +import java.util.Map; /** * Abstract implementation of ResourceIndexer which can be extended @@ -32,4 +36,8 @@ public String getPluginDescription() { return "ResourceIndexer plugin implementation"; } + @Override + public Map> getIndexedAttributes() { + return Collections.emptyMap(); + } } From 54a318aa52bc6db0c6da5f5fc3013b97d455bf58 Mon Sep 17 00:00:00 2001 From: Radek Vais Date: Tue, 18 Dec 2018 15:11:51 +0100 Subject: [PATCH 48/85] clean EAP project and move to arch folder --- crce.eap => arch/crce.eap | Bin 1804288 -> 1804288 bytes 1 file changed, 0 insertions(+), 0 deletions(-) rename crce.eap => arch/crce.eap (96%) diff --git a/crce.eap b/arch/crce.eap similarity index 96% rename from crce.eap rename to arch/crce.eap index 920e2ace4faf9fe65ff626c862e2344e990235f8..c34892879350694774ef2c0e2346f19c8465f9ce 100644 GIT binary patch delta 10704 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 Q!UUpZ0+OZF_?yE21IU3Rh5!Hn delta 7342 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 From a0de0fe8d3f17d421fa205302e654c92c32affe3 Mon Sep 17 00:00:00 2001 From: Radek Vais Date: Tue, 18 Dec 2018 19:18:54 +0100 Subject: [PATCH 49/85] Cajova-Houba#4 - move crce-compatibility-api to core --- .../crce-compatibility-api/osgi.bnd | 10 +++++----- .../crce-compatibility-api/pom.xml | 13 ++++++------- .../kiv/crce/compatibility/Compatibility.java | 0 .../compatibility/CompatibilityFactory.java | 0 .../CompatibilityVersionComparator.java | 0 .../cz/zcu/kiv/crce/compatibility/Contract.java | 0 .../cz/zcu/kiv/crce/compatibility/Diff.java | 0 .../zcu/kiv/crce/compatibility/Difference.java | 0 .../kiv/crce/compatibility/DifferenceLevel.java | 0 .../kiv/crce/compatibility/DifferenceRole.java | 0 .../impl/DefaultCompatibilityFactoryImpl.java | 0 .../impl/DefaultCompatibilityImpl.java | 0 .../compatibility/impl/DefaultDiffImpl.java | 0 .../namespace/NsCrceCompatibility.java | 0 .../service/CompatibilitySearchService.java | 0 .../service/CompatibilityService.java | 0 .../schema/v1_0_0/compatibility.xsd | 0 .../DefaultCompatibilityImplTest.java | 0 core/crce-core/pom.xml | 5 +++++ core/pom.xml | 5 ++++- modules/crce-compatibility-dao-api/pom.xml | 12 ++++++------ modules/crce-compatibility-dao-mongodb/pom.xml | 11 ++++++----- modules/crce-default-modules/pom.xml | 17 ++++++----------- modules/crce-rest/pom.xml | 5 ----- modules/pom.xml | 3 +-- 25 files changed, 39 insertions(+), 42 deletions(-) rename {modules => core}/crce-compatibility-api/osgi.bnd (97%) rename {modules => core}/crce-compatibility-api/pom.xml (76%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Compatibility.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityFactory.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityVersionComparator.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Contract.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Diff.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Difference.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/DifferenceLevel.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/DifferenceRole.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityFactoryImpl.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityImpl.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultDiffImpl.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/namespace/NsCrceCompatibility.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/service/CompatibilitySearchService.java (100%) rename {modules => core}/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/service/CompatibilityService.java (100%) rename {modules => core}/crce-compatibility-api/src/main/resources/cz/zcu/kiv/crce/compatibility/schema/v1_0_0/compatibility.xsd (100%) rename {modules => core}/crce-compatibility-api/src/test/java/cz.zcu.kiv.crce.compatibility/DefaultCompatibilityImplTest.java (100%) diff --git a/modules/crce-compatibility-api/osgi.bnd b/core/crce-compatibility-api/osgi.bnd similarity index 97% rename from modules/crce-compatibility-api/osgi.bnd rename to core/crce-compatibility-api/osgi.bnd index fb96e5f2..cf6ca00e 100644 --- a/modules/crce-compatibility-api/osgi.bnd +++ b/core/crce-compatibility-api/osgi.bnd @@ -1,5 +1,5 @@ -#----------------------------------------------------------------- -# Use this file to add customized Bnd instructions for the bundle -#----------------------------------------------------------------- - -Private-Package: +#----------------------------------------------------------------- +# Use this file to add customized Bnd instructions for the bundle +#----------------------------------------------------------------- + +Private-Package: diff --git a/modules/crce-compatibility-api/pom.xml b/core/crce-compatibility-api/pom.xml similarity index 76% rename from modules/crce-compatibility-api/pom.xml rename to core/crce-compatibility-api/pom.xml index 58b92917..a5ef525e 100644 --- a/modules/crce-compatibility-api/pom.xml +++ b/core/crce-compatibility-api/pom.xml @@ -4,10 +4,10 @@ 4.0.0 - ../pom cz.zcu.kiv.crce - crce-modules-parent - 2.1.1-SNAPSHOT + compiled-bundle-settings + 2.1.2-SNAPSHOT + crce-compatibility-api @@ -22,13 +22,12 @@ - ${project.groupId} - crce-core - pom + crce-metadata-api + 3.0.1-SNAPSHOT - + \ No newline at end of file diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Compatibility.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Compatibility.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Compatibility.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Compatibility.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityFactory.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityFactory.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityFactory.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityFactory.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityVersionComparator.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityVersionComparator.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityVersionComparator.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/CompatibilityVersionComparator.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Contract.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Contract.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Contract.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Contract.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Diff.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Diff.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Diff.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Diff.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Difference.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Difference.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Difference.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/Difference.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/DifferenceLevel.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/DifferenceLevel.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/DifferenceLevel.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/DifferenceLevel.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/DifferenceRole.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/DifferenceRole.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/DifferenceRole.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/DifferenceRole.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityFactoryImpl.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityFactoryImpl.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityFactoryImpl.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityFactoryImpl.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityImpl.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityImpl.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityImpl.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultCompatibilityImpl.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultDiffImpl.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultDiffImpl.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultDiffImpl.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/impl/DefaultDiffImpl.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/namespace/NsCrceCompatibility.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/namespace/NsCrceCompatibility.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/namespace/NsCrceCompatibility.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/namespace/NsCrceCompatibility.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/service/CompatibilitySearchService.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/service/CompatibilitySearchService.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/service/CompatibilitySearchService.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/service/CompatibilitySearchService.java diff --git a/modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/service/CompatibilityService.java b/core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/service/CompatibilityService.java similarity index 100% rename from modules/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/service/CompatibilityService.java rename to core/crce-compatibility-api/src/main/java/cz/zcu/kiv/crce/compatibility/service/CompatibilityService.java diff --git a/modules/crce-compatibility-api/src/main/resources/cz/zcu/kiv/crce/compatibility/schema/v1_0_0/compatibility.xsd b/core/crce-compatibility-api/src/main/resources/cz/zcu/kiv/crce/compatibility/schema/v1_0_0/compatibility.xsd similarity index 100% rename from modules/crce-compatibility-api/src/main/resources/cz/zcu/kiv/crce/compatibility/schema/v1_0_0/compatibility.xsd rename to core/crce-compatibility-api/src/main/resources/cz/zcu/kiv/crce/compatibility/schema/v1_0_0/compatibility.xsd diff --git a/modules/crce-compatibility-api/src/test/java/cz.zcu.kiv.crce.compatibility/DefaultCompatibilityImplTest.java b/core/crce-compatibility-api/src/test/java/cz.zcu.kiv.crce.compatibility/DefaultCompatibilityImplTest.java similarity index 100% rename from modules/crce-compatibility-api/src/test/java/cz.zcu.kiv.crce.compatibility/DefaultCompatibilityImplTest.java rename to core/crce-compatibility-api/src/test/java/cz.zcu.kiv.crce.compatibility/DefaultCompatibilityImplTest.java diff --git a/core/crce-core/pom.xml b/core/crce-core/pom.xml index 7f0f1bb8..67226ce4 100644 --- a/core/crce-core/pom.xml +++ b/core/crce-core/pom.xml @@ -98,6 +98,11 @@ ${project.groupId} crce-resolver-impl 2.2.0-SNAPSHOT + + + ${project.groupId} + crce-compatibility-api + 2.1.1-SNAPSHOT diff --git a/core/pom.xml b/core/pom.xml index 539732d6..89806c72 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -20,6 +20,7 @@ crce-metadata-service-api crce-repository-api crce-resolver-api + crce-compatibility-api crce-metadata-json-impl crce-metadata-impl @@ -30,8 +31,10 @@ crce-resolver-impl crce-concurrency - + crce-core + + diff --git a/modules/crce-compatibility-dao-api/pom.xml b/modules/crce-compatibility-dao-api/pom.xml index 442780a4..86c9fd2a 100644 --- a/modules/crce-compatibility-dao-api/pom.xml +++ b/modules/crce-compatibility-dao-api/pom.xml @@ -30,12 +30,12 @@ - - - ${project.groupId} - crce-compatibility-api - ${project.version} - + + + + + + diff --git a/modules/crce-compatibility-dao-mongodb/pom.xml b/modules/crce-compatibility-dao-mongodb/pom.xml index 01fae91b..c382fafb 100644 --- a/modules/crce-compatibility-dao-mongodb/pom.xml +++ b/modules/crce-compatibility-dao-mongodb/pom.xml @@ -31,11 +31,12 @@ - - ${project.groupId} - crce-compatibility-api - ${project.version} - + + + + + + ${project.groupId} crce-compatibility-dao-api diff --git a/modules/crce-default-modules/pom.xml b/modules/crce-default-modules/pom.xml index a284d0d3..876e8f61 100644 --- a/modules/crce-default-modules/pom.xml +++ b/modules/crce-default-modules/pom.xml @@ -28,23 +28,12 @@ ${project.groupId} crce-metadata-osgi-bundle 2.1.1-SNAPSHOT - - - ${project.groupId} - crce-webui - 2.1.1-SNAPSHOT - war ${project.groupId} crce-rest-v2 2.1.1-SNAPSHOT war - - - ${project.groupId} - crce-compatibility-api - 2.1.1-SNAPSHOT ${project.groupId} @@ -66,6 +55,12 @@ crce-webservices-indexer 2.1.1-SNAPSHOT + + ${project.groupId} + crce-webui + 2.1.1-SNAPSHOT + war + diff --git a/modules/crce-rest/pom.xml b/modules/crce-rest/pom.xml index 69c9f1e3..d2e80916 100644 --- a/modules/crce-rest/pom.xml +++ b/modules/crce-rest/pom.xml @@ -193,11 +193,6 @@ crce-metadata-osgi-bundle ${project.version} - - cz.zcu.kiv.crce - crce-compatibility-api - ${project.version} - diff --git a/modules/pom.xml b/modules/pom.xml index 0d8f434e..8d63ab37 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -62,9 +62,8 @@ crce-rest-v2 - - crce-compatibility-api + crce-compatibility-dao-api crce-compatibility-dao-mongodb crce-vo From 13915e72cb96df207c151c3e0fa0e77e6d951763 Mon Sep 17 00:00:00 2001 From: Radek Vais Date: Tue, 18 Dec 2018 19:22:26 +0100 Subject: [PATCH 50/85] Cajova-Houba#4 - update EA project move crce-compatibility-api --- arch/crce.eap | Bin 1804288 -> 1804288 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/arch/crce.eap b/arch/crce.eap index c34892879350694774ef2c0e2346f19c8465f9ce..3fb42916edc5910bb6cbb6883b5fa2202c0ea794 100644 GIT binary patch delta 13696 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 delta 8792 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℘siXjmosJD*3#Hp`=E2iMQp zVn`xb&)b%e2zLK@TLE!}X@a;&;~<=a2o7xPl5ooGzc1M2DC0jF$z@v-9nVA6b_Bf< zJY4NS&}(f$%!y!K>}te@An3KNLCl3<-LSQYMIpe^_`k6I+_06$wh>^g`mbNuemV?= zX;Iiq2sD(rMd2J+Uqujc0D-O78XDIXn|N?%kJTgxae?|mq1GYX%~*Pq5d#h1W4Qe`e- z!8aqbLoko92i}Z)AmV>1aPm>)>x8j9bb{d8Cy}Wpak|8XwSb>jNdH~r>Y*4BZVIXJ z$8H_W+mZe4apKOIIz5XG*rO>-f65*K!Qa?b=@=D`Lr0tF1n>LynXK!$eWJL(!%h$P zMpDan2Xd&-UPhpi+E=0e`7O1(hy=aVJ_(m%tZ09eFU4O(`*Cy?ek|GJ*=5P@MCEuw zGAN`tpKlcNwAi;0IJQ!WfP*FW{jhk=;6PrdLMMEfOGoz)JU4Wu9I3-4ym8vp))Kt=-CAK5n0lJ=c@Ni|p?zyywKj+4hwp zp0|b^`~4t~x5qHcc>7iBzg1oi2kif534EegWonE4y5qYx<8k|biCYWyY@5B6u+iJ> zjKtn@2GY4?h3r2^LbumLX&c*h@R?VZ^bObKSBAw{l$n@4^{5wqAJLJUoKkQcdvSR8WWgui=QE32#7 zjesLbWWF-T8NBmb4_7+gncLQ(^5YUGisTs(k2n%wx5@OMko=k>O(LKZEMk!8?z(q)5*s%tFT0PyQwzW~4Lih|%i)f{H{xF%v{+VA}zH_o1RAOjvJuAw@- z+xU$Xa;+{;e12A5p06-1CAqLDzbH99E2BC&uh5&8oROWLmFdgROv~`4LHQ|H3bPtq zUljsXqgJ#1vs_b2+fNK66E0S{b`DGN`7-k}3X77x-VASYdbPJY*;kmCo?Mt)Sd@~P zotu}P23`3scbIcQzj*m^1pe{h`K3CE-7&|tfsz)Kdy>JM%K^()WnO%4W@=GZp|3Ex zz?Y6~W>opG&HU`-G;e-teqmN>t}iVO$OlSHSmbSujvr{Wv)GlV2fA6A023=+$*_2{ zqLJ;`2kWVFd3AKgR^H!)(D366Qu9*0c`511>As@u-} zTA1J8m1*hU#&2H5$6s`Kk&6aM6Pj+}HZ?ByJps?Y=^DY_ z>~u{Lb#H&$^2osqc-ic7>1Pi9BM3`RxU8U=5!`#yH5``NT+Shl4NDf+)GS!Apt7`d z)}6x}Ke(w>qqpIE1aeiEE3~=n)03_!G3@&?mj_WuQEGL&G0-;CWMlDfxOPkM`=jVg zJU-JT!8>zIUS;;e#S0fSd*F^2BAxK`3y~ATJ*yTiT(;2DT(O|Bp#jSp!QY@oYonVh z8k-g_t7^u-E1Rm8vE6UF7N!E7>{?A$a{csB)JAyyZ55+eB(7)Os=Sz|(onVC7gHhi{=j21hMrXW&YXv>^E(so-uFrT%4U`ik7ib3 vR&t@Yps*;TuplqJr~tw@M#X5#hJLY($8nNf=uK>J6_KA{^9(jd)zkk0&+#YA From 188518856814438071aa0f6009fe1231a4362cce Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Tue, 18 Dec 2018 18:40:22 +0100 Subject: [PATCH 51/85] #8: Removed unused imports. --- .../zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java b/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java index 6f512f0c..3eed5a59 100644 --- a/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java +++ b/core/crce-metadata-indexer-api/src/main/java/cz/zcu/kiv/crce/metadata/indexer/AbstractResourceIndexer.java @@ -1,10 +1,8 @@ package cz.zcu.kiv.crce.metadata.indexer; import cz.zcu.kiv.crce.metadata.AttributeType; -import cz.zcu.kiv.crce.metadata.Resource; import cz.zcu.kiv.crce.plugin.AbstractPlugin; -import java.io.InputStream; import java.util.Collections; import java.util.List; import java.util.Map; From fb83cf6ca9ec6b68f9ec8be46a06810f58209535 Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Tue, 18 Dec 2018 20:00:04 +0100 Subject: [PATCH 52/85] #3: Dockerfile moved to deploy dir. Newer version of Felix used. --- Dockerfile => deploy/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename Dockerfile => deploy/Dockerfile (63%) diff --git a/Dockerfile b/deploy/Dockerfile similarity index 63% rename from Dockerfile rename to deploy/Dockerfile index a80de102..9a6f2d49 100644 --- a/Dockerfile +++ b/deploy/Dockerfile @@ -7,12 +7,12 @@ WORKDIR /felix # Download and upack Felix # 4.6.1 is compatible with Java 1.7 -ADD https://archive.apache.org/dist/felix/org.apache.felix.main.distribution-4.6.1.tar.gz ./apache-felix.tar.gz +ADD https://archive.apache.org/dist/felix/org.apache.felix.main.distribution-5.0.0.tar.gz ./apache-felix.tar.gz RUN tar xvfz apache-felix.tar.gz && rm apache-felix.tar.gz -ENV FELIX_PATH /felix/felix-framework-4.6.1 +ENV FELIX_PATH /felix/felix-framework-5.0.0 # Add CRCE modules to Felix autodeploy dir -ADD ./deploy/runner/bundles/* ${FELIX_PATH}/bundle/ +ADD ./runner/bundles/* ${FELIX_PATH}/bundle/ # Run Felix -CMD cd ${FELIX_PATH} && java -jar ./bin/felix.jar +CMD cd ${FELIX_PATH} && java -Dgosh.args=--noi -jar ./bin/felix.jar From 63042df5a32a44c00dc865627826dfc891120f0a Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Tue, 18 Dec 2018 20:37:11 +0100 Subject: [PATCH 53/85] #8: Fully qualified names fixed so pmd is ok. --- .../internal/OsgiManifestBundleIndexer.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexer.java b/modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexer.java index 890a3bd8..54f4c822 100644 --- a/modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexer.java +++ b/modules/crce-metadata-osgi-bundle/src/main/java/cz/zcu/kiv/crce/metadata/osgi/internal/OsgiManifestBundleIndexer.java @@ -42,7 +42,6 @@ import cz.zcu.kiv.crce.metadata.osgi.namespace.*; import cz.zcu.kiv.crce.metadata.service.MetadataService; import cz.zcu.kiv.crce.metadata.type.Version; -import org.apache.felix.utils.manifest.Attribute; import org.apache.felix.utils.manifest.Clause; import org.apache.felix.utils.manifest.Directive; import org.apache.felix.utils.manifest.Parser; @@ -122,16 +121,16 @@ public InputStream getInputStream() throws IOException { return Collections.emptyList(); } - cz.zcu.kiv.crce.metadata.Attribute pn = osgiIdentity.getAttribute(NsOsgiIdentity.ATTRIBUTE__PRESENTATION_NAME); + Attribute pn = osgiIdentity.getAttribute(NsOsgiIdentity.ATTRIBUTE__PRESENTATION_NAME); if (pn != null) { metadataService.setPresentationName(resource, pn.getValue()); } - cz.zcu.kiv.crce.metadata.Attribute sn = osgiIdentity.getAttribute(NsOsgiIdentity.ATTRIBUTE__SYMBOLIC_NAME); + Attribute sn = osgiIdentity.getAttribute(NsOsgiIdentity.ATTRIBUTE__SYMBOLIC_NAME); if(sn != null) { metadataService.setExternalId(resource, sn.getValue()); } - cz.zcu.kiv.crce.metadata.Attribute ver = osgiIdentity.getAttribute(NsOsgiIdentity.ATTRIBUTE__VERSION); + Attribute ver = osgiIdentity.getAttribute(NsOsgiIdentity.ATTRIBUTE__VERSION); if(ver != null) { Capability identity = metadataService.getIdentity(resource); identity.setAttribute(NsCrceIdentity.ATTRIBUTE__VERSION, ver.getValue()); @@ -354,9 +353,9 @@ private void createServiceFilter(Requirement ri, Clause clause) { private Capability createServiceCapability(Clause clause) { Capability capability = metadataFactory.createCapability(NsOsgiService.NAMESPACE__OSGI_SERVICE); capability.setAttribute(NsOsgiService.ATTRIBUTE__NAME, clause.getName()); - Attribute[] attributes = clause.getAttributes(); + org.apache.felix.utils.manifest.Attribute[] attributes = clause.getAttributes(); if (attributes != null) { - for (Attribute attribute : attributes) { + for (org.apache.felix.utils.manifest.Attribute attribute : attributes) { capability.setAttribute(new SimpleAttributeType<>(attribute.getName(), String.class), attribute.getValue()); } } @@ -444,7 +443,7 @@ private Capability createCapability(Clause clause) { Capability capability = metadataFactory.createCapability(NsOsgiPackage.NAMESPACE__OSGI_PACKAGE); capability.setAttribute(NsOsgiPackage.ATTRIBUTE__NAME, clause.getName()); capability.setAttribute(NsOsgiPackage.ATTRIBUTE__VERSION, new Version(getVersion(clause))); - Attribute[] attributes = clause.getAttributes(); + org.apache.felix.utils.manifest.Attribute[] attributes = clause.getAttributes(); for (int i = 0; attributes != null && i < attributes.length; i++) { String key = attributes[i].getName(); if (!key.equalsIgnoreCase(Constants.PACKAGE_SPECIFICATION_VERSION) && !key.equalsIgnoreCase(Constants.VERSION_ATTRIBUTE)) { @@ -478,7 +477,7 @@ private void doImportPackages(Resource resource, Headers headers) throws IOExcep private void createImportFilter(Requirement requirement, AttributeType name, Clause clause) { requirement.addAttribute(name, clause.getName()); appendVersion(requirement, NsOsgiPackage.ATTRIBUTE__VERSION, getVersionRange(clause)); - Attribute[] attributes = clause.getAttributes(); + org.apache.felix.utils.manifest.Attribute[] attributes = clause.getAttributes(); Set attrs = doImportPackageAttributes(requirement, attributes); // The next code is using the subset operator @@ -502,7 +501,7 @@ private void createImportFilter(Requirement requirement, AttributeType n } @SuppressWarnings("deprecation") - private Set doImportPackageAttributes(Requirement requirement, Attribute[] attributes) { + private Set doImportPackageAttributes(Requirement requirement, org.apache.felix.utils.manifest.Attribute[] attributes) { HashSet set = new HashSet<>(); for (int i = 0; attributes != null && i < attributes.length; i++) { String name = attributes[i].getName(); From 9bd1377c940faa040507025311b934e1fb75e309 Mon Sep 17 00:00:00 2001 From: Radek Vais Date: Sat, 29 Dec 2018 12:47:49 +0100 Subject: [PATCH 54/85] Add documentation placeholder --- arch/.gitignore | 8 +++++ arch/sar-2018.pdf | Bin 0 -> 131865 bytes arch/sar-2018.tex | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 arch/.gitignore create mode 100644 arch/sar-2018.pdf create mode 100644 arch/sar-2018.tex diff --git a/arch/.gitignore b/arch/.gitignore new file mode 100644 index 00000000..a14f836d --- /dev/null +++ b/arch/.gitignore @@ -0,0 +1,8 @@ +#ignore vim +*.swp + +#ignore tex build +*.aux +*.gz +*.log + diff --git a/arch/sar-2018.pdf b/arch/sar-2018.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2ca3beff6052316cf0731495f358080c4de802ce GIT binary patch literal 131865 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 Nn|=52aQ=AN{RJMWhrs{< literal 0 HcmV?d00001 diff --git a/arch/sar-2018.tex b/arch/sar-2018.tex new file mode 100644 index 00000000..8323e0c5 --- /dev/null +++ b/arch/sar-2018.tex @@ -0,0 +1,79 @@ +\documentclass[12pt, a4paper]{article} +\usepackage[utf8]{inputenc} +\usepackage[IL2]{fontenc} +\usepackage[czech]{babel} +\usepackage{graphicx} + +\begin{document} +\begin{figure}[h!] +\centering +\includegraphics[bb= 0 0 820 445 , width=75mm]{favlogo.jpg} +\end{figure} + +\vspace{5cm} + +{\centering +{\huge Architektura CRCE}\\[1em] +{\large KIV/SAR - semestrální práce}\\[7,5cm] +} + +\begin{tabular}{l r} +student: & Radek VAIS, Zdeněk VALEŠ\\ +mail: & vaisr@students.zcu.cz, valesz@students.zcu.cz\\ +datum: & 1.1.2019\\ +\end{tabular} + +\thispagestyle{empty} +\newpage + +%======================================== +%======================================== +%======================================== +%======================================== +%======================================== +\section{Zadání} %===================================================================================================== + +CRCE je komponentívé úložiště \ldots + +\subsection{Motivace} + +\subsection{Cíle projektu} + +\newpage +%======================================== +%======================================== +%======================================== +%======================================== +%======================================== +\section{Analýza~architektury} %============================================================================================ + + +%======================================== +%======================================== +%======================================== +%======================================== +%======================================== +\section{Popis~navržených~změn} %======================================================================================= + + +%======================================== +%======================================== +%======================================== +%======================================== +%======================================== +\section{Uživatelská~příručka} %====================================================================================== + +Provedené změny ovlivnily základní používání projektu při vývoji. + + +%======================================== +%======================================== +%======================================== +%======================================== +%======================================== +\newpage +\section{Závěr} %====================================================================================================== + + + +\end{document} \ No newline at end of file From a0b3a695b0dc28577233aecff982efd80f70c5d5 Mon Sep 17 00:00:00 2001 From: Zdenek Vales Date: Thu, 3 Jan 2019 20:24:32 +0100 Subject: [PATCH 55/85] #8: crce-webui module moved to core, version increased to 2.1.2-SNAPSHOT. --- build/compiled/pom.xml | 14 + build/pom.xml | 17 + {modules => core}/crce-webui/osgi.bnd | 0 {modules => core}/crce-webui/pom.xml | 23 +- .../kiv/crce/webui/internal/Activator.java | 0 .../kiv/crce/webui/internal/CheckServlet.java | 160 +- .../crce/webui/internal/DownloadServlet.java | 264 +-- .../kiv/crce/webui/internal/EditServlet.java | 2046 ++++++++--------- .../zcu/kiv/crce/webui/internal/Helper.java | 0 .../crce/webui/internal/ResourceServlet.java | 16 +- .../crce/webui/internal/RuntimeServlet.java | 222 +- .../crce/webui/internal/SessionListener.java | 0 .../crce/webui/internal/UploadServlet.java | 0 .../kiv/crce/webui/internal/VersionInfo.java | 0 .../crce/webui/internal/bean/Category.java | 0 .../crce/webui/internal/custom/Plugin.java | 0 .../internal/custom/RequirementAdapter.java | 170 +- .../webui/internal/custom/RequirementExt.java | 42 +- .../internal/custom/RequirementsWrap.java | 84 +- .../internal/custom/ResourceAdapter.java | 682 +++--- .../webui/internal/custom/ResourceExt.java | 90 +- .../webui/internal/custom/ResourceWrap.java | 963 ++++---- .../CompatibilityAvailabilityFilter.java | 0 .../webui/internal/legacy/Capability.java | 0 .../webui/internal/legacy/NewProperty.java | 26 +- .../crce/webui/internal/legacy/Property.java | 0 .../internal/legacy/PropertyProvider.java | 0 .../webui/internal/legacy/Requirement.java | 0 .../crce/webui/internal/legacy/Resource.java | 0 .../kiv/crce/webui/internal/legacy/Type.java | 0 .../src/main/webapp/META-INF/MANIFEST.MF | 6 +- .../src/main/webapp/WEB-INF/web.xml | 0 .../crce-webui/src/main/webapp/crce.png | Bin .../crce-webui/src/main/webapp/css/styl.css | 1222 +++++----- .../src/main/webapp/graphic/add.png | Bin .../src/main/webapp/graphic/check.png | Bin .../src/main/webapp/graphic/commit.png | Bin .../src/main/webapp/graphic/crce.png | Bin .../src/main/webapp/graphic/del.png | Bin .../src/main/webapp/graphic/edit.png | Bin .../src/main/webapp/graphic/heading-bg.png | Bin .../src/main/webapp/graphic/hlavicka_bg.png | Bin .../src/main/webapp/graphic/hlavicka_loga.png | Bin .../src/main/webapp/graphic/logo.png | Bin .../src/main/webapp/graphic/menu_bg.png | Bin .../src/main/webapp/graphic/save.png | Bin .../src/main/webapp/graphic/zoom.png | Bin .../crce-webui/src/main/webapp/index.jsp | 10 +- .../src/main/webapp/js/jquery-1.5.1.js | 0 .../src/main/webapp/js/plus_minus_form.js | 96 +- .../crce-webui/src/main/webapp/js/slide.js | 36 +- .../crce-webui/src/main/webapp/jsp/buffer.jsp | 0 .../src/main/webapp/jsp/compatibility.jsp | 2 +- .../webapp/jsp/forms/capabilitiesForm.jsp | 92 +- .../main/webapp/jsp/forms/capabilityForm.jsp | 60 +- .../main/webapp/jsp/forms/categoriesForm.jsp | 48 +- .../main/webapp/jsp/forms/categoryForm.jsp | 60 +- .../src/main/webapp/jsp/forms/pluginForm.jsp | 68 +- .../main/webapp/jsp/forms/propertiesForm.jsp | 114 +- .../main/webapp/jsp/forms/propertyForm.jsp | 96 +- .../main/webapp/jsp/forms/requirementForm.jsp | 110 +- .../webapp/jsp/forms/requirementsForm.jsp | 78 +- .../src/main/webapp/jsp/forms/testForm.jsp | 130 +- .../src/main/webapp/jsp/include/footer.jsp | 22 +- .../src/main/webapp/jsp/include/header.jsp | 0 .../src/main/webapp/jsp/plugins.jsp | 0 .../crce-webui/src/main/webapp/jsp/store.jsp | 0 .../crce-webui/src/main/webapp/jsp/tags.jsp | 0 .../crce-webui/src/main/webapp/test.jsp | 8 +- .../webui/internal/ResourceServletTest.java | 0 modules/crce-default-modules/pom.xml | 2 +- modules/pom.xml | 2 +- 72 files changed, 3560 insertions(+), 3521 deletions(-) rename {modules => core}/crce-webui/osgi.bnd (100%) rename {modules => core}/crce-webui/pom.xml (91%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Activator.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java (97%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java (97%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java (97%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Helper.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java (95%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java (97%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/SessionListener.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/UploadServlet.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/VersionInfo.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/bean/Category.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/Plugin.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java (95%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java (95%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java (95%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java (94%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java (96%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java (93%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/filter/CompatibilityAvailabilityFilter.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Capability.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java (96%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Property.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/PropertyProvider.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Requirement.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Resource.java (100%) rename {modules => core}/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Type.java (100%) rename {modules => core}/crce-webui/src/main/webapp/META-INF/MANIFEST.MF (92%) rename {modules => core}/crce-webui/src/main/webapp/WEB-INF/web.xml (100%) rename {modules => core}/crce-webui/src/main/webapp/crce.png (100%) rename {modules => core}/crce-webui/src/main/webapp/css/styl.css (94%) rename {modules => core}/crce-webui/src/main/webapp/graphic/add.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/check.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/commit.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/crce.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/del.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/edit.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/heading-bg.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/hlavicka_bg.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/hlavicka_loga.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/logo.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/menu_bg.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/save.png (100%) rename {modules => core}/crce-webui/src/main/webapp/graphic/zoom.png (100%) rename {modules => core}/crce-webui/src/main/webapp/index.jsp (95%) rename {modules => core}/crce-webui/src/main/webapp/js/jquery-1.5.1.js (100%) rename {modules => core}/crce-webui/src/main/webapp/js/plus_minus_form.js (96%) rename {modules => core}/crce-webui/src/main/webapp/js/slide.js (96%) rename {modules => core}/crce-webui/src/main/webapp/jsp/buffer.jsp (100%) rename {modules => core}/crce-webui/src/main/webapp/jsp/compatibility.jsp (100%) rename {modules => core}/crce-webui/src/main/webapp/jsp/forms/capabilitiesForm.jsp (97%) rename {modules => core}/crce-webui/src/main/webapp/jsp/forms/capabilityForm.jsp (96%) rename {modules => core}/crce-webui/src/main/webapp/jsp/forms/categoriesForm.jsp (97%) rename {modules => core}/crce-webui/src/main/webapp/jsp/forms/categoryForm.jsp (96%) rename {modules => core}/crce-webui/src/main/webapp/jsp/forms/pluginForm.jsp (96%) rename {modules => core}/crce-webui/src/main/webapp/jsp/forms/propertiesForm.jsp (97%) rename {modules => core}/crce-webui/src/main/webapp/jsp/forms/propertyForm.jsp (97%) rename {modules => core}/crce-webui/src/main/webapp/jsp/forms/requirementForm.jsp (97%) rename {modules => core}/crce-webui/src/main/webapp/jsp/forms/requirementsForm.jsp (98%) rename {modules => core}/crce-webui/src/main/webapp/jsp/forms/testForm.jsp (96%) rename {modules => core}/crce-webui/src/main/webapp/jsp/include/footer.jsp (97%) rename {modules => core}/crce-webui/src/main/webapp/jsp/include/header.jsp (100%) rename {modules => core}/crce-webui/src/main/webapp/jsp/plugins.jsp (100%) rename {modules => core}/crce-webui/src/main/webapp/jsp/store.jsp (100%) rename {modules => core}/crce-webui/src/main/webapp/jsp/tags.jsp (100%) rename {modules => core}/crce-webui/src/main/webapp/test.jsp (100%) rename {modules => core}/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java (100%) diff --git a/build/compiled/pom.xml b/build/compiled/pom.xml index c0ceda26..3377beca 100644 --- a/build/compiled/pom.xml +++ b/build/compiled/pom.xml @@ -125,6 +125,20 @@ true provided + + + + javax.ws.rs + javax.ws.rs-api + + + org.glassfish.jersey.containers + jersey-container-servlet-core + + + org.glassfish.jersey.media + jersey-media-multipart + diff --git a/build/pom.xml b/build/pom.xml index 0676f4c3..e04246ef 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -161,6 +161,23 @@ + + + javax.ws.rs + javax.ws.rs-api + 2.0 + + + org.glassfish.jersey.containers + jersey-container-servlet-core + 2.9.1 + + + org.glassfish.jersey.media + jersey-media-multipart + 2.9.1 + + @@ -135,18 +137,14 @@ ${project.groupId} crce-core + 3.0.0-SNAPSHOT pom - - ${project.groupId} - crce-metadata-osgi-bundle - ${project.version} - ${project.groupId} crce-compatibility-api - ${project.version} + ${compatibility.api.version} @@ -167,14 +165,21 @@ javax.ws.rs javax.ws.rs-api + 2.0 org.glassfish.jersey.containers jersey-container-servlet-core + 2.9.1 org.glassfish.jersey.media jersey-media-multipart + 2.9.1 + + + org.apache.felix + org.apache.felix.bundlerepository diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Activator.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Activator.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Activator.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Activator.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java similarity index 97% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java index 124026df..f075e75f 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/CheckServlet.java @@ -1,80 +1,80 @@ -package cz.zcu.kiv.crce.webui.internal; - -import java.io.IOException; -import java.util.Collections; -import java.util.List; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -//import cz.zcu.kiv.crce.metadata.Resolver; -import cz.zcu.kiv.crce.metadata.Resource; -//import cz.zcu.kiv.crce.metadata.ResourceCreator; - -public class CheckServlet extends HttpServlet { - - private static final Logger logger = LoggerFactory.getLogger(CheckServlet.class); - - private static final long serialVersionUID = -6116518932972052481L; - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - List res = chooseFrom(req); - if (res == null) { - req.getRequestDispatcher("resource").forward(req, resp); - } else { - String source = (String) req.getSession().getAttribute("source"); - req.getSession().setAttribute(source, res); - req.getSession().removeAttribute("source"); - req.getRequestDispatcher("jsp/" + source + ".jsp").forward(req, resp); - } - - } - - private List chooseFrom(HttpServletRequest req) { - String source = (String) req.getSession().getAttribute("source"); - if (source == null) { - return null; - } else if (source.equals("buffer")) { - return doCheck(Activator.instance().getBuffer(req).getResources()); - } else if (source.equals("store")) { - return doCheck(Activator.instance().getStore(null).getResources()); - } else { - return null; - } - } - - private List doCheck(List resources) { - logger.warn("Resolver is not designed yet in new Metadata API, returning empty list of resources. Checked resource: {}", resources); -// Resource[] resources = repository.getResources(); -// Resource[] cloned = new Resource[resources.length]; -// System.arraycopy(resources, 0, cloned, 0, resources.length); -// ArrayList ext = new ArrayList<>(); -// HashMap extMap = new HashMap<>(); -// ResourceCreator rc = Activator.instance().getCreator(); -// Resolver resolver = rc.createResolver(repository); -// for (Resource r : cloned) { -// resolver.add(r); -// r.getUri(); -// extMap.put(r.getUri(), new ResourceExt(r)); -// ext.add(new ResourceExt(r)); -// } -// if (!resolver.resolve()) { -// for (Reason r : resolver.getUnsatisfiedRequirements()) { -// if (extMap.containsKey(r.getResource().getUri())) { -// extMap.get(r.getResource().getUri()).addRequirement(r.getRequirement()); -// } -// -// } -// return extMap.values().toArray(new Resource[extMap.values().size()]); -// } else { -// return resources; -// } - return Collections.emptyList(); - } -} +package cz.zcu.kiv.crce.webui.internal; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +//import cz.zcu.kiv.crce.metadata.Resolver; +import cz.zcu.kiv.crce.metadata.Resource; +//import cz.zcu.kiv.crce.metadata.ResourceCreator; + +public class CheckServlet extends HttpServlet { + + private static final Logger logger = LoggerFactory.getLogger(CheckServlet.class); + + private static final long serialVersionUID = -6116518932972052481L; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + List res = chooseFrom(req); + if (res == null) { + req.getRequestDispatcher("resource").forward(req, resp); + } else { + String source = (String) req.getSession().getAttribute("source"); + req.getSession().setAttribute(source, res); + req.getSession().removeAttribute("source"); + req.getRequestDispatcher("jsp/" + source + ".jsp").forward(req, resp); + } + + } + + private List chooseFrom(HttpServletRequest req) { + String source = (String) req.getSession().getAttribute("source"); + if (source == null) { + return null; + } else if (source.equals("buffer")) { + return doCheck(Activator.instance().getBuffer(req).getResources()); + } else if (source.equals("store")) { + return doCheck(Activator.instance().getStore(null).getResources()); + } else { + return null; + } + } + + private List doCheck(List resources) { + logger.warn("Resolver is not designed yet in new Metadata API, returning empty list of resources. Checked resource: {}", resources); +// Resource[] resources = repository.getResources(); +// Resource[] cloned = new Resource[resources.length]; +// System.arraycopy(resources, 0, cloned, 0, resources.length); +// ArrayList ext = new ArrayList<>(); +// HashMap extMap = new HashMap<>(); +// ResourceCreator rc = Activator.instance().getCreator(); +// Resolver resolver = rc.createResolver(repository); +// for (Resource r : cloned) { +// resolver.add(r); +// r.getUri(); +// extMap.put(r.getUri(), new ResourceExt(r)); +// ext.add(new ResourceExt(r)); +// } +// if (!resolver.resolve()) { +// for (Reason r : resolver.getUnsatisfiedRequirements()) { +// if (extMap.containsKey(r.getResource().getUri())) { +// extMap.get(r.getResource().getUri()).addRequirement(r.getRequirement()); +// } +// +// } +// return extMap.values().toArray(new Resource[extMap.values().size()]); +// } else { +// return resources; +// } + return Collections.emptyList(); + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java similarity index 97% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java index 0f68ce99..983e1328 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/DownloadServlet.java @@ -1,132 +1,132 @@ -package cz.zcu.kiv.crce.webui.internal; - -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; - -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import cz.zcu.kiv.crce.metadata.Resource; -import cz.zcu.kiv.crce.webui.internal.custom.ResourceExt; - -public class DownloadServlet extends HttpServlet { - - private static final long serialVersionUID = 6399102910617353070L; - - private static final Logger logger = LoggerFactory.getLogger(DownloadServlet.class); - - private static final int BUFSIZE = 128; - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - boolean success; - String message; - @SuppressWarnings("unchecked") - List buffer = (List) req.getSession().getAttribute("buffer"); - List list = Activator.instance().getBuffer(req).commit(true); - if (list.size() == buffer.size()) { - success = true; - message = "All resources commited successfully"; - } else { - success = false; - message = "Not all resources commited successfully"; - } - req.getSession().setAttribute("source", "commit"); - ResourceServlet.setError(req.getSession(), success, message); - req.getRequestDispatcher("resource?link=store").forward(req, resp); - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - boolean failed = false; - String message; - if (req.getParameter("uri") != null) { - String link = (String) req.getSession().getAttribute("source"); - String uri = req.getParameter("uri"); - try { - URI fileUri = new URI(uri); - if (link != null) { - switch (link) { - case "store": { - List resources = Activator.instance().getStore(null).getResources(); - Resource found = EditServlet.findResource(fileUri, resources); - doDownload(req, resp, found); - break; - } - case "buffer": { - List resources = Activator.instance().getBuffer(req).getResources(); - Resource found = EditServlet.findResource(fileUri, resources); - logger.debug("Found!" + Activator.instance().getMetadataService().getPresentationName(found)); - doDownload(req, resp, found); - break; - } - default: - failed = true; - break; - } - } else { - failed = true; - } - - } catch (IOException e) { - failed = true; - logger.error("Failed to download resource: {}", uri, e); - } catch (URISyntaxException e) { - failed = true; - logger.error("Failed to download resource, invalid URI: {}", uri, e); - } - } else { - failed = true; - } - - if (failed) { - message = "Download failed"; - } else { - message = "Download successful"; - } - ResourceServlet.setError(req.getSession(), !failed, message); - - } - - private void doDownload(HttpServletRequest req, HttpServletResponse resp, Resource found) throws IOException { // NOPMD req would be used in the future - - File f = new File(Activator.instance().getMetadataService().getUri(found)); - int length = 0; - try (ServletOutputStream op = resp.getOutputStream()) { - ServletContext context = getServletConfig().getServletContext(); - String mimetype = context.getMimeType(Activator.instance().getMetadataService().getUri(found).toString()); - - // - // Set the response and go! - // - // - resp.setContentType((mimetype != null) ? mimetype : "application/octet-stream"); - resp.setContentLength((int) f.length()); - resp.setHeader("Content-Disposition", "attachment; filename=\"" + Activator.instance().getMetadataService().getFileName(found) + "\""); - - // - // Stream to the requester. - // - byte[] bbuf = new byte[BUFSIZE]; - try (DataInputStream in = new DataInputStream(new FileInputStream(f))) { - while (in != null && (length = in.read(bbuf)) != -1) { - op.write(bbuf, 0, length); - } - op.flush(); - } - } - } -} +package cz.zcu.kiv.crce.webui.internal; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.webui.internal.custom.ResourceExt; + +public class DownloadServlet extends HttpServlet { + + private static final long serialVersionUID = 6399102910617353070L; + + private static final Logger logger = LoggerFactory.getLogger(DownloadServlet.class); + + private static final int BUFSIZE = 128; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + boolean success; + String message; + @SuppressWarnings("unchecked") + List buffer = (List) req.getSession().getAttribute("buffer"); + List list = Activator.instance().getBuffer(req).commit(true); + if (list.size() == buffer.size()) { + success = true; + message = "All resources commited successfully"; + } else { + success = false; + message = "Not all resources commited successfully"; + } + req.getSession().setAttribute("source", "commit"); + ResourceServlet.setError(req.getSession(), success, message); + req.getRequestDispatcher("resource?link=store").forward(req, resp); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + boolean failed = false; + String message; + if (req.getParameter("uri") != null) { + String link = (String) req.getSession().getAttribute("source"); + String uri = req.getParameter("uri"); + try { + URI fileUri = new URI(uri); + if (link != null) { + switch (link) { + case "store": { + List resources = Activator.instance().getStore(null).getResources(); + Resource found = EditServlet.findResource(fileUri, resources); + doDownload(req, resp, found); + break; + } + case "buffer": { + List resources = Activator.instance().getBuffer(req).getResources(); + Resource found = EditServlet.findResource(fileUri, resources); + logger.debug("Found!" + Activator.instance().getMetadataService().getPresentationName(found)); + doDownload(req, resp, found); + break; + } + default: + failed = true; + break; + } + } else { + failed = true; + } + + } catch (IOException e) { + failed = true; + logger.error("Failed to download resource: {}", uri, e); + } catch (URISyntaxException e) { + failed = true; + logger.error("Failed to download resource, invalid URI: {}", uri, e); + } + } else { + failed = true; + } + + if (failed) { + message = "Download failed"; + } else { + message = "Download successful"; + } + ResourceServlet.setError(req.getSession(), !failed, message); + + } + + private void doDownload(HttpServletRequest req, HttpServletResponse resp, Resource found) throws IOException { // NOPMD req would be used in the future + + File f = new File(Activator.instance().getMetadataService().getUri(found)); + int length = 0; + try (ServletOutputStream op = resp.getOutputStream()) { + ServletContext context = getServletConfig().getServletContext(); + String mimetype = context.getMimeType(Activator.instance().getMetadataService().getUri(found).toString()); + + // + // Set the response and go! + // + // + resp.setContentType((mimetype != null) ? mimetype : "application/octet-stream"); + resp.setContentLength((int) f.length()); + resp.setHeader("Content-Disposition", "attachment; filename=\"" + Activator.instance().getMetadataService().getFileName(found) + "\""); + + // + // Stream to the requester. + // + byte[] bbuf = new byte[BUFSIZE]; + try (DataInputStream in = new DataInputStream(new FileInputStream(f))) { + while (in != null && (length = in.read(bbuf)) != -1) { + op.write(bbuf, 0, length); + } + op.flush(); + } + } + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java similarity index 97% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java index 801e5898..3121fba0 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/EditServlet.java @@ -1,1023 +1,1023 @@ -package cz.zcu.kiv.crce.webui.internal; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import cz.zcu.kiv.crce.metadata.Attribute; -import cz.zcu.kiv.crce.metadata.Capability; -import cz.zcu.kiv.crce.metadata.Requirement; -import cz.zcu.kiv.crce.metadata.Resource; -import cz.zcu.kiv.crce.metadata.impl.GenericAttributeType; -import cz.zcu.kiv.crce.webui.internal.legacy.Type; - -public class EditServlet extends HttpServlet { - - private static final long serialVersionUID = -4949620462179710290L; - - private static final Logger logger = LoggerFactory.getLogger(EditServlet.class); - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - - boolean success = false; - Map parameters = req.getParameterMap(); - String form = null; - - if (parameters.containsKey("form")) { - form = ((String[]) parameters.get("form"))[0]; - } - if (form != null) { - switch (form) { - case "addCategory": - if (addCategory(req, resp, parameters)) { - success = editCategories(req, resp); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot add category."); - success = true; - } - } else { - ResourceServlet.setError(req.getSession(), false, "Cannot add category."); - success = true; - } - break; - - case "requirements": - if (saveRequirements(req, resp, parameters)) { - success = editRequirements(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot save requirements."); - success = true; - } - } - break; - - case "addRequirement": - if (!addRequirementForm(req, resp, parameters)) { - ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); - } - success = editRequirements(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); - success = true; - } - break; - - case "capabilities": - if (saveCapabilities(req, resp, parameters)) { - success = editCapabilities(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot save capabilities."); - success = true; - } - - } else { - ResourceServlet.setError(req.getSession(), false, "Cannot save capabilities."); - success = true; - } - break; - - case "capability": - if (saveCapability(req, resp, parameters)) { - success = editCapabilities(req, resp, parameters, true); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); - success = true; - } - } else { - ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); - success = true; - } - break; - - case "property": - if (!saveProperty(req, resp, parameters)) { - ResourceServlet.setError(req.getSession(), false, "Cannot add property."); - } - success = editCapabilities(req, resp, parameters, true); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Error while loading capabilities."); - success = true; - } - break; - - case "editProperties": - if (!saveResourceProperty(req, resp, parameters)) { - ResourceServlet.setError(req.getSession(), false, "Cannot change properties."); - } - success = editProperties(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Error while loading capabilities."); - success = true; - } - break; - - default: - } - } - if (!success) { - resp.sendError(HttpServletResponse.SC_ACCEPTED, "NOT FOUND OR FAILED TO PROCEED"); - } - } - - private boolean saveResourceProperty(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future - String uri; - if (parameters.containsKey("uri")) { - uri = ((String[]) parameters.get("uri"))[0]; - } else { - return false; - } - try { - URI resURI = new URI(uri); - String link = (String) req.getSession().getAttribute("source"); - List resources = getResources(req, link); - if (resources == null) { - return false; - } - Resource resource = findResource(resURI, resources); - // TODO why was the following here: -// String symbolicName = ((String[]) parameters.get("symbolicName"))[0]; -// String version = ((String[]) parameters.get("version"))[0]; - -// LegacyMetadataHelper.setVersion(Activator.instance().getMetadataFactory(), resource, new Version(version)); -// LegacyMetadataHelper.setSymbolicName(Activator.instance().getMetadataFactory(), resource, symbolicName); - - Activator.instance().getMetadataDao().saveResource(resource); - } catch (URISyntaxException e) { - logger.warn("Can't save resource property: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't save resource property, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't save resource property", e); - return false; - } - - return true; - } - - private boolean saveProperty(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future - String uri; - String id; - if (parameters.containsKey("uri") && parameters.containsKey("capabilityId")) { - uri = ((String[]) parameters.get("uri"))[0]; - id = ((String[]) parameters.get("capabilityId"))[0]; - } else { - return false; - } - try { - URI resURI = new URI(uri); - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - Resource resource = findResource(resURI, array); - Capability capability = resource.getCapabilities().get(Integer.parseInt(id) - 1); - String name = ((String[]) parameters.get("name"))[0]; - String type = ((String[]) parameters.get("propertyType"))[0]; - Object value = ((String[]) parameters.get("value"))[0]; - - try { - capability.setAttribute(new GenericAttributeType(name, type), value); - } catch (IllegalArgumentException e) { - return false; - } - Activator.instance().getMetadataDao().saveResource(resource); - - } catch (URISyntaxException e) { - logger.warn("Can't save property: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't save property, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't save property", e); - return false; - } - - return true; - } - - private boolean editCapabilities(HttpServletRequest req, - HttpServletResponse resp, Map parameters) { - return editCapabilities(req, resp, parameters, false); - } - - private boolean saveCapability(HttpServletRequest req, - HttpServletResponse resp, Map parameters) { - String uri; - String capabilityName; - if (parameters.containsKey("uri") - && parameters.containsKey("capability")) { - uri = ((String[]) parameters.get("uri"))[0]; - capabilityName = ((String[]) parameters.get("capability"))[0]; - } else { - return false; - } - try { - URI resURI = new URI(uri); - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - Resource resource = findResource(resURI, array); - int lengthBefore = resource.getCapabilities().size(); - resource.addCapability(Activator.instance().getMetadataFactory().createCapability(capabilityName)); - if (lengthBefore == resource.getCapabilities().size()) { - resp.sendRedirect("resource"); - return false; - } - - Activator.instance().getMetadataDao().saveResource(resource); - - req.setAttribute("capabilityId", String.valueOf(resource.getCapabilities().size())); - } catch (URISyntaxException e) { - logger.warn("Can't save capability: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't save capability, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't save capability", e); - return false; - } - - return true; - } - - private boolean addRequirementForm(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future - String uri; - if (parameters.containsKey("uri")) { - uri = ((String[]) parameters.get("uri"))[0]; - } else { - return false; - } - - try { - URI resURI = new URI(uri); - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - Resource resource = findResource(resURI, array); - String name = null; - Requirement requir = null; - String filter = null; - boolean multiple = false; - boolean extend = false; - boolean optional = false; - Requirement requirBefore = null; - if (parameters.containsKey("name") - && parameters.containsKey("filter")) { - name = ((String[]) parameters.get("name"))[0]; - filter = ((String[]) parameters.get("filter"))[0]; - if (parameters.containsKey("multiple")) { - multiple = ((String[]) parameters.get("multiple"))[0].equals("on"); - } - if (parameters.containsKey("optional")) { - optional = ((String[]) parameters.get("optional"))[0].equals("on"); - } - if (parameters.containsKey("extend")) { - extend = ((String[]) parameters.get("extend"))[0].equals("on"); - } - String comment = null; - if (parameters.containsKey("comment")) { - comment = ((String[]) parameters.get("comment"))[0]; - } - int lengthBefore = resource.getRequirements().size(); - requir = Activator.instance().getMetadataFactory().createRequirement(name); - resource.addRequirement(requir); - if (lengthBefore == resource.getRequirements().size()) { - req.getSession().setAttribute("success", false); - req.getSession().setAttribute("message", "Cannot add requirement."); - return false; - } - try { - logger.warn("OSGi filter is not supported yet with new Metadata API, setting as a directive to track it's usage: {}", filter); - requir.setDirective("filter", filter); - } catch (IllegalArgumentException e) { - resource.removeRequirement(requir); - resource.addRequirement(requirBefore); - } - requir.setDirective("multiple", String.valueOf(multiple)); - requir.setDirective("optional", String.valueOf(optional)); - requir.setDirective("extend", String.valueOf(extend)); - requir.setDirective("comment", comment); - } - Activator.instance().getMetadataDao().saveResource(resource); - } catch (URISyntaxException e) { - logger.warn("Can't add requirement: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't add requirement, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't requirement", e); - return false; - } - - req.getSession().setAttribute("success", true); - return true; - - } - - private boolean saveCapabilities(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future - int capabilityId = -1; - String uri; - if (parameters.containsKey("uri") && parameters.containsKey("capabilityId")) { - uri = ((String[]) parameters.get("uri"))[0]; - capabilityId = Integer.parseInt(((String[]) parameters.get("capabilityId"))[0]); - } else { - return false; - } - - try { - URI resURI = new URI(uri); - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - Resource resource = findResource(resURI, array); - - Capability capability = resource.getCapabilities().get(capabilityId - 1); - List> attributes = capability.getAttributes(); -// Property[] properties = capability.getProperties(); - for (int i = 0; i < attributes.size(); i++) { - String name = ((String[]) parameters.get("name_" + (i + 1)))[0]; - String type = ((String[]) parameters.get("type_" + (i + 1)))[0]; - String value = ((String[]) parameters.get("value_" + (i + 1)))[0]; - Attribute propBefore = attributes.get(i); - int propertiesLengthBefore = attributes.size(); - capability.removeAttribute(attributes.get(i).getAttributeType()); - - if (propertiesLengthBefore == capability.getAttributes().size()) { - req.getSession().setAttribute("success", false); - req.getSession().setAttribute("message", "Cannot change property."); - logger.debug("Cannot change property, resource: {}", resource); - continue; - } - - try { - capability.setAttribute(new GenericAttributeType(name, type), value); - } catch (IllegalArgumentException e) { - capability.setAttribute(propBefore); - req.getSession().setAttribute("success", false); - req.getSession().setAttribute("message", "Cannot change property."); - logger.warn("Cannot change property, resource: {}, capability: {}", resource, capability); - } - } - Activator.instance().getMetadataDao().saveResource(resource); - } catch (URISyntaxException e) { - logger.warn("Can't save capabilities: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't save capabilities, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't save capabilities", e); - return false; - } - return true; - } - - private boolean saveRequirements(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future - String uri; - if (parameters.containsKey("uri")) { - uri = ((String[]) parameters.get("uri"))[0]; - } else { - return false; - } - - try { - URI resURI = new URI(uri); - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - Resource resource = findResource(resURI, array); - - List requirements = resource.getRequirements(); - int requirLengthBefore = 0; - String name = null; - Requirement requir = null; - String filter = null; - String comment = null; - boolean multiple = false; - boolean extend = false; - boolean optional = false; - Requirement requirBefore = null; - for (int i = 0; i < requirements.size(); i++) { - - if (parameters.containsKey("name_" + (i + 1)) - && parameters.containsKey("filter_" + (i + 1))) { - - name = ((String[]) parameters.get("name_" + (i + 1)))[0]; - filter = ((String[]) parameters.get("filter_" + (i + 1)))[0]; - - if (parameters.containsKey("multiple_" + (i + 1))) { - multiple = ((String[]) parameters.get("multiple_" + (i + 1)))[0].equals("on"); - } - if (parameters.containsKey("optional_" + (i + 1))) { - optional = ((String[]) parameters.get("optional_" + (i + 1)))[0].equals("on"); - } - if (parameters.containsKey("extend_" + (i + 1))) { - extend = ((String[]) parameters.get("extend_" + (i + 1)))[0].equals("on"); - } - if (parameters.containsKey("comment_" + (i + 1))) { - comment = ((String[]) parameters.get("comment_" + (i + 1)))[0]; - } -// requirBefore = requirements[i]; - requirLengthBefore = requirements.size(); - resource.removeRequirement(requirements.get(i)); - if (requirLengthBefore == resource.getRequirements().size()) { -//TODO req.getSession().setAttribute("success", false); -//TODO req.getSession().setAttribute("message", "Cannot change requirement."); - continue; - } - requir = Activator.instance().getMetadataFactory().createRequirement(name); - resource.addRequirement(requir); - try { - logger.warn("OSGi filter is not supported yet with new Metadata API, setting as a directive to track it's usage: {}", filter); - requir.setDirective("filter", filter); - } catch (IllegalArgumentException e) { -//TODO req.getSession().setAttribute("success", false); -//TODO req.getSession().setAttribute("message", "Cannot change requirement."); - resource.removeRequirement(requir); - resource.addRequirement(requirBefore); - continue; - } - requir.setDirective("multiple", String.valueOf(multiple)); - requir.setDirective("optional", String.valueOf(optional)); - requir.setDirective("extend", String.valueOf(extend)); - requir.setDirective("comment", comment); -// resource.addRequirement(requir); - } - } - Activator.instance().getMetadataDao().saveResource(resource); - } catch (URISyntaxException e) { - logger.warn("Can't save requirements: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't save requirements, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't save requirements", e); - return false; - } - return true; - } - - private boolean addCategory(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future - String category = null; - String uri = null; - if (parameters.containsKey("category") - && parameters.containsKey("uri")) { - category = ((String[]) parameters.get("category"))[0]; - uri = ((String[]) parameters.get("uri"))[0]; - - } else { - return false; - } - - try { - URI resURI = new URI(uri); - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - Resource resource = findResource(resURI, array); - - - int categoriesLengthBefore = Activator.instance().getMetadataService().getCategories(resource).size(); - Activator.instance().getMetadataService().addCategory(resource, category); - - // check that category was really added - if (categoriesLengthBefore >= Activator.instance().getMetadataService().getCategories(resource).size()) { - req.getSession().setAttribute("success", false); - req.getSession().setAttribute("message", "Cannot add category."); - } - - Activator.instance().getMetadataDao().saveResource(resource); - - } catch (URISyntaxException e) { - logger.warn("Can't add category: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't add category, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't add category", e); - return false; - } - return true; - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - cleanSession(req.getSession()); - - req.getSession().removeAttribute("success"); - boolean success = false; - Map parameters = (Map) req.getParameterMap(); - - String type = null; - if (parameters.containsKey("type")) { - type = ((String[]) parameters.get("type"))[0]; - } - if (type != null) { - switch (type) { - case "deleteCompoment": - success = deleteComponent(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot delete component."); - success = true; - } - break; - - case "category": - success = editCategories(req, resp); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot edit category."); - success = true; - } - break; - - case "deleteCategory": - if (!deleteCategory(req, resp, parameters)) { - ResourceServlet.setError(req.getSession(), false, "Cannot delete category."); - success = true; - } - success = editCategories(req, resp); - break; - - case "addCategory": - success = addCategories(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot add category."); - success = true; - } - break; - - case "addCapability": - success = addCapabilities(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); - success = true; - } - break; - - case "addCapabilityProperty": - success = addCapabilityProperty(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); - success = true; - } - break; - - case "capability": - success = editCapabilities(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot edit capabilities."); - success = true; - } - break; - - case "requirement": - success = editRequirements(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot edit requirements."); - success = true; - } - break; - - case "addRequirement": - success = addRequirement(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); - success = true; - } - break; - - case "properties": - success = editProperties(req, resp, parameters); - if (!success) { - ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); - success = true; - } - break; - default: - success = false; - break; - } - } - if (!success) { - resp.sendError(HttpServletResponse.SC_ACCEPTED, "NOT FOUND OR FAILED TO PROCEED"); - } - } - - private boolean editProperties(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - String uri = req.getParameter("uri"); - try { - URI resURI = new URI(uri); - Resource resource = findResource(resURI, array); - req.getSession().setAttribute("resource", resource); - req.getRequestDispatcher("jsp/forms/propertiesForm.jsp").forward(req, resp); // FIXME hardcoded - } catch (URISyntaxException e) { - logger.warn("Can't edit properties: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't edit properties, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't edit properties", e); - return false; - } catch (ServletException e) { - logger.error("Can't forward", e); - return false; - } - return true; - } - - private boolean addCapabilityProperty(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - String uri = req.getParameter("uri"); - try { - URI resURI = new URI(uri); - Resource resource = findResource(resURI, array); - req.getSession().setAttribute("resource", resource); - req.getSession().setAttribute("capabilityId", req.getParameter("capabilityId")); - req.getRequestDispatcher("jsp/forms/propertyForm.jsp").forward(req, resp); // FIXME hardcoded - } catch (URISyntaxException e) { - logger.warn("Can't add capability property: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't add capability property, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't add capability property", e); - return false; - } catch (ServletException e) { - logger.error("Can't forward", e); - return false; - } - - return true; - } - - private boolean addRequirement(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future - - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - String uri = req.getParameter("uri"); - try { - URI resURI = new URI(uri); - Resource resource = findResource(resURI, array); - req.getSession().setAttribute("resource", resource); - req.getRequestDispatcher("jsp/forms/requirementForm.jsp").forward(req, resp); // FIXME hardcoded - } catch (URISyntaxException e) { - logger.warn("Can't add requirement: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't add requirement, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't add requirement", e); - return false; - } catch (ServletException e) { - logger.error("Can't forward", e); - return false; - } - - return true; - } - - private boolean editRequirements(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future - - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - - String uri = req.getParameter("uri"); - - try { - URI resURI = new URI(uri); - Resource resource = findResource(resURI, array); - req.getSession().setAttribute("resource", resource); - req.getRequestDispatcher("jsp/forms/requirementsForm.jsp").forward(req, resp); // FIXME hardcoded - } catch (URISyntaxException e) { - logger.warn("Can't edit requirement: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't edit requirement, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't edit requirement", e); - return false; - } catch (ServletException e) { - logger.error("Can't forward", e); - return false; - } - return true; - } - - private boolean addCapabilities(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - - String uri = req.getParameter("uri"); - - try { - URI resURI = new URI(uri); - Resource resource = findResource(resURI, array); - req.getSession().setAttribute("resource", resource); - req.getSession().setAttribute("types", Type.values()); - req.getRequestDispatcher("jsp/forms/capabilityForm.jsp").forward(req, resp); // FIXME hardcoded - } catch (URISyntaxException e) { - logger.warn("Can't add capabilities: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't add capabilities, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't add capabilities", e); - return false; - } catch (ServletException e) { - logger.error("Can't forward", e); - return false; - } - - return true; - } - - private boolean editCapabilities(HttpServletRequest req, HttpServletResponse resp, Map parameters, boolean b) { - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - - String uri = null; - try { - String id = null; - if (b && parameters.containsKey("uri") && req.getAttribute("capabilityId") != null) { - uri = ((String[]) parameters.get("uri"))[0]; - id = (String) req.getAttribute("capabilityId"); - } else if (parameters.containsKey("capabilityId") && parameters.containsKey("uri")) { - uri = ((String[]) parameters.get("uri"))[0]; - id = ((String[]) parameters.get("capabilityId"))[0]; - } else { - return false; - } - Resource resource = findResource(new URI(uri), array); - - req.getSession().setAttribute("resource", resource); - req.getSession().setAttribute("types", Type.values()); - req.getSession().setAttribute("capability", resource.getCapabilities().get(Integer.parseInt(id) - 1)); - req.getSession().setAttribute("capabilityId", id); - req.getRequestDispatcher("jsp/forms/capabilitiesForm.jsp").forward(req, resp); // FIXME hardcoded - } catch (URISyntaxException e) { - logger.warn("Can't edit capabilities: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't edit capabilities, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't edit capabilities", e); - return false; - } catch (ServletException e) { - logger.error("Can't forward", e); - return false; - } - - return true; - } - - private boolean addCategories(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future - - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - - String uri = req.getParameter("uri"); - try { - URI resURI = new URI(uri); - Resource resource = findResource(resURI, array); - req.getSession().setAttribute("resource", resource); - req.getRequestDispatcher("jsp/forms/categoryForm.jsp").forward(req, resp); // FIXME hardcoded - } catch (URISyntaxException e) { - logger.warn("Can't add capabilities: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't add capabilities, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't add capabilities", e); - return false; - } catch (ServletException e) { - logger.error("Can't forward", e); - return false; - } - - return true; - } - - private boolean editCategories(HttpServletRequest req, HttpServletResponse resp) { - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - - String uri = req.getParameter("uri"); - try { - URI resURI = new URI(uri); - Resource resource = findResource(resURI, array); - req.getSession().setAttribute("resource", resource); - req.getRequestDispatcher("jsp/forms/categoriesForm.jsp").forward(req, resp); // FIXME hardcoded - } catch (URISyntaxException e) { - logger.warn("Can't edit categories: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't edit categories, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't edit categories", e); - return false; - } catch (ServletException e) { - logger.error("Can't forward", e); - return false; - } - - return true; - } - - private boolean deleteCategory(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future - String category = null; - String uri = null; - if (parameters.containsKey("category") - && parameters.containsKey("uri")) { - category = ((String[]) parameters.get("category"))[0]; - uri = ((String[]) parameters.get("uri"))[0]; - - } else { - return false; - } - try { - URI resURI = new URI(uri); - String link = (String) req.getSession().getAttribute("source"); - List array = getResources(req, link); - if (array == null) { - return false; - } - - Resource resource = findResource(resURI, array); - - int categoriesLengthBefore = Activator.instance().getMetadataService().getCategories(resource).size(); - Activator.instance().getMetadataService().removeCategory(resource, category); - -// Zjištění zda kategorie byla odstraněna. - if (categoriesLengthBefore == Activator.instance().getMetadataService().getCategories(resource).size()) { - return false; - } - - Activator.instance().getMetadataDao().saveResource(resource); - - } catch (URISyntaxException e) { - logger.warn("Can't delete category: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't delete category, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't delete category", e); - return false; - } - - return true; - } - - private boolean deleteComponent(HttpServletRequest req, HttpServletResponse resp, final Map parameters) { - String link = null; - String uri = null; - if (parameters.containsKey("link") - && parameters.containsKey("uri")) { - link = ((String[]) parameters.get("link"))[0]; - uri = ((String[]) parameters.get("uri"))[0]; - - } else { - return false; - } - try { - URI fileUri = new URI(uri); - if ("store".equals(link)) { - List array = Activator.instance().getStore(getRepositoryId(req)).getResources(); - Resource found = findResource(fileUri, array); - Activator.instance().getStore(getRepositoryId(req)).remove(found); - } else if ("buffer".equals(link)) { - List array = Activator.instance().getBuffer(req).getResources(); - Resource found = findResource(fileUri, array); - if (!Activator.instance().getBuffer(req).remove(found)) { - logger.warn("Buffer didn't contain removed resource: {}", found); - } - } else { - return false; - } - - req.getRequestDispatcher("resource").forward(req, resp); - - } catch (URISyntaxException e) { - logger.warn("Can't delete component: {}", e.getMessage()); - return false; - } catch (FileNotFoundException e) { - logger.error("Can't delete component, file not found: {}", uri); - return false; - } catch (IOException e) { - logger.error("Can't delete component", e); - return false; - } catch (ServletException e) { - logger.error("Can't forward", e); - return false; - } - return true; - } - - public static Resource findResource(URI uri, List array) throws FileNotFoundException { - Resource found = null; - for (Resource r : array) { - if (Activator.instance().getMetadataService().getUri(r).equals(uri)) { - found = r; - break; - } - } - if (found == null) { - throw new FileNotFoundException(); - } - return found; - } - - private static void cleanSession(HttpSession session) { - session.removeAttribute("resource"); - } - - private List getResources(HttpServletRequest req, String link) { - switch (link) { - case "store": - return Activator.instance().getStore(getRepositoryId(req)).getResources(); - case "buffer": - return Activator.instance().getBuffer(req).getResources(); - default: - return null; - } - } - - private String getRepositoryId(HttpServletRequest req) { - String id = req.getParameter("repositoryId"); - if (id == null) { - Map stores = Activator.instance().getRepositories(); - if (stores.isEmpty()) { - return null; - } - id = stores.keySet().iterator().next(); - logger.trace("Store ID not specified, using the first store found: " + id); - } - return id; - } -} +package cz.zcu.kiv.crce.webui.internal; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cz.zcu.kiv.crce.metadata.Attribute; +import cz.zcu.kiv.crce.metadata.Capability; +import cz.zcu.kiv.crce.metadata.Requirement; +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.metadata.impl.GenericAttributeType; +import cz.zcu.kiv.crce.webui.internal.legacy.Type; + +public class EditServlet extends HttpServlet { + + private static final long serialVersionUID = -4949620462179710290L; + + private static final Logger logger = LoggerFactory.getLogger(EditServlet.class); + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + boolean success = false; + Map parameters = req.getParameterMap(); + String form = null; + + if (parameters.containsKey("form")) { + form = ((String[]) parameters.get("form"))[0]; + } + if (form != null) { + switch (form) { + case "addCategory": + if (addCategory(req, resp, parameters)) { + success = editCategories(req, resp); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add category."); + success = true; + } + } else { + ResourceServlet.setError(req.getSession(), false, "Cannot add category."); + success = true; + } + break; + + case "requirements": + if (saveRequirements(req, resp, parameters)) { + success = editRequirements(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot save requirements."); + success = true; + } + } + break; + + case "addRequirement": + if (!addRequirementForm(req, resp, parameters)) { + ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); + } + success = editRequirements(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); + success = true; + } + break; + + case "capabilities": + if (saveCapabilities(req, resp, parameters)) { + success = editCapabilities(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot save capabilities."); + success = true; + } + + } else { + ResourceServlet.setError(req.getSession(), false, "Cannot save capabilities."); + success = true; + } + break; + + case "capability": + if (saveCapability(req, resp, parameters)) { + success = editCapabilities(req, resp, parameters, true); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); + success = true; + } + } else { + ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); + success = true; + } + break; + + case "property": + if (!saveProperty(req, resp, parameters)) { + ResourceServlet.setError(req.getSession(), false, "Cannot add property."); + } + success = editCapabilities(req, resp, parameters, true); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Error while loading capabilities."); + success = true; + } + break; + + case "editProperties": + if (!saveResourceProperty(req, resp, parameters)) { + ResourceServlet.setError(req.getSession(), false, "Cannot change properties."); + } + success = editProperties(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Error while loading capabilities."); + success = true; + } + break; + + default: + } + } + if (!success) { + resp.sendError(HttpServletResponse.SC_ACCEPTED, "NOT FOUND OR FAILED TO PROCEED"); + } + } + + private boolean saveResourceProperty(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String uri; + if (parameters.containsKey("uri")) { + uri = ((String[]) parameters.get("uri"))[0]; + } else { + return false; + } + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List resources = getResources(req, link); + if (resources == null) { + return false; + } + Resource resource = findResource(resURI, resources); + // TODO why was the following here: +// String symbolicName = ((String[]) parameters.get("symbolicName"))[0]; +// String version = ((String[]) parameters.get("version"))[0]; + +// LegacyMetadataHelper.setVersion(Activator.instance().getMetadataFactory(), resource, new Version(version)); +// LegacyMetadataHelper.setSymbolicName(Activator.instance().getMetadataFactory(), resource, symbolicName); + + Activator.instance().getMetadataDao().saveResource(resource); + } catch (URISyntaxException e) { + logger.warn("Can't save resource property: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't save resource property, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't save resource property", e); + return false; + } + + return true; + } + + private boolean saveProperty(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String uri; + String id; + if (parameters.containsKey("uri") && parameters.containsKey("capabilityId")) { + uri = ((String[]) parameters.get("uri"))[0]; + id = ((String[]) parameters.get("capabilityId"))[0]; + } else { + return false; + } + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + Capability capability = resource.getCapabilities().get(Integer.parseInt(id) - 1); + String name = ((String[]) parameters.get("name"))[0]; + String type = ((String[]) parameters.get("propertyType"))[0]; + Object value = ((String[]) parameters.get("value"))[0]; + + try { + capability.setAttribute(new GenericAttributeType(name, type), value); + } catch (IllegalArgumentException e) { + return false; + } + Activator.instance().getMetadataDao().saveResource(resource); + + } catch (URISyntaxException e) { + logger.warn("Can't save property: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't save property, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't save property", e); + return false; + } + + return true; + } + + private boolean editCapabilities(HttpServletRequest req, + HttpServletResponse resp, Map parameters) { + return editCapabilities(req, resp, parameters, false); + } + + private boolean saveCapability(HttpServletRequest req, + HttpServletResponse resp, Map parameters) { + String uri; + String capabilityName; + if (parameters.containsKey("uri") + && parameters.containsKey("capability")) { + uri = ((String[]) parameters.get("uri"))[0]; + capabilityName = ((String[]) parameters.get("capability"))[0]; + } else { + return false; + } + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + int lengthBefore = resource.getCapabilities().size(); + resource.addCapability(Activator.instance().getMetadataFactory().createCapability(capabilityName)); + if (lengthBefore == resource.getCapabilities().size()) { + resp.sendRedirect("resource"); + return false; + } + + Activator.instance().getMetadataDao().saveResource(resource); + + req.setAttribute("capabilityId", String.valueOf(resource.getCapabilities().size())); + } catch (URISyntaxException e) { + logger.warn("Can't save capability: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't save capability, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't save capability", e); + return false; + } + + return true; + } + + private boolean addRequirementForm(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String uri; + if (parameters.containsKey("uri")) { + uri = ((String[]) parameters.get("uri"))[0]; + } else { + return false; + } + + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + String name = null; + Requirement requir = null; + String filter = null; + boolean multiple = false; + boolean extend = false; + boolean optional = false; + Requirement requirBefore = null; + if (parameters.containsKey("name") + && parameters.containsKey("filter")) { + name = ((String[]) parameters.get("name"))[0]; + filter = ((String[]) parameters.get("filter"))[0]; + if (parameters.containsKey("multiple")) { + multiple = ((String[]) parameters.get("multiple"))[0].equals("on"); + } + if (parameters.containsKey("optional")) { + optional = ((String[]) parameters.get("optional"))[0].equals("on"); + } + if (parameters.containsKey("extend")) { + extend = ((String[]) parameters.get("extend"))[0].equals("on"); + } + String comment = null; + if (parameters.containsKey("comment")) { + comment = ((String[]) parameters.get("comment"))[0]; + } + int lengthBefore = resource.getRequirements().size(); + requir = Activator.instance().getMetadataFactory().createRequirement(name); + resource.addRequirement(requir); + if (lengthBefore == resource.getRequirements().size()) { + req.getSession().setAttribute("success", false); + req.getSession().setAttribute("message", "Cannot add requirement."); + return false; + } + try { + logger.warn("OSGi filter is not supported yet with new Metadata API, setting as a directive to track it's usage: {}", filter); + requir.setDirective("filter", filter); + } catch (IllegalArgumentException e) { + resource.removeRequirement(requir); + resource.addRequirement(requirBefore); + } + requir.setDirective("multiple", String.valueOf(multiple)); + requir.setDirective("optional", String.valueOf(optional)); + requir.setDirective("extend", String.valueOf(extend)); + requir.setDirective("comment", comment); + } + Activator.instance().getMetadataDao().saveResource(resource); + } catch (URISyntaxException e) { + logger.warn("Can't add requirement: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add requirement, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't requirement", e); + return false; + } + + req.getSession().setAttribute("success", true); + return true; + + } + + private boolean saveCapabilities(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + int capabilityId = -1; + String uri; + if (parameters.containsKey("uri") && parameters.containsKey("capabilityId")) { + uri = ((String[]) parameters.get("uri"))[0]; + capabilityId = Integer.parseInt(((String[]) parameters.get("capabilityId"))[0]); + } else { + return false; + } + + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + + Capability capability = resource.getCapabilities().get(capabilityId - 1); + List> attributes = capability.getAttributes(); +// Property[] properties = capability.getProperties(); + for (int i = 0; i < attributes.size(); i++) { + String name = ((String[]) parameters.get("name_" + (i + 1)))[0]; + String type = ((String[]) parameters.get("type_" + (i + 1)))[0]; + String value = ((String[]) parameters.get("value_" + (i + 1)))[0]; + Attribute propBefore = attributes.get(i); + int propertiesLengthBefore = attributes.size(); + capability.removeAttribute(attributes.get(i).getAttributeType()); + + if (propertiesLengthBefore == capability.getAttributes().size()) { + req.getSession().setAttribute("success", false); + req.getSession().setAttribute("message", "Cannot change property."); + logger.debug("Cannot change property, resource: {}", resource); + continue; + } + + try { + capability.setAttribute(new GenericAttributeType(name, type), value); + } catch (IllegalArgumentException e) { + capability.setAttribute(propBefore); + req.getSession().setAttribute("success", false); + req.getSession().setAttribute("message", "Cannot change property."); + logger.warn("Cannot change property, resource: {}, capability: {}", resource, capability); + } + } + Activator.instance().getMetadataDao().saveResource(resource); + } catch (URISyntaxException e) { + logger.warn("Can't save capabilities: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't save capabilities, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't save capabilities", e); + return false; + } + return true; + } + + private boolean saveRequirements(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String uri; + if (parameters.containsKey("uri")) { + uri = ((String[]) parameters.get("uri"))[0]; + } else { + return false; + } + + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + + List requirements = resource.getRequirements(); + int requirLengthBefore = 0; + String name = null; + Requirement requir = null; + String filter = null; + String comment = null; + boolean multiple = false; + boolean extend = false; + boolean optional = false; + Requirement requirBefore = null; + for (int i = 0; i < requirements.size(); i++) { + + if (parameters.containsKey("name_" + (i + 1)) + && parameters.containsKey("filter_" + (i + 1))) { + + name = ((String[]) parameters.get("name_" + (i + 1)))[0]; + filter = ((String[]) parameters.get("filter_" + (i + 1)))[0]; + + if (parameters.containsKey("multiple_" + (i + 1))) { + multiple = ((String[]) parameters.get("multiple_" + (i + 1)))[0].equals("on"); + } + if (parameters.containsKey("optional_" + (i + 1))) { + optional = ((String[]) parameters.get("optional_" + (i + 1)))[0].equals("on"); + } + if (parameters.containsKey("extend_" + (i + 1))) { + extend = ((String[]) parameters.get("extend_" + (i + 1)))[0].equals("on"); + } + if (parameters.containsKey("comment_" + (i + 1))) { + comment = ((String[]) parameters.get("comment_" + (i + 1)))[0]; + } +// requirBefore = requirements[i]; + requirLengthBefore = requirements.size(); + resource.removeRequirement(requirements.get(i)); + if (requirLengthBefore == resource.getRequirements().size()) { +//TODO req.getSession().setAttribute("success", false); +//TODO req.getSession().setAttribute("message", "Cannot change requirement."); + continue; + } + requir = Activator.instance().getMetadataFactory().createRequirement(name); + resource.addRequirement(requir); + try { + logger.warn("OSGi filter is not supported yet with new Metadata API, setting as a directive to track it's usage: {}", filter); + requir.setDirective("filter", filter); + } catch (IllegalArgumentException e) { +//TODO req.getSession().setAttribute("success", false); +//TODO req.getSession().setAttribute("message", "Cannot change requirement."); + resource.removeRequirement(requir); + resource.addRequirement(requirBefore); + continue; + } + requir.setDirective("multiple", String.valueOf(multiple)); + requir.setDirective("optional", String.valueOf(optional)); + requir.setDirective("extend", String.valueOf(extend)); + requir.setDirective("comment", comment); +// resource.addRequirement(requir); + } + } + Activator.instance().getMetadataDao().saveResource(resource); + } catch (URISyntaxException e) { + logger.warn("Can't save requirements: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't save requirements, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't save requirements", e); + return false; + } + return true; + } + + private boolean addCategory(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String category = null; + String uri = null; + if (parameters.containsKey("category") + && parameters.containsKey("uri")) { + category = ((String[]) parameters.get("category"))[0]; + uri = ((String[]) parameters.get("uri"))[0]; + + } else { + return false; + } + + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + Resource resource = findResource(resURI, array); + + + int categoriesLengthBefore = Activator.instance().getMetadataService().getCategories(resource).size(); + Activator.instance().getMetadataService().addCategory(resource, category); + + // check that category was really added + if (categoriesLengthBefore >= Activator.instance().getMetadataService().getCategories(resource).size()) { + req.getSession().setAttribute("success", false); + req.getSession().setAttribute("message", "Cannot add category."); + } + + Activator.instance().getMetadataDao().saveResource(resource); + + } catch (URISyntaxException e) { + logger.warn("Can't add category: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add category, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't add category", e); + return false; + } + return true; + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + cleanSession(req.getSession()); + + req.getSession().removeAttribute("success"); + boolean success = false; + Map parameters = (Map) req.getParameterMap(); + + String type = null; + if (parameters.containsKey("type")) { + type = ((String[]) parameters.get("type"))[0]; + } + if (type != null) { + switch (type) { + case "deleteCompoment": + success = deleteComponent(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot delete component."); + success = true; + } + break; + + case "category": + success = editCategories(req, resp); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot edit category."); + success = true; + } + break; + + case "deleteCategory": + if (!deleteCategory(req, resp, parameters)) { + ResourceServlet.setError(req.getSession(), false, "Cannot delete category."); + success = true; + } + success = editCategories(req, resp); + break; + + case "addCategory": + success = addCategories(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add category."); + success = true; + } + break; + + case "addCapability": + success = addCapabilities(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); + success = true; + } + break; + + case "addCapabilityProperty": + success = addCapabilityProperty(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add capability."); + success = true; + } + break; + + case "capability": + success = editCapabilities(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot edit capabilities."); + success = true; + } + break; + + case "requirement": + success = editRequirements(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot edit requirements."); + success = true; + } + break; + + case "addRequirement": + success = addRequirement(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); + success = true; + } + break; + + case "properties": + success = editProperties(req, resp, parameters); + if (!success) { + ResourceServlet.setError(req.getSession(), false, "Cannot add requirement."); + success = true; + } + break; + default: + success = false; + break; + } + } + if (!success) { + resp.sendError(HttpServletResponse.SC_ACCEPTED, "NOT FOUND OR FAILED TO PROCEED"); + } + } + + private boolean editProperties(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + String uri = req.getParameter("uri"); + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getRequestDispatcher("jsp/forms/propertiesForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't edit properties: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't edit properties, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't edit properties", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + return true; + } + + private boolean addCapabilityProperty(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + String uri = req.getParameter("uri"); + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getSession().setAttribute("capabilityId", req.getParameter("capabilityId")); + req.getRequestDispatcher("jsp/forms/propertyForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't add capability property: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add capability property, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't add capability property", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean addRequirement(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + String uri = req.getParameter("uri"); + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getRequestDispatcher("jsp/forms/requirementForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't add requirement: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add requirement, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't add requirement", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean editRequirements(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + String uri = req.getParameter("uri"); + + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getRequestDispatcher("jsp/forms/requirementsForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't edit requirement: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't edit requirement, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't edit requirement", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + return true; + } + + private boolean addCapabilities(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + String uri = req.getParameter("uri"); + + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getSession().setAttribute("types", Type.values()); + req.getRequestDispatcher("jsp/forms/capabilityForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't add capabilities: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add capabilities, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't add capabilities", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean editCapabilities(HttpServletRequest req, HttpServletResponse resp, Map parameters, boolean b) { + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + String uri = null; + try { + String id = null; + if (b && parameters.containsKey("uri") && req.getAttribute("capabilityId") != null) { + uri = ((String[]) parameters.get("uri"))[0]; + id = (String) req.getAttribute("capabilityId"); + } else if (parameters.containsKey("capabilityId") && parameters.containsKey("uri")) { + uri = ((String[]) parameters.get("uri"))[0]; + id = ((String[]) parameters.get("capabilityId"))[0]; + } else { + return false; + } + Resource resource = findResource(new URI(uri), array); + + req.getSession().setAttribute("resource", resource); + req.getSession().setAttribute("types", Type.values()); + req.getSession().setAttribute("capability", resource.getCapabilities().get(Integer.parseInt(id) - 1)); + req.getSession().setAttribute("capabilityId", id); + req.getRequestDispatcher("jsp/forms/capabilitiesForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't edit capabilities: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't edit capabilities, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't edit capabilities", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean addCategories(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD parameters would be used in the future + + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + String uri = req.getParameter("uri"); + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getRequestDispatcher("jsp/forms/categoryForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't add capabilities: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't add capabilities, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't add capabilities", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean editCategories(HttpServletRequest req, HttpServletResponse resp) { + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + String uri = req.getParameter("uri"); + try { + URI resURI = new URI(uri); + Resource resource = findResource(resURI, array); + req.getSession().setAttribute("resource", resource); + req.getRequestDispatcher("jsp/forms/categoriesForm.jsp").forward(req, resp); // FIXME hardcoded + } catch (URISyntaxException e) { + logger.warn("Can't edit categories: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't edit categories, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't edit categories", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + + return true; + } + + private boolean deleteCategory(HttpServletRequest req, HttpServletResponse resp, Map parameters) { // NOPMD resp would be used in the future + String category = null; + String uri = null; + if (parameters.containsKey("category") + && parameters.containsKey("uri")) { + category = ((String[]) parameters.get("category"))[0]; + uri = ((String[]) parameters.get("uri"))[0]; + + } else { + return false; + } + try { + URI resURI = new URI(uri); + String link = (String) req.getSession().getAttribute("source"); + List array = getResources(req, link); + if (array == null) { + return false; + } + + Resource resource = findResource(resURI, array); + + int categoriesLengthBefore = Activator.instance().getMetadataService().getCategories(resource).size(); + Activator.instance().getMetadataService().removeCategory(resource, category); + +// Zjištění zda kategorie byla odstraněna. + if (categoriesLengthBefore == Activator.instance().getMetadataService().getCategories(resource).size()) { + return false; + } + + Activator.instance().getMetadataDao().saveResource(resource); + + } catch (URISyntaxException e) { + logger.warn("Can't delete category: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't delete category, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't delete category", e); + return false; + } + + return true; + } + + private boolean deleteComponent(HttpServletRequest req, HttpServletResponse resp, final Map parameters) { + String link = null; + String uri = null; + if (parameters.containsKey("link") + && parameters.containsKey("uri")) { + link = ((String[]) parameters.get("link"))[0]; + uri = ((String[]) parameters.get("uri"))[0]; + + } else { + return false; + } + try { + URI fileUri = new URI(uri); + if ("store".equals(link)) { + List array = Activator.instance().getStore(getRepositoryId(req)).getResources(); + Resource found = findResource(fileUri, array); + Activator.instance().getStore(getRepositoryId(req)).remove(found); + } else if ("buffer".equals(link)) { + List array = Activator.instance().getBuffer(req).getResources(); + Resource found = findResource(fileUri, array); + if (!Activator.instance().getBuffer(req).remove(found)) { + logger.warn("Buffer didn't contain removed resource: {}", found); + } + } else { + return false; + } + + req.getRequestDispatcher("resource").forward(req, resp); + + } catch (URISyntaxException e) { + logger.warn("Can't delete component: {}", e.getMessage()); + return false; + } catch (FileNotFoundException e) { + logger.error("Can't delete component, file not found: {}", uri); + return false; + } catch (IOException e) { + logger.error("Can't delete component", e); + return false; + } catch (ServletException e) { + logger.error("Can't forward", e); + return false; + } + return true; + } + + public static Resource findResource(URI uri, List array) throws FileNotFoundException { + Resource found = null; + for (Resource r : array) { + if (Activator.instance().getMetadataService().getUri(r).equals(uri)) { + found = r; + break; + } + } + if (found == null) { + throw new FileNotFoundException(); + } + return found; + } + + private static void cleanSession(HttpSession session) { + session.removeAttribute("resource"); + } + + private List getResources(HttpServletRequest req, String link) { + switch (link) { + case "store": + return Activator.instance().getStore(getRepositoryId(req)).getResources(); + case "buffer": + return Activator.instance().getBuffer(req).getResources(); + default: + return null; + } + } + + private String getRepositoryId(HttpServletRequest req) { + String id = req.getParameter("repositoryId"); + if (id == null) { + Map stores = Activator.instance().getRepositories(); + if (stores.isEmpty()) { + return null; + } + id = stores.keySet().iterator().next(); + logger.trace("Store ID not specified, using the first store found: " + id); + } + return id; + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Helper.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Helper.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Helper.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/Helper.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java similarity index 95% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java index 77aef538..3919ecfd 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/ResourceServlet.java @@ -15,6 +15,8 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import cz.zcu.kiv.crce.metadata.AttributeType; +import cz.zcu.kiv.crce.metadata.impl.SimpleAttributeType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,7 +24,6 @@ import cz.zcu.kiv.crce.compatibility.CompatibilityVersionComparator; import cz.zcu.kiv.crce.metadata.Requirement; import cz.zcu.kiv.crce.metadata.Resource; -import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiIdentity; import cz.zcu.kiv.crce.metadata.type.Version; import cz.zcu.kiv.crce.plugin.Plugin; import cz.zcu.kiv.crce.webui.internal.bean.Category; @@ -34,6 +35,13 @@ public class ResourceServlet extends HttpServlet { private static final Logger logger = LoggerFactory.getLogger(ResourceServlet.class); + // loose coupling with crce-metadata-osgi-bundle module + // see namespace package in crce-metadata-osgi-bundle + // same variables are declared there + private static final String OSG_IDENTITY_NAMESPACE = "osgi.identity"; + private static final AttributeType ATTRIBUTE_SYMBOLIC_NAME = new SimpleAttributeType<>("symbolic-name", String.class); + public static final AttributeType ATTRIBUTE_VERSION = new SimpleAttributeType<>(org.apache.felix.bundlerepository.Resource.VERSION, Version.class); + @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { @@ -230,10 +238,10 @@ private boolean fillSession(String link, HttpServletRequest req, Requirement fil } session.setAttribute("nodata", false); - Requirement resFilter = Activator.instance().getMetadataFactory().createRequirement(NsOsgiIdentity.NAMESPACE__OSGI_IDENTITY); - resFilter.addAttribute(NsOsgiIdentity.ATTRIBUTE__SYMBOLIC_NAME, name); + Requirement resFilter = Activator.instance().getMetadataFactory().createRequirement(OSG_IDENTITY_NAMESPACE); + resFilter.addAttribute(ATTRIBUTE_SYMBOLIC_NAME, name); Version v = new Version(version); - resFilter.addAttribute(NsOsgiIdentity.ATTRIBUTE__VERSION, v); + resFilter.addAttribute(ATTRIBUTE_VERSION, v); List res = Activator.instance().getStore(id).getResources(resFilter, false); if (!res.isEmpty()) { diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java similarity index 97% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java index d0bace62..9c3dabf9 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/RuntimeServlet.java @@ -1,111 +1,111 @@ -package cz.zcu.kiv.crce.webui.internal; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import cz.zcu.kiv.crce.metadata.Resource; -import cz.zcu.kiv.crce.repository.plugins.Executable; - -public class RuntimeServlet extends HttpServlet { - - private static final Logger logger = LoggerFactory.getLogger(RuntimeServlet.class); - - /** - * - */ - private static final long serialVersionUID = 1L; - private String message = null; - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - - if (isStoreBufferAction(req)) { - if (setSessionForForm(req)) { - req.getRequestDispatcher("jsp/forms/testForm.jsp").forward(req, resp); // FIXME hardcoded - } else { - message = "No bundles selected"; - logger.warn(message); - ResourceServlet.setError(req.getSession(), false, message); - req.getRequestDispatcher("jsp/" + req.getSession().getAttribute("source") + ".jsp").forward(req, resp); - } - } - ResourceServlet.setError(req.getSession(), false, "Wrong params!"); - req.getRequestDispatcher("resource").forward(req, resp); - - } - - private boolean setSessionForForm(HttpServletRequest req) { - Resource[] toTest = parseParams(req); - if (toTest == null) { - return false; - } else { - HttpSession session = req.getSession(); - ResourceServlet.cleanSession(session); - session.setAttribute("resources", toTest); - List testPlugins = Activator.instance().getPluginManager().getPlugins(Executable.class); - // Executable is not Serializable so this workaround is needed - List testPluginIds = new ArrayList<>(testPlugins.size()); - for (Executable executable : testPlugins) { - testPluginIds.add(executable.getPluginId()); - } - session.setAttribute("tests", testPluginIds); - return true; - } - } - - private List fetchRightResources(String source, HttpServletRequest req) { - Activator a = Activator.instance(); - if (source.equals("store")) { - return a.getStore(null).getResources(); - } else { - return a.getBuffer(req).getResources(); - } - } - - private Resource[] parseParams(HttpServletRequest req) { - - - String[] uris = req.getParameterValues("check"); - if (uris == null || uris.length == 0) { - return null; - } - List resources = fetchRightResources((String) req.getSession().getAttribute("source"), req); - Resource[] toTest = new Resource[uris.length]; - for (int i = 0; i < uris.length; i++) { - try { - toTest[i] = EditServlet.findResource(new URI(uris[i]), resources); - } catch (FileNotFoundException e) { - message = "File not found! Please try again!"; - return null; - } catch (URISyntaxException e) { - message = "Malformed URI cant make URI from param!"; - return null; - } - - } - return toTest; - } - - private boolean isStoreBufferAction(HttpServletRequest req) { - String source = (String) req.getSession().getAttribute("source"); - logger.debug("Runtime servlet POST source: {}", source); - if ("buffer".equals(source) || "store".equals(source)) { - return true; - } else { - return false; - } - } -} +package cz.zcu.kiv.crce.webui.internal; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.repository.plugins.Executable; + +public class RuntimeServlet extends HttpServlet { + + private static final Logger logger = LoggerFactory.getLogger(RuntimeServlet.class); + + /** + * + */ + private static final long serialVersionUID = 1L; + private String message = null; + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + if (isStoreBufferAction(req)) { + if (setSessionForForm(req)) { + req.getRequestDispatcher("jsp/forms/testForm.jsp").forward(req, resp); // FIXME hardcoded + } else { + message = "No bundles selected"; + logger.warn(message); + ResourceServlet.setError(req.getSession(), false, message); + req.getRequestDispatcher("jsp/" + req.getSession().getAttribute("source") + ".jsp").forward(req, resp); + } + } + ResourceServlet.setError(req.getSession(), false, "Wrong params!"); + req.getRequestDispatcher("resource").forward(req, resp); + + } + + private boolean setSessionForForm(HttpServletRequest req) { + Resource[] toTest = parseParams(req); + if (toTest == null) { + return false; + } else { + HttpSession session = req.getSession(); + ResourceServlet.cleanSession(session); + session.setAttribute("resources", toTest); + List testPlugins = Activator.instance().getPluginManager().getPlugins(Executable.class); + // Executable is not Serializable so this workaround is needed + List testPluginIds = new ArrayList<>(testPlugins.size()); + for (Executable executable : testPlugins) { + testPluginIds.add(executable.getPluginId()); + } + session.setAttribute("tests", testPluginIds); + return true; + } + } + + private List fetchRightResources(String source, HttpServletRequest req) { + Activator a = Activator.instance(); + if (source.equals("store")) { + return a.getStore(null).getResources(); + } else { + return a.getBuffer(req).getResources(); + } + } + + private Resource[] parseParams(HttpServletRequest req) { + + + String[] uris = req.getParameterValues("check"); + if (uris == null || uris.length == 0) { + return null; + } + List resources = fetchRightResources((String) req.getSession().getAttribute("source"), req); + Resource[] toTest = new Resource[uris.length]; + for (int i = 0; i < uris.length; i++) { + try { + toTest[i] = EditServlet.findResource(new URI(uris[i]), resources); + } catch (FileNotFoundException e) { + message = "File not found! Please try again!"; + return null; + } catch (URISyntaxException e) { + message = "Malformed URI cant make URI from param!"; + return null; + } + + } + return toTest; + } + + private boolean isStoreBufferAction(HttpServletRequest req) { + String source = (String) req.getSession().getAttribute("source"); + logger.debug("Runtime servlet POST source: {}", source); + if ("buffer".equals(source) || "store".equals(source)) { + return true; + } else { + return false; + } + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/SessionListener.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/SessionListener.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/SessionListener.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/SessionListener.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/UploadServlet.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/UploadServlet.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/UploadServlet.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/UploadServlet.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/VersionInfo.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/VersionInfo.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/VersionInfo.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/VersionInfo.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/bean/Category.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/bean/Category.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/bean/Category.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/bean/Category.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/Plugin.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/Plugin.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/Plugin.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/Plugin.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java similarity index 95% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java index 47307bb0..2fe19dba 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementAdapter.java @@ -1,85 +1,85 @@ -package cz.zcu.kiv.crce.webui.internal.custom; - -import cz.zcu.kiv.crce.webui.internal.legacy.Capability; -import cz.zcu.kiv.crce.webui.internal.legacy.Requirement; - -public class RequirementAdapter implements Requirement { - - @Override - public String getName() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getFilter() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean isMultiple() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isOptional() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isExtend() { - // TODO Auto-generated method stub - return false; - } - - @Override - public String getComment() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean isWritable() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isSatisfied(Capability capability) { - // TODO Auto-generated method stub - return false; - } - - @Override - public Requirement setFilter(String filter) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Requirement setMultiple(boolean multiple) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Requirement setOptional(boolean optional) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Requirement setExtend(boolean extend) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Requirement setComment(String comment) { - // TODO Auto-generated method stub - return null; - } -} +package cz.zcu.kiv.crce.webui.internal.custom; + +import cz.zcu.kiv.crce.webui.internal.legacy.Capability; +import cz.zcu.kiv.crce.webui.internal.legacy.Requirement; + +public class RequirementAdapter implements Requirement { + + @Override + public String getName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getFilter() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isMultiple() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isOptional() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isExtend() { + // TODO Auto-generated method stub + return false; + } + + @Override + public String getComment() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isWritable() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isSatisfied(Capability capability) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Requirement setFilter(String filter) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement setMultiple(boolean multiple) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement setOptional(boolean optional) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement setExtend(boolean extend) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement setComment(String comment) { + // TODO Auto-generated method stub + return null; + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java similarity index 95% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java index fb7b57bc..10f68e53 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementExt.java @@ -1,21 +1,21 @@ -package cz.zcu.kiv.crce.webui.internal.custom; - -import cz.zcu.kiv.crce.metadata.Requirement; - -public class RequirementExt extends RequirementsWrap { - - private boolean satisfied; - - public RequirementExt(Requirement r) { - super(r); - satisfied = false; - } - - public void setSatisfied(boolean satisfied) { - this.satisfied = satisfied; - } - - public boolean getSatisfied() { - return satisfied; - } -} +package cz.zcu.kiv.crce.webui.internal.custom; + +import cz.zcu.kiv.crce.metadata.Requirement; + +public class RequirementExt extends RequirementsWrap { + + private boolean satisfied; + + public RequirementExt(Requirement r) { + super(r); + satisfied = false; + } + + public void setSatisfied(boolean satisfied) { + this.satisfied = satisfied; + } + + public boolean getSatisfied() { + return satisfied; + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java similarity index 95% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java index a87d1338..2dec5c03 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/RequirementsWrap.java @@ -1,42 +1,42 @@ -package cz.zcu.kiv.crce.webui.internal.custom; - -import cz.zcu.kiv.crce.metadata.Requirement; - -public class RequirementsWrap extends RequirementAdapter { - - protected Requirement requirement; - - public RequirementsWrap(Requirement r) { - this.requirement = r; - } - - @Override - public String getName() { - return requirement.getNamespace(); - } - - @Override - public String getFilter() { - return requirement.getDirective("filter"); // TODO filter is not supported yet - } - - @Override - public boolean isExtend() { - return Boolean.valueOf(requirement.getDirective("extend")); - } - - @Override - public boolean isMultiple() { - return Boolean.valueOf(requirement.getDirective("multiple")); - } - - @Override - public boolean isOptional() { - return Boolean.valueOf(requirement.getDirective("optional")); - } - - @Override - public boolean isWritable() { - return true; - } -} +package cz.zcu.kiv.crce.webui.internal.custom; + +import cz.zcu.kiv.crce.metadata.Requirement; + +public class RequirementsWrap extends RequirementAdapter { + + protected Requirement requirement; + + public RequirementsWrap(Requirement r) { + this.requirement = r; + } + + @Override + public String getName() { + return requirement.getNamespace(); + } + + @Override + public String getFilter() { + return requirement.getDirective("filter"); // TODO filter is not supported yet + } + + @Override + public boolean isExtend() { + return Boolean.valueOf(requirement.getDirective("extend")); + } + + @Override + public boolean isMultiple() { + return Boolean.valueOf(requirement.getDirective("multiple")); + } + + @Override + public boolean isOptional() { + return Boolean.valueOf(requirement.getDirective("optional")); + } + + @Override + public boolean isWritable() { + return true; + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java similarity index 94% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java index 47e4e54d..b7f8f204 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceAdapter.java @@ -1,341 +1,341 @@ -package cz.zcu.kiv.crce.webui.internal.custom; - -import java.net.URI; -import java.net.URL; -import java.util.Map; -import java.util.Set; - -import cz.zcu.kiv.crce.metadata.type.Version; - -import cz.zcu.kiv.crce.webui.internal.legacy.Capability; -import cz.zcu.kiv.crce.webui.internal.legacy.NewProperty; -import cz.zcu.kiv.crce.webui.internal.legacy.Property; -import cz.zcu.kiv.crce.webui.internal.legacy.Requirement; -import cz.zcu.kiv.crce.webui.internal.legacy.Resource; -import cz.zcu.kiv.crce.webui.internal.legacy.Type; - -public class ResourceAdapter implements Resource { - - @Override - public Property[] getProperties() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Property getProperty(String name) { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getPropertyString(String name) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource setProperty(Property property) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource setProperty(String name, String value, Type type) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource setProperty(String name, String string) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource setProperty(String name, Version version) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource setProperty(String name, URL url) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource setProperty(String name, URI uri) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource setProperty(String name, long llong) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource setProperty(String name, double ddouble) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource setProperty(String name, Set values) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Resource unsetProperty(String name) { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getId() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getSymbolicName() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Version getVersion() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getPresentationName() { - // TODO Auto-generated method stub - return null; - } - - @Override - public URI getUri() { - // TODO Auto-generated method stub - return null; - } - - @Override - public URI getRelativeUri() { - // TODO Auto-generated method stub - return null; - } - - @Override - public NewProperty[] getNewProperties() { - // TODO Auto-generated method stub - return null; - } - - @Override - public long getSize() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public String[] getCategories() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Capability[] getCapabilities() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Capability[] getCapabilities(String name) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Requirement[] getRequirements() { - // TODO Auto-generated method stub - return null; - } - - @Override - public Requirement[] getRequirements(String name) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Map getPropertiesMap() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean hasCategory(String category) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean hasCapability(Capability capability) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean hasRequirement(Requirement requirement) { - // TODO Auto-generated method stub - return false; - } - - @Override - public void setSymbolicName(String name) { - // TODO Auto-generated method stub - - } - - @Override - public void setSymbolicName(String name, boolean isStatic) { - // TODO Auto-generated method stub - - } - - @Override - public void setPresentationName(String name) { - // TODO Auto-generated method stub - - } - - @Override - public void setVersion(Version version) { - // TODO Auto-generated method stub - - } - - @Override - public void setVersion(Version version, boolean isStatic) { - // TODO Auto-generated method stub - - } - - @Override - public void setVersion(String version) { - // TODO Auto-generated method stub - - } - - @Override - public void setVersion(String version, boolean isStatic) { - // TODO Auto-generated method stub - - } - - @Override - public void addCategory(String category) { - // TODO Auto-generated method stub - - } - - @Override - public void addCapability(Capability capability) { - // TODO Auto-generated method stub - - } - - @Override - public void addRequirement(Requirement requirement) { - // TODO Auto-generated method stub - - } - - @Override - public Capability createCapability(String name) { - // TODO Auto-generated method stub - return null; - } - - @Override - public Requirement createRequirement(String name) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void unsetCategory(String category) { - // TODO Auto-generated method stub - - } - - @Override - public void unsetCapability(Capability capability) { - // TODO Auto-generated method stub - - } - - @Override - public void unsetRequirement(Requirement requirement) { - // TODO Auto-generated method stub - - } - - @Override - public void setSize(long size) { - // TODO Auto-generated method stub - - } - - @Override - public void setUri(URI uri) { - // TODO Auto-generated method stub - - } - - @Override - public boolean isWritable() { - // TODO Auto-generated method stub - return false; - } - - @Override - public void unsetWritable() { - // TODO Auto-generated method stub - - } - - @Override - public boolean isVersionStatic() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isSymbolicNameStatic() { - // TODO Auto-generated method stub - return false; - } - - @Override - public String asString() { - // TODO Auto-generated method stub - return null; - } - -// @Override -// public Repository getRepository() { -// // TODO Auto-generated method stub -// return null; -// } -// -// @Override -// public void setRepository(WritableRepository repository) { -// // TODO Auto-generated method stub -// } -} +package cz.zcu.kiv.crce.webui.internal.custom; + +import java.net.URI; +import java.net.URL; +import java.util.Map; +import java.util.Set; + +import cz.zcu.kiv.crce.metadata.type.Version; + +import cz.zcu.kiv.crce.webui.internal.legacy.Capability; +import cz.zcu.kiv.crce.webui.internal.legacy.NewProperty; +import cz.zcu.kiv.crce.webui.internal.legacy.Property; +import cz.zcu.kiv.crce.webui.internal.legacy.Requirement; +import cz.zcu.kiv.crce.webui.internal.legacy.Resource; +import cz.zcu.kiv.crce.webui.internal.legacy.Type; + +public class ResourceAdapter implements Resource { + + @Override + public Property[] getProperties() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Property getProperty(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getPropertyString(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(Property property) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, String value, Type type) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, String string) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, Version version) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, URL url) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, URI uri) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, long llong) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, double ddouble) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource setProperty(String name, Set values) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Resource unsetProperty(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getId() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getSymbolicName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Version getVersion() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getPresentationName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public URI getUri() { + // TODO Auto-generated method stub + return null; + } + + @Override + public URI getRelativeUri() { + // TODO Auto-generated method stub + return null; + } + + @Override + public NewProperty[] getNewProperties() { + // TODO Auto-generated method stub + return null; + } + + @Override + public long getSize() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public String[] getCategories() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Capability[] getCapabilities() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Capability[] getCapabilities(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement[] getRequirements() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement[] getRequirements(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map getPropertiesMap() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean hasCategory(String category) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean hasCapability(Capability capability) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean hasRequirement(Requirement requirement) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void setSymbolicName(String name) { + // TODO Auto-generated method stub + + } + + @Override + public void setSymbolicName(String name, boolean isStatic) { + // TODO Auto-generated method stub + + } + + @Override + public void setPresentationName(String name) { + // TODO Auto-generated method stub + + } + + @Override + public void setVersion(Version version) { + // TODO Auto-generated method stub + + } + + @Override + public void setVersion(Version version, boolean isStatic) { + // TODO Auto-generated method stub + + } + + @Override + public void setVersion(String version) { + // TODO Auto-generated method stub + + } + + @Override + public void setVersion(String version, boolean isStatic) { + // TODO Auto-generated method stub + + } + + @Override + public void addCategory(String category) { + // TODO Auto-generated method stub + + } + + @Override + public void addCapability(Capability capability) { + // TODO Auto-generated method stub + + } + + @Override + public void addRequirement(Requirement requirement) { + // TODO Auto-generated method stub + + } + + @Override + public Capability createCapability(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Requirement createRequirement(String name) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void unsetCategory(String category) { + // TODO Auto-generated method stub + + } + + @Override + public void unsetCapability(Capability capability) { + // TODO Auto-generated method stub + + } + + @Override + public void unsetRequirement(Requirement requirement) { + // TODO Auto-generated method stub + + } + + @Override + public void setSize(long size) { + // TODO Auto-generated method stub + + } + + @Override + public void setUri(URI uri) { + // TODO Auto-generated method stub + + } + + @Override + public boolean isWritable() { + // TODO Auto-generated method stub + return false; + } + + @Override + public void unsetWritable() { + // TODO Auto-generated method stub + + } + + @Override + public boolean isVersionStatic() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean isSymbolicNameStatic() { + // TODO Auto-generated method stub + return false; + } + + @Override + public String asString() { + // TODO Auto-generated method stub + return null; + } + +// @Override +// public Repository getRepository() { +// // TODO Auto-generated method stub +// return null; +// } +// +// @Override +// public void setRepository(WritableRepository repository) { +// // TODO Auto-generated method stub +// } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java similarity index 96% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java index c5e991c0..8229291b 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceExt.java @@ -1,45 +1,45 @@ -package cz.zcu.kiv.crce.webui.internal.custom; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import cz.zcu.kiv.crce.metadata.Resource; -import cz.zcu.kiv.crce.metadata.service.MetadataService; - -public class ResourceExt extends ResourceWrap { - - private static final Logger logger = LoggerFactory.getLogger(ResourceExt.class); - - private boolean satisfied; - - public ResourceExt(Resource r, MetadataService metadataService) { - super(r, metadataService); - this.satisfied = true; - } - - public boolean getSatisfied() { - return satisfied; - } - - @Override - public void addRequirement(cz.zcu.kiv.crce.webui.internal.legacy.Requirement requirement) { - satisfied = false; - logger.warn("Adding legacy requirements is not supported yet with new Metadata API: {}", requirement); // TODO fix functionality -// resource.unsetRequirement(requirement); -// RequirementExt rext = new RequirementExt(requirement); -// resource.addRequirement(rext); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof cz.zcu.kiv.crce.webui.internal.legacy.Resource) { - return this.getUri().equals(((cz.zcu.kiv.crce.webui.internal.legacy.Resource) obj).getUri()); - } - return super.equals(obj); - } - - @Override - public int hashCode() { - return resource.hashCode(); - } -} +package cz.zcu.kiv.crce.webui.internal.custom; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cz.zcu.kiv.crce.metadata.Resource; +import cz.zcu.kiv.crce.metadata.service.MetadataService; + +public class ResourceExt extends ResourceWrap { + + private static final Logger logger = LoggerFactory.getLogger(ResourceExt.class); + + private boolean satisfied; + + public ResourceExt(Resource r, MetadataService metadataService) { + super(r, metadataService); + this.satisfied = true; + } + + public boolean getSatisfied() { + return satisfied; + } + + @Override + public void addRequirement(cz.zcu.kiv.crce.webui.internal.legacy.Requirement requirement) { + satisfied = false; + logger.warn("Adding legacy requirements is not supported yet with new Metadata API: {}", requirement); // TODO fix functionality +// resource.unsetRequirement(requirement); +// RequirementExt rext = new RequirementExt(requirement); +// resource.addRequirement(rext); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof cz.zcu.kiv.crce.webui.internal.legacy.Resource) { + return this.getUri().equals(((cz.zcu.kiv.crce.webui.internal.legacy.Resource) obj).getUri()); + } + return super.equals(obj); + } + + @Override + public int hashCode() { + return resource.hashCode(); + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java similarity index 93% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java index 36a43157..88150093 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/custom/ResourceWrap.java @@ -1,482 +1,481 @@ -package cz.zcu.kiv.crce.webui.internal.custom; - -import java.net.URI; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import javax.annotation.Nonnull; - -import cz.zcu.kiv.crce.metadata.type.Version; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import cz.zcu.kiv.crce.metadata.Attribute; -import cz.zcu.kiv.crce.metadata.Capability; -import cz.zcu.kiv.crce.metadata.Requirement; -import cz.zcu.kiv.crce.metadata.Resource; -import cz.zcu.kiv.crce.metadata.osgi.namespace.NsOsgiBundle; -import cz.zcu.kiv.crce.metadata.service.MetadataService; -import cz.zcu.kiv.crce.webui.internal.legacy.NewProperty; -import cz.zcu.kiv.crce.webui.internal.legacy.Property; -import cz.zcu.kiv.crce.webui.internal.legacy.Type; - -abstract class ResourceWrap extends ResourceAdapter { - - private static final Logger logger = LoggerFactory.getLogger(ResourceWrap.class); - - protected Resource resource; - private final MetadataService metadataService; - - protected ResourceWrap(Resource r, MetadataService metadataService) { - this.resource = r; - this.metadataService = metadataService; - } - - @Override - public Property[] getProperties() { - Property[] properties; - List crceCapabilities = Collections.singletonList(metadataService.getIdentity(resource)); - - int crceSize = crceCapabilities.isEmpty() ? 0 : crceCapabilities.get(0).getAttributes().size(); - - properties = new Property[crceSize]; - int i = 0; - if (crceSize > 0) { - for (Attribute atr : crceCapabilities.get(0).getAttributes()) { - properties[i++] = new PropertyImpl(atr); - } - } - return properties; - } - - @Override - public NewProperty[] getNewProperties() { - List newProperties = resource.getProperties(); - NewProperty[] properties = new NewProperty[newProperties.size()]; - int i = 0; - for (cz.zcu.kiv.crce.metadata.Property newProperty : newProperties) { - properties[i++] = new NewPropertyImpl(newProperty); - } - return properties; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Capability[] getCapabilities() { - List capabilities = resource.getCapabilities(); - cz.zcu.kiv.crce.webui.internal.legacy.Capability[] result = new cz.zcu.kiv.crce.webui.internal.legacy.Capability[capabilities.size()]; - int i = 0; - for (Capability capability : capabilities) { - result[i++] = new CapabilityImpl(capability); - } - return result; - } - - @Override - public String[] getCategories() { - return metadataService.getCategories(resource).toArray(new String[0]); - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Requirement[] getRequirements() { - List requirements = resource.getRequirements(); - cz.zcu.kiv.crce.webui.internal.legacy.Requirement[] result = new cz.zcu.kiv.crce.webui.internal.legacy.Requirement[requirements.size()]; - int i = 0; - for (Requirement requirement : requirements) { - result[i++] = new RequirementImpl(requirement); - } - return result; - } - - @Override - public String getSymbolicName() { - String name = "unknown-symbolic-name"; - List capabilities = resource.getCapabilities(NsOsgiBundle.NAMESPACE__OSGI_BUNDLE); - if (!capabilities.isEmpty()) { - name = capabilities.get(0).getAttributeValue(NsOsgiBundle.ATTRIBUTE__SYMBOLIC_NAME); - } - return name; - } - - @Override - public String getId() { - return resource.getId(); - } - - @Override - public Version getVersion() { - Version version = null; - List capabilities = resource.getCapabilities(NsOsgiBundle.NAMESPACE__OSGI_BUNDLE); - if (!capabilities.isEmpty()) { - version = capabilities.get(0).getAttributeValue(NsOsgiBundle.ATTRIBUTE__VERSION); - } - return version; - } - - @Override - public String getPresentationName() { - return metadataService.getPresentationName(resource); - } - - @Override - public URI getUri() { - return metadataService.getUri(resource); - } - - @Override - public URI getRelativeUri() { - return metadataService.getUri(resource); - } - - @Override - public long getSize() { - return metadataService.getSize(resource); - } - - private static class PropertyImpl implements Property { - - private final Attribute attribute; - - public PropertyImpl(Attribute attribute) { - this.attribute = attribute; - } - - @Override - public String getName() { - return attribute.getAttributeType().getName(); - } - - @Override - public Type getType() { - return Type.getValue(attribute.getAttributeType().getType().getSimpleName()); - } - - @Override - public String getValue() { - - Object value = attribute.getValue(); - if (value instanceof Double) { - return String.format("%.3f", value); - } - - return attribute.getStringValue(); - } - - @Override - public Object getConvertedValue() { - return attribute.getValue(); - } - - @Override - public boolean isWritable() { - return true; - } - } - - private static class NewPropertyImpl implements NewProperty { - - private final cz.zcu.kiv.crce.metadata.Property property; - - public NewPropertyImpl(cz.zcu.kiv.crce.metadata.Property property) { - this.property = property; - } - - @Override - public String getName() { - return property.getNamespace(); - } - - @Override - public Property[] getProperties() { - List> attributes = property.getAttributes(); - Property[] properties = new Property[attributes.size()]; - int i = 0; - for (Attribute attribute : attributes) { - properties[i++] = new PropertyImpl(attribute); - } - return properties; - } - - @Override - public Property getProperty(String name) { - Attribute attribute = property.getAttributesMap().get(name); - if (attribute != null) { - return new PropertyImpl(attribute); - } - return null; - } - - @Override - public String getPropertyString(String name) { - Attribute attribute = property.getAttributesMap().get(name); - if (attribute != null) { - return attribute.getStringValue(); - } - return null; - } - - @SuppressWarnings("unchecked") - @Override - public NewProperty setProperty(Property property) { - this.property.setAttribute(property.getName(), (Class) property.getType().getTypeClass(), property.getConvertedValue()); - return this; - } - - @SuppressWarnings("unchecked") - @Override - public NewProperty setProperty(String name, String value, Type type) { - this.property.setAttribute(name, (Class) type.getTypeClass(), Type.propertyValueFromString(type, value)); - return this; - } - - @Override - public NewProperty setProperty(String name, String string) { - this.property.setAttribute(name, String.class, string); - return this; - } - - @Override - public NewProperty setProperty(String name, Version version) { - this.property.setAttribute(name, Version.class, version); - return this; - } - - @Override - public NewProperty setProperty(String name, URL url) { - this.property.setAttribute(name, String.class, url.toString()); - return this; - } - - @Override - public NewProperty setProperty(String name, URI uri) { - this.property.setAttribute(name, String.class, uri.toString()); - return this; - } - - @Override - public NewProperty setProperty(String name, long llong) { - this.property.setAttribute(name, Long.class, llong); - return this; - } - - @Override - public NewProperty setProperty(String name, double ddouble) { - this.property.setAttribute(name, Double.class, ddouble); - return this; - } - - @SuppressWarnings("unchecked") - @Override - public NewProperty setProperty(String name, Set values) { - this.property.setAttribute(name, List.class, new ArrayList<>(values)); - return this; - } - - @Override - public NewProperty unsetProperty(String name) { - this.property.removeAttribute(name); - return this; - } - - } - - private static class CapabilityImpl implements cz.zcu.kiv.crce.webui.internal.legacy.Capability { - - private final Capability capability; - - public CapabilityImpl(Capability capability) { - this.capability = capability; - } - - @Override - public String getName() { - return capability.getNamespace(); - } - - @Override - public NewProperty[] getNewProperties() { - List newProperties = capability.getProperties(); - NewProperty[] properties = new NewProperty[newProperties.size()]; - int i = 0; - for (cz.zcu.kiv.crce.metadata.Property newProperty : newProperties) { - properties[i++] = new NewPropertyImpl(newProperty); - } - return properties; - } - - @Override - public Property[] getProperties() { - List> attributes = capability.getAttributes(); - Property[] properties = new Property[attributes.size()]; - int i = 0; - for (Attribute attribute : attributes) { - properties[i++] = new PropertyImpl(attribute); - } - return properties; - } - - @Override - public Property getProperty(String name) { - Attribute attribute = capability.getAttributesMap().get(name); - if (attribute != null) { - return new PropertyImpl(attribute); - } - return null; - } - - @Override - public String getPropertyString(String name) { - Attribute attribute = capability.getAttributesMap().get(name); - if (attribute != null) { - return attribute.getStringValue(); - } - return null; - } - - @Override - @SuppressWarnings("unchecked") - public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(Property property) { - capability.setAttribute(property.getName(), (Class) property.getType().getTypeClass(), property.getConvertedValue()); - return this; - } - - @Override - @SuppressWarnings("unchecked") - public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, String value, Type type) { - capability.setAttribute(name, (Class) type.getTypeClass(), Type.propertyValueFromString(type, value)); - return this; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, String value) { - capability.setAttribute(name, String.class, value); - return this; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, Version version) { - capability.setAttribute(name, Version.class, version); - return this; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, URL url) { - capability.setAttribute(name, String.class, url.toString()); - return this; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, URI uri) { - capability.setAttribute(name, String.class, uri.toString()); - return this; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, long llong) { - capability.setAttribute(name, Long.class, llong); - return this; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, double ddouble) { - capability.setAttribute(name, Double.class, ddouble); - return this; - } - - @Override - @SuppressWarnings("unchecked") - public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, Set values) { - capability.setAttribute(name, List.class, new ArrayList<>(values)); - return this; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Capability unsetProperty(String name) { - capability.removeAttribute(name); - return this; - } - } - - private static class RequirementImpl implements cz.zcu.kiv.crce.webui.internal.legacy.Requirement { - - private final Requirement requirement; - - public RequirementImpl(@Nonnull Requirement requirement) { - this.requirement = requirement; - } - - @Override - public String getName() { - return requirement.getNamespace(); - } - - @Override - public String getFilter() { - return requirement.getDirective("filter"); - } - - @Override - public boolean isMultiple() { - return Boolean.valueOf(requirement.getDirective("multiple")); - } - - @Override - public boolean isOptional() { - return Boolean.valueOf(requirement.getDirective("optional")); - } - - @Override - public boolean isExtend() { - return Boolean.valueOf(requirement.getDirective("extend")); - } - - @Override - public String getComment() { - return requirement.getDirective("comment"); - } - - @Override - public boolean isWritable() { - return true; - } - - @Override - public boolean isSatisfied(cz.zcu.kiv.crce.webui.internal.legacy.Capability capability) { - logger.warn("Method isSatisfied is not supported by new Metadata API, returning false for Capability: {}, Requirement: {}", capability, requirement); - return false; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setFilter(String filter) { - requirement.setDirective("filter", filter); - return this; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setMultiple(boolean multiple) { - requirement.setDirective("multiple", String.valueOf(multiple)); - return this; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setOptional(boolean optional) { - requirement.setDirective("optional", String.valueOf(optional)); - return this; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setExtend(boolean extend) { - requirement.setDirective("extend", String.valueOf(extend)); - return this; - } - - @Override - public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setComment(String comment) { - requirement.setDirective("comment", String.valueOf(comment)); - return this; - } - } -} +package cz.zcu.kiv.crce.webui.internal.custom; + +import cz.zcu.kiv.crce.metadata.*; +import cz.zcu.kiv.crce.metadata.impl.SimpleAttributeType; +import cz.zcu.kiv.crce.metadata.service.MetadataService; +import cz.zcu.kiv.crce.metadata.type.Version; +import cz.zcu.kiv.crce.webui.internal.legacy.NewProperty; +import cz.zcu.kiv.crce.webui.internal.legacy.Property; +import cz.zcu.kiv.crce.webui.internal.legacy.Type; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Nonnull; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +abstract class ResourceWrap extends ResourceAdapter { + + private static final Logger logger = LoggerFactory.getLogger(ResourceWrap.class); + + // loose coupling with crce-metadata-osgi-bundle module + private static final String OSG_IDENTITY_NAMESPACE = "osgi.identity"; + private static final AttributeType ATTRIBUTE_SYMBOLIC_NAME = new SimpleAttributeType<>("symbolic-name", String.class); + public static final AttributeType ATTRIBUTE_VERSION = new SimpleAttributeType<>(org.apache.felix.bundlerepository.Resource.VERSION, Version.class); + + protected Resource resource; + private final MetadataService metadataService; + + protected ResourceWrap(Resource r, MetadataService metadataService) { + this.resource = r; + this.metadataService = metadataService; + } + + @Override + public Property[] getProperties() { + Property[] properties; + List crceCapabilities = Collections.singletonList(metadataService.getIdentity(resource)); + + int crceSize = crceCapabilities.isEmpty() ? 0 : crceCapabilities.get(0).getAttributes().size(); + + properties = new Property[crceSize]; + int i = 0; + if (crceSize > 0) { + for (Attribute atr : crceCapabilities.get(0).getAttributes()) { + properties[i++] = new PropertyImpl(atr); + } + } + return properties; + } + + @Override + public NewProperty[] getNewProperties() { + List newProperties = resource.getProperties(); + NewProperty[] properties = new NewProperty[newProperties.size()]; + int i = 0; + for (cz.zcu.kiv.crce.metadata.Property newProperty : newProperties) { + properties[i++] = new NewPropertyImpl(newProperty); + } + return properties; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability[] getCapabilities() { + List capabilities = resource.getCapabilities(); + cz.zcu.kiv.crce.webui.internal.legacy.Capability[] result = new cz.zcu.kiv.crce.webui.internal.legacy.Capability[capabilities.size()]; + int i = 0; + for (Capability capability : capabilities) { + result[i++] = new CapabilityImpl(capability); + } + return result; + } + + @Override + public String[] getCategories() { + return metadataService.getCategories(resource).toArray(new String[0]); + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement[] getRequirements() { + List requirements = resource.getRequirements(); + cz.zcu.kiv.crce.webui.internal.legacy.Requirement[] result = new cz.zcu.kiv.crce.webui.internal.legacy.Requirement[requirements.size()]; + int i = 0; + for (Requirement requirement : requirements) { + result[i++] = new RequirementImpl(requirement); + } + return result; + } + + @Override + public String getSymbolicName() { + String name = "unknown-symbolic-name"; + List capabilities = resource.getCapabilities(OSG_IDENTITY_NAMESPACE); + if (!capabilities.isEmpty()) { + name = capabilities.get(0).getAttributeValue(ATTRIBUTE_SYMBOLIC_NAME); + } + return name; + } + + @Override + public String getId() { + return resource.getId(); + } + + @Override + public Version getVersion() { + Version version = null; + List capabilities = resource.getCapabilities(OSG_IDENTITY_NAMESPACE); + if (!capabilities.isEmpty()) { + version = capabilities.get(0).getAttributeValue(ATTRIBUTE_VERSION); + } + return version; + } + + @Override + public String getPresentationName() { + return metadataService.getPresentationName(resource); + } + + @Override + public URI getUri() { + return metadataService.getUri(resource); + } + + @Override + public URI getRelativeUri() { + return metadataService.getUri(resource); + } + + @Override + public long getSize() { + return metadataService.getSize(resource); + } + + private static class PropertyImpl implements Property { + + private final Attribute attribute; + + public PropertyImpl(Attribute attribute) { + this.attribute = attribute; + } + + @Override + public String getName() { + return attribute.getAttributeType().getName(); + } + + @Override + public Type getType() { + return Type.getValue(attribute.getAttributeType().getType().getSimpleName()); + } + + @Override + public String getValue() { + + Object value = attribute.getValue(); + if (value instanceof Double) { + return String.format("%.3f", value); + } + + return attribute.getStringValue(); + } + + @Override + public Object getConvertedValue() { + return attribute.getValue(); + } + + @Override + public boolean isWritable() { + return true; + } + } + + private static class NewPropertyImpl implements NewProperty { + + private final cz.zcu.kiv.crce.metadata.Property property; + + public NewPropertyImpl(cz.zcu.kiv.crce.metadata.Property property) { + this.property = property; + } + + @Override + public String getName() { + return property.getNamespace(); + } + + @Override + public Property[] getProperties() { + List> attributes = property.getAttributes(); + Property[] properties = new Property[attributes.size()]; + int i = 0; + for (Attribute attribute : attributes) { + properties[i++] = new PropertyImpl(attribute); + } + return properties; + } + + @Override + public Property getProperty(String name) { + Attribute attribute = property.getAttributesMap().get(name); + if (attribute != null) { + return new PropertyImpl(attribute); + } + return null; + } + + @Override + public String getPropertyString(String name) { + Attribute attribute = property.getAttributesMap().get(name); + if (attribute != null) { + return attribute.getStringValue(); + } + return null; + } + + @SuppressWarnings("unchecked") + @Override + public NewProperty setProperty(Property property) { + this.property.setAttribute(property.getName(), (Class) property.getType().getTypeClass(), property.getConvertedValue()); + return this; + } + + @SuppressWarnings("unchecked") + @Override + public NewProperty setProperty(String name, String value, Type type) { + this.property.setAttribute(name, (Class) type.getTypeClass(), Type.propertyValueFromString(type, value)); + return this; + } + + @Override + public NewProperty setProperty(String name, String string) { + this.property.setAttribute(name, String.class, string); + return this; + } + + @Override + public NewProperty setProperty(String name, Version version) { + this.property.setAttribute(name, Version.class, version); + return this; + } + + @Override + public NewProperty setProperty(String name, URL url) { + this.property.setAttribute(name, String.class, url.toString()); + return this; + } + + @Override + public NewProperty setProperty(String name, URI uri) { + this.property.setAttribute(name, String.class, uri.toString()); + return this; + } + + @Override + public NewProperty setProperty(String name, long llong) { + this.property.setAttribute(name, Long.class, llong); + return this; + } + + @Override + public NewProperty setProperty(String name, double ddouble) { + this.property.setAttribute(name, Double.class, ddouble); + return this; + } + + @SuppressWarnings("unchecked") + @Override + public NewProperty setProperty(String name, Set values) { + this.property.setAttribute(name, List.class, new ArrayList<>(values)); + return this; + } + + @Override + public NewProperty unsetProperty(String name) { + this.property.removeAttribute(name); + return this; + } + + } + + private static class CapabilityImpl implements cz.zcu.kiv.crce.webui.internal.legacy.Capability { + + private final Capability capability; + + public CapabilityImpl(Capability capability) { + this.capability = capability; + } + + @Override + public String getName() { + return capability.getNamespace(); + } + + @Override + public NewProperty[] getNewProperties() { + List newProperties = capability.getProperties(); + NewProperty[] properties = new NewProperty[newProperties.size()]; + int i = 0; + for (cz.zcu.kiv.crce.metadata.Property newProperty : newProperties) { + properties[i++] = new NewPropertyImpl(newProperty); + } + return properties; + } + + @Override + public Property[] getProperties() { + List> attributes = capability.getAttributes(); + Property[] properties = new Property[attributes.size()]; + int i = 0; + for (Attribute attribute : attributes) { + properties[i++] = new PropertyImpl(attribute); + } + return properties; + } + + @Override + public Property getProperty(String name) { + Attribute attribute = capability.getAttributesMap().get(name); + if (attribute != null) { + return new PropertyImpl(attribute); + } + return null; + } + + @Override + public String getPropertyString(String name) { + Attribute attribute = capability.getAttributesMap().get(name); + if (attribute != null) { + return attribute.getStringValue(); + } + return null; + } + + @Override + @SuppressWarnings("unchecked") + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(Property property) { + capability.setAttribute(property.getName(), (Class) property.getType().getTypeClass(), property.getConvertedValue()); + return this; + } + + @Override + @SuppressWarnings("unchecked") + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, String value, Type type) { + capability.setAttribute(name, (Class) type.getTypeClass(), Type.propertyValueFromString(type, value)); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, String value) { + capability.setAttribute(name, String.class, value); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, Version version) { + capability.setAttribute(name, Version.class, version); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, URL url) { + capability.setAttribute(name, String.class, url.toString()); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, URI uri) { + capability.setAttribute(name, String.class, uri.toString()); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, long llong) { + capability.setAttribute(name, Long.class, llong); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, double ddouble) { + capability.setAttribute(name, Double.class, ddouble); + return this; + } + + @Override + @SuppressWarnings("unchecked") + public cz.zcu.kiv.crce.webui.internal.legacy.Capability setProperty(String name, Set values) { + capability.setAttribute(name, List.class, new ArrayList<>(values)); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Capability unsetProperty(String name) { + capability.removeAttribute(name); + return this; + } + } + + private static class RequirementImpl implements cz.zcu.kiv.crce.webui.internal.legacy.Requirement { + + private final Requirement requirement; + + public RequirementImpl(@Nonnull Requirement requirement) { + this.requirement = requirement; + } + + @Override + public String getName() { + return requirement.getNamespace(); + } + + @Override + public String getFilter() { + return requirement.getDirective("filter"); + } + + @Override + public boolean isMultiple() { + return Boolean.valueOf(requirement.getDirective("multiple")); + } + + @Override + public boolean isOptional() { + return Boolean.valueOf(requirement.getDirective("optional")); + } + + @Override + public boolean isExtend() { + return Boolean.valueOf(requirement.getDirective("extend")); + } + + @Override + public String getComment() { + return requirement.getDirective("comment"); + } + + @Override + public boolean isWritable() { + return true; + } + + @Override + public boolean isSatisfied(cz.zcu.kiv.crce.webui.internal.legacy.Capability capability) { + logger.warn("Method isSatisfied is not supported by new Metadata API, returning false for Capability: {}, Requirement: {}", capability, requirement); + return false; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setFilter(String filter) { + requirement.setDirective("filter", filter); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setMultiple(boolean multiple) { + requirement.setDirective("multiple", String.valueOf(multiple)); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setOptional(boolean optional) { + requirement.setDirective("optional", String.valueOf(optional)); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setExtend(boolean extend) { + requirement.setDirective("extend", String.valueOf(extend)); + return this; + } + + @Override + public cz.zcu.kiv.crce.webui.internal.legacy.Requirement setComment(String comment) { + requirement.setDirective("comment", String.valueOf(comment)); + return this; + } + } +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/filter/CompatibilityAvailabilityFilter.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/filter/CompatibilityAvailabilityFilter.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/filter/CompatibilityAvailabilityFilter.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/filter/CompatibilityAvailabilityFilter.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Capability.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Capability.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Capability.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Capability.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java similarity index 96% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java index 1f2b5e1d..c989b1d2 100644 --- a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java +++ b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/NewProperty.java @@ -1,13 +1,13 @@ -package cz.zcu.kiv.crce.webui.internal.legacy; - -/** - * A property that can be set to a Resource or a Capability. - * - * This Property corresponds to cz.zcu.kiv.crce.metadata.Property - * - * @author Jan Smajcl (smajcl@students.zcu.cz) - */ -public interface NewProperty extends PropertyProvider { - - String getName(); -} +package cz.zcu.kiv.crce.webui.internal.legacy; + +/** + * A property that can be set to a Resource or a Capability. + * + * This Property corresponds to cz.zcu.kiv.crce.metadata.Property + * + * @author Jan Smajcl (smajcl@students.zcu.cz) + */ +public interface NewProperty extends PropertyProvider { + + String getName(); +} diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Property.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Property.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Property.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Property.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/PropertyProvider.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/PropertyProvider.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/PropertyProvider.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/PropertyProvider.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Requirement.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Requirement.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Requirement.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Requirement.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Resource.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Resource.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Resource.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Resource.java diff --git a/modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Type.java b/core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Type.java similarity index 100% rename from modules/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Type.java rename to core/crce-webui/src/main/java/cz/zcu/kiv/crce/webui/internal/legacy/Type.java diff --git a/modules/crce-webui/src/main/webapp/META-INF/MANIFEST.MF b/core/crce-webui/src/main/webapp/META-INF/MANIFEST.MF similarity index 92% rename from modules/crce-webui/src/main/webapp/META-INF/MANIFEST.MF rename to core/crce-webui/src/main/webapp/META-INF/MANIFEST.MF index 5e949512..254272e1 100644 --- a/modules/crce-webui/src/main/webapp/META-INF/MANIFEST.MF +++ b/core/crce-webui/src/main/webapp/META-INF/MANIFEST.MF @@ -1,3 +1,3 @@ -Manifest-Version: 1.0 -Class-Path: - +Manifest-Version: 1.0 +Class-Path: + diff --git a/modules/crce-webui/src/main/webapp/WEB-INF/web.xml b/core/crce-webui/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from modules/crce-webui/src/main/webapp/WEB-INF/web.xml rename to core/crce-webui/src/main/webapp/WEB-INF/web.xml diff --git a/modules/crce-webui/src/main/webapp/crce.png b/core/crce-webui/src/main/webapp/crce.png similarity index 100% rename from modules/crce-webui/src/main/webapp/crce.png rename to core/crce-webui/src/main/webapp/crce.png diff --git a/modules/crce-webui/src/main/webapp/css/styl.css b/core/crce-webui/src/main/webapp/css/styl.css similarity index 94% rename from modules/crce-webui/src/main/webapp/css/styl.css rename to core/crce-webui/src/main/webapp/css/styl.css index 7d9d8879..c19c4c94 100644 --- a/modules/crce-webui/src/main/webapp/css/styl.css +++ b/core/crce-webui/src/main/webapp/css/styl.css @@ -1,612 +1,612 @@ -/* CSS Document */ - -body { - margin: 0 auto; - text-align: center; - font-family: Verdana; -} - -img { - border: 0; -} - -a { - color: #666; -} - -a:hover { - color: #BBB; -} - -p { - padding: 0 0 5px 15px; -} - -h2 { - color: #464A47; - padding: 0 0 0 10px; - font-size: 1.1em; - font-weight: bold; -} - -h3 { - padding: 0 0 0 15px; - font-size: 0.9em; - font-weight: normal; - color: #464A47; -} - -.konec { - clear: both; - width: 0; - visibility: hidden; - height: 0; - font-size: 0; - display: block; -} - -#stranka { - width: 902px; - margin: 0 auto; - margin-top: 20px; - border: 1px solid #AAA; -} - -/*--------------------HLAVICKA----------------------------------------*/ - -#hlavicka { - /*border: 1px solid black;*/ - width: 100%; - background: url('../graphic/hlavicka_bg.png') no-repeat; - text-align: left; - padding: 26px 0px; -} - -#hlavicka .loga_h { - height: 90px; - background: url('../graphic/hlavicka_loga.png') no-repeat; -} - -#hlavicka .logo_img { - float: left; - width: 600px; - color: red; - /*border: 1px solid black;*/ - margin: 10px 0px 0px 12px; -} - -#hlavicka .nazev { - float: left; - width: 600px; - color: #666; - font-weight: bold; - font-size: 1.6em; - /*border: 1px solid black;*/ - margin: 5px 0px 5px 12px; -} - -#hlavicka .vyhledavani { - float: right; - width: 250px; - text-align: right; - border: 1px solid black; - margin: 10px 15px 0 0; -} - -#hlavicka .vyhledavani .text { - width: 150px; - color: #222; - background-color: #EEE; - border: 1px solid #AAA; -} - -#hlavicka .vyhledavani .tlacitko { - width: 55px; - background-color: #666; - border: 1px solid #AAA; - color: #FFF; - font-weight: bold; -} - -#hlavicka .vyhledavani .tlacitko:hover { - color: #222; - background-color: #BBB; - border: 1px solid #AAA; -} - -/*--------------------MENU----------------------------------------*/ - -#menu .vyhledavani_h { - float: right; - width: 450px; - height: 24px; - /*line-height: 20px;*/ - text-align: right; - margin-right: 6px; - -} - -#menu .vyhledavani_h .text { - width: 150px; - height: 16px; - color: #565c59; - background-color: white; - border: 1px solid black; - margin-top: 2px; - -} - -#menu .vyhledavani_h .tlacitko { - width: 25px; - height: 18px; - background-color: #eeeee5; - color: black; - font-family: Verdana; - font-weight: normal; - line-height: 16px; - font-size: 8pt; -} - -#menu .vyhledavani_h .repository_selection { - width: 250px; -} - -#menu { - background: url('../graphic/menu_bg.png') repeat-x; - height: 24px; - -} - -#menu ul { - padding: 0px; - margin: 0px; - float: left; -} - -#menu li { - display: inline; - list-style: none; - padding: 0px 10px; -} - -#menu li a:link, -#menu li a:visited, -#menu li a:active, -#menu li a:hover { - - text-decoration: none; - color: white; - font-weight: bold; - font-size: 0.7em; -} - -#menu li a:hover { - text-decoration: underline; -} - -#menu li a.aktivni { - color: #c0c0a0; -} - -/* Vycisteni menu */ -.vycisteni:after { - display: block; - clear: both; - visibility: hidden; - height: 0; - font-size: 0; - content: ' '; -} - -.vycisteni { - min-height: 1px; -} - -.vycisteni { - display: inline-block; -} - -/* Backslash hack - nemel by to videt IE/Mac \*/ -.vycisteni { - display: block; -} - -/* Konec hacku */ - -/*-------------------------ZPRAVA USPECH NEUSPECH---------------------------------*/ -#zprava { - color: #FFF; - text-align: center; - width: 100%; - margin: 0 auto; - padding: 3px 0px; - font-weight: bold; - font-size: 0.7em; -} - -.uspech { - background-color: #b2c980; -} - -.neuspech { - background-color: #f86965; -} - -/*--------------------TELO----------------------------------------*/ -#telo { - width: 100%; - padding: 10px 0 10px 0; - text-align: left; - margin: 0 auto; - background-color: #EEEEE5; -} - -.pridat { - width: 880px; - margin: 0 auto; - padding: 10px 0 10px 0; -} - -.komponenta { - width: 880px; - margin: 0 auto; - border: 1px solid #AAA; - overflow: hidden; -} - -.komponenta div.nadpis { - /*border: 1px solid black;*/ - background: url('../graphic/heading-bg.png') repeat-x; - height: 21px; - line-height: 21px; - padding: 0px 10px 0px 10px; - font-weight: bold; - font-size: 0.7em; -} - -.komponenta .nadpis .popis { - width: 740px; - height: 21px; - line-height: 21px; - float: left; - border: 0px solid black; -} - -.komponenta .nadpis .popis a { - width: 100%; - /*padding: 0 0 0 10px;*/ - text-decoration: none; - - /*color: #222;*/ - /*border: 1px solid black;*/ -} - -.komponenta .nadpis .popis a:hover { - text-decoration: underline; -} - -.komponenta .nadpis:hover { - /*background-color: #777;*/ -} - -.komponenta .nadpis .popis .sName { - color: #7b847c; - font-style: italic; - margin-left: 10px; - font-size: 0.9em; -} - -.komponenta .nadpis .popis .version { - color: #464a47; - margin-left: 10px; -} - -.komponenta .nadpis .popis .version_obsah { - color: #7b847c; -} - -.komponenta .nadpis .popis .pName { - color: #464a47; - -} - -.komponenta .nadpis .popis .category { - color: #464a47; -} - -.komponenta .nadpis .popis .category_obsah { - color: #7b847c; -} - -.komponenta .nadpis .nabidka { - float: right; - text-align: right; - margin: 2px 0 0 0; - border: 0px solid black; - width: 120px; - height: 19px; - line-height: 19px; -} - -.komponenta .informace { - /*border: 1px solid black;*/ - /*background-color: #EEE;*/ - padding: 5px 10px 5px 10px; - font-size: 0.8em; -} - -.komponenta .polozka { - color: #464a47; - padding-bottom: 10px; -} - -.komponenta .polozka li { - font-size: 0.9em; -} - -.komponenta a.edit, -.edit-addnew { - text-decoration: underline; - font-size: 0.8em; - color: #464a47; -} - -.komponenta a.edit:hover, -.edit-addnew { - text-decoration: none; -} - -.komponenta .polozka .inline { - margin-bottom: 10px; -} - -.komponenta .polozka .inline li { - float: left; - padding-left: 5px; - list-style: none; -} - -.vsechnykategorie { - /*float:left;*/ - margin-bottom: 20px; -} - -.kategorie { - width: 100px; - margin: 5px 2px 2px 2px; - border: 1px solid #AAA; - overflow: hidden; - height: 21px; - line-height: 21px; - padding: 0px 10px 0px 10px; - font-weight: bold; - font-size: 0.7em; -} - -.komponenty .komponenta { - /*width: 760px;*/ -} - -.komponenty .komponenta .nadpis .popis { - /*width: 640px;*/ -} - -/*--------------------POSKYTUJE-------------------------*/ - -.poskytuje { - padding: 5px; - width: 100%; - margin: 0 auto; - -} - -.poskytuje th { - text-align: left; - font-weight: bold; - -} - -.poskytuje .text { - width: 98%; -} - -.poskytuje .jmeno { - -} - -.poskytuje .typ { - width: 90px; -} - -.poskytuje .hodnota { - max-width: 580px; - width: 580px; -} - -/*-------------------------VYZADUJE------------------------------*/ -.vyzaduje { - padding: 10px; - width: 100%; - margin: 0 auto; - font-size: 0.9em; -} - -.komponenta .vyzaduje { - padding: 0px; - width: 830px; -} - -.vyzaduje input { - width: 98%; - margin: 0 auto; -} - -.vyzaduje th { - text-align: left; - font-weight: bold; - /*background: #f5f5f1;*/ -} - -.vyzaduje .text { - width: 98%; - margin: 0 auto; -} - -.vyzaduje .tlacitko { - width: 150px; -} - -.vyzaduje .komentar { - width: 98%; - padding: 0 0 10px 0; - font-size: 0.9em; - font-style: italic; -} - -.vyzaduje .jmeno { - width: 100px; -} - -.vyzaduje .filter { - width: 600px; -} - -.vyzaduje td.req-neuspech { - color: #f86965; -} - -/*---------------ANIMACNI_ODKAZY---------------------------------------*/ -#animacni_odkazy { - width: 880px; - margin: 0 auto; - font-size: 0.8em; - padding-top: 5px; - text-align: right; - border: 0px solid black; - -} - -/*--------------------PATICKA----------------------------------------*/ -#paticka { - padding-top: 3px; - width: 904px; - font-size: 0.6em; - margin: 0 auto; - /*border: 1px solid black;*/ - background-color: #EEE; - color: #333; -} - -/*-------------TLACITKO----------------------------------------------*/ - -.tlacitko { - text-align: center; - /*background-color: #666;*/ - background: #ddddca; - /*border: 1px solid #AAA;*/ - border: 1px solid #c8b8b5; - color: #000; - font-size: 0.8em; - -} - -.tlacitko:hover { - /*color: #222;*/ - background-color: #FFF; -} - -div.tlac { - float: left; - margin-right: 5px; -} - -/*----------------UPLOAD---------------------------------------------*/ - -div.upload { - background-color: #999; - margin-bottom: 10px; - padding: 5px; -} - -table.upload { - - /*width: 880px;*/ - /*margin: 0 auto;*/ - -} - -.upload td { - text-align: left; - width: 100%; -} - -.upload .text { - width: 400px; - color: #222; - background-color: #FFF; - border: 1px solid #AAA; -} - -.upload .tlacitko { - /*width: 200px;*/ - font-size: 0.8em; -} - -/*--------------------FORMULAR----------------------------------------*/ - -.formular { - padding: 10px; - width: 100%; - text-align: left; - -} - -.formular th { - font-weight: bold; - font-size: 0.8em; - color: #464a47; -} - -.formular td { - text-align: left; - margin: 0 auto; -} - -.formular .text { - width: 500px; - color: #222; - background-color: #FFF; - border: 1px solid #AAA; -} - -.formular .chyba { - color: red; - font-weight: bold; - padding: 0 10px 0 10px; -} - -.formular .tlacitko { - margin: 10px 0 0 0; -} - -.formy th { - font-size: 0.8em; - color: #464a47; -} - -.categorie-edit-ul li { - font-size: 0.8em; - color: #464a47; - -} - -/*-----------------EXECUTE_COMMIT-------------------------*/ - -.execute_commit .tlacitko { - margin: 0 0 10px 10px; -} - -/*------------------COMPATIBILITY-------------------------*/ -.pivot { - background-color: #FCFC55; +/* CSS Document */ + +body { + margin: 0 auto; + text-align: center; + font-family: Verdana; +} + +img { + border: 0; +} + +a { + color: #666; +} + +a:hover { + color: #BBB; +} + +p { + padding: 0 0 5px 15px; +} + +h2 { + color: #464A47; + padding: 0 0 0 10px; + font-size: 1.1em; + font-weight: bold; +} + +h3 { + padding: 0 0 0 15px; + font-size: 0.9em; + font-weight: normal; + color: #464A47; +} + +.konec { + clear: both; + width: 0; + visibility: hidden; + height: 0; + font-size: 0; + display: block; +} + +#stranka { + width: 902px; + margin: 0 auto; + margin-top: 20px; + border: 1px solid #AAA; +} + +/*--------------------HLAVICKA----------------------------------------*/ + +#hlavicka { + /*border: 1px solid black;*/ + width: 100%; + background: url('../graphic/hlavicka_bg.png') no-repeat; + text-align: left; + padding: 26px 0px; +} + +#hlavicka .loga_h { + height: 90px; + background: url('../graphic/hlavicka_loga.png') no-repeat; +} + +#hlavicka .logo_img { + float: left; + width: 600px; + color: red; + /*border: 1px solid black;*/ + margin: 10px 0px 0px 12px; +} + +#hlavicka .nazev { + float: left; + width: 600px; + color: #666; + font-weight: bold; + font-size: 1.6em; + /*border: 1px solid black;*/ + margin: 5px 0px 5px 12px; +} + +#hlavicka .vyhledavani { + float: right; + width: 250px; + text-align: right; + border: 1px solid black; + margin: 10px 15px 0 0; +} + +#hlavicka .vyhledavani .text { + width: 150px; + color: #222; + background-color: #EEE; + border: 1px solid #AAA; +} + +#hlavicka .vyhledavani .tlacitko { + width: 55px; + background-color: #666; + border: 1px solid #AAA; + color: #FFF; + font-weight: bold; +} + +#hlavicka .vyhledavani .tlacitko:hover { + color: #222; + background-color: #BBB; + border: 1px solid #AAA; +} + +/*--------------------MENU----------------------------------------*/ + +#menu .vyhledavani_h { + float: right; + width: 450px; + height: 24px; + /*line-height: 20px;*/ + text-align: right; + margin-right: 6px; + +} + +#menu .vyhledavani_h .text { + width: 150px; + height: 16px; + color: #565c59; + background-color: white; + border: 1px solid black; + margin-top: 2px; + +} + +#menu .vyhledavani_h .tlacitko { + width: 25px; + height: 18px; + background-color: #eeeee5; + color: black; + font-family: Verdana; + font-weight: normal; + line-height: 16px; + font-size: 8pt; +} + +#menu .vyhledavani_h .repository_selection { + width: 250px; +} + +#menu { + background: url('../graphic/menu_bg.png') repeat-x; + height: 24px; + +} + +#menu ul { + padding: 0px; + margin: 0px; + float: left; +} + +#menu li { + display: inline; + list-style: none; + padding: 0px 10px; +} + +#menu li a:link, +#menu li a:visited, +#menu li a:active, +#menu li a:hover { + + text-decoration: none; + color: white; + font-weight: bold; + font-size: 0.7em; +} + +#menu li a:hover { + text-decoration: underline; +} + +#menu li a.aktivni { + color: #c0c0a0; +} + +/* Vycisteni menu */ +.vycisteni:after { + display: block; + clear: both; + visibility: hidden; + height: 0; + font-size: 0; + content: ' '; +} + +.vycisteni { + min-height: 1px; +} + +.vycisteni { + display: inline-block; +} + +/* Backslash hack - nemel by to videt IE/Mac \*/ +.vycisteni { + display: block; +} + +/* Konec hacku */ + +/*-------------------------ZPRAVA USPECH NEUSPECH---------------------------------*/ +#zprava { + color: #FFF; + text-align: center; + width: 100%; + margin: 0 auto; + padding: 3px 0px; + font-weight: bold; + font-size: 0.7em; +} + +.uspech { + background-color: #b2c980; +} + +.neuspech { + background-color: #f86965; +} + +/*--------------------TELO----------------------------------------*/ +#telo { + width: 100%; + padding: 10px 0 10px 0; + text-align: left; + margin: 0 auto; + background-color: #EEEEE5; +} + +.pridat { + width: 880px; + margin: 0 auto; + padding: 10px 0 10px 0; +} + +.komponenta { + width: 880px; + margin: 0 auto; + border: 1px solid #AAA; + overflow: hidden; +} + +.komponenta div.nadpis { + /*border: 1px solid black;*/ + background: url('../graphic/heading-bg.png') repeat-x; + height: 21px; + line-height: 21px; + padding: 0px 10px 0px 10px; + font-weight: bold; + font-size: 0.7em; +} + +.komponenta .nadpis .popis { + width: 740px; + height: 21px; + line-height: 21px; + float: left; + border: 0px solid black; +} + +.komponenta .nadpis .popis a { + width: 100%; + /*padding: 0 0 0 10px;*/ + text-decoration: none; + + /*color: #222;*/ + /*border: 1px solid black;*/ +} + +.komponenta .nadpis .popis a:hover { + text-decoration: underline; +} + +.komponenta .nadpis:hover { + /*background-color: #777;*/ +} + +.komponenta .nadpis .popis .sName { + color: #7b847c; + font-style: italic; + margin-left: 10px; + font-size: 0.9em; +} + +.komponenta .nadpis .popis .version { + color: #464a47; + margin-left: 10px; +} + +.komponenta .nadpis .popis .version_obsah { + color: #7b847c; +} + +.komponenta .nadpis .popis .pName { + color: #464a47; + +} + +.komponenta .nadpis .popis .category { + color: #464a47; +} + +.komponenta .nadpis .popis .category_obsah { + color: #7b847c; +} + +.komponenta .nadpis .nabidka { + float: right; + text-align: right; + margin: 2px 0 0 0; + border: 0px solid black; + width: 120px; + height: 19px; + line-height: 19px; +} + +.komponenta .informace { + /*border: 1px solid black;*/ + /*background-color: #EEE;*/ + padding: 5px 10px 5px 10px; + font-size: 0.8em; +} + +.komponenta .polozka { + color: #464a47; + padding-bottom: 10px; +} + +.komponenta .polozka li { + font-size: 0.9em; +} + +.komponenta a.edit, +.edit-addnew { + text-decoration: underline; + font-size: 0.8em; + color: #464a47; +} + +.komponenta a.edit:hover, +.edit-addnew { + text-decoration: none; +} + +.komponenta .polozka .inline { + margin-bottom: 10px; +} + +.komponenta .polozka .inline li { + float: left; + padding-left: 5px; + list-style: none; +} + +.vsechnykategorie { + /*float:left;*/ + margin-bottom: 20px; +} + +.kategorie { + width: 100px; + margin: 5px 2px 2px 2px; + border: 1px solid #AAA; + overflow: hidden; + height: 21px; + line-height: 21px; + padding: 0px 10px 0px 10px; + font-weight: bold; + font-size: 0.7em; +} + +.komponenty .komponenta { + /*width: 760px;*/ +} + +.komponenty .komponenta .nadpis .popis { + /*width: 640px;*/ +} + +/*--------------------POSKYTUJE-------------------------*/ + +.poskytuje { + padding: 5px; + width: 100%; + margin: 0 auto; + +} + +.poskytuje th { + text-align: left; + font-weight: bold; + +} + +.poskytuje .text { + width: 98%; +} + +.poskytuje .jmeno { + +} + +.poskytuje .typ { + width: 90px; +} + +.poskytuje .hodnota { + max-width: 580px; + width: 580px; +} + +/*-------------------------VYZADUJE------------------------------*/ +.vyzaduje { + padding: 10px; + width: 100%; + margin: 0 auto; + font-size: 0.9em; +} + +.komponenta .vyzaduje { + padding: 0px; + width: 830px; +} + +.vyzaduje input { + width: 98%; + margin: 0 auto; +} + +.vyzaduje th { + text-align: left; + font-weight: bold; + /*background: #f5f5f1;*/ +} + +.vyzaduje .text { + width: 98%; + margin: 0 auto; +} + +.vyzaduje .tlacitko { + width: 150px; +} + +.vyzaduje .komentar { + width: 98%; + padding: 0 0 10px 0; + font-size: 0.9em; + font-style: italic; +} + +.vyzaduje .jmeno { + width: 100px; +} + +.vyzaduje .filter { + width: 600px; +} + +.vyzaduje td.req-neuspech { + color: #f86965; +} + +/*---------------ANIMACNI_ODKAZY---------------------------------------*/ +#animacni_odkazy { + width: 880px; + margin: 0 auto; + font-size: 0.8em; + padding-top: 5px; + text-align: right; + border: 0px solid black; + +} + +/*--------------------PATICKA----------------------------------------*/ +#paticka { + padding-top: 3px; + width: 904px; + font-size: 0.6em; + margin: 0 auto; + /*border: 1px solid black;*/ + background-color: #EEE; + color: #333; +} + +/*-------------TLACITKO----------------------------------------------*/ + +.tlacitko { + text-align: center; + /*background-color: #666;*/ + background: #ddddca; + /*border: 1px solid #AAA;*/ + border: 1px solid #c8b8b5; + color: #000; + font-size: 0.8em; + +} + +.tlacitko:hover { + /*color: #222;*/ + background-color: #FFF; +} + +div.tlac { + float: left; + margin-right: 5px; +} + +/*----------------UPLOAD---------------------------------------------*/ + +div.upload { + background-color: #999; + margin-bottom: 10px; + padding: 5px; +} + +table.upload { + + /*width: 880px;*/ + /*margin: 0 auto;*/ + +} + +.upload td { + text-align: left; + width: 100%; +} + +.upload .text { + width: 400px; + color: #222; + background-color: #FFF; + border: 1px solid #AAA; +} + +.upload .tlacitko { + /*width: 200px;*/ + font-size: 0.8em; +} + +/*--------------------FORMULAR----------------------------------------*/ + +.formular { + padding: 10px; + width: 100%; + text-align: left; + +} + +.formular th { + font-weight: bold; + font-size: 0.8em; + color: #464a47; +} + +.formular td { + text-align: left; + margin: 0 auto; +} + +.formular .text { + width: 500px; + color: #222; + background-color: #FFF; + border: 1px solid #AAA; +} + +.formular .chyba { + color: red; + font-weight: bold; + padding: 0 10px 0 10px; +} + +.formular .tlacitko { + margin: 10px 0 0 0; +} + +.formy th { + font-size: 0.8em; + color: #464a47; +} + +.categorie-edit-ul li { + font-size: 0.8em; + color: #464a47; + +} + +/*-----------------EXECUTE_COMMIT-------------------------*/ + +.execute_commit .tlacitko { + margin: 0 0 10px 10px; +} + +/*------------------COMPATIBILITY-------------------------*/ +.pivot { + background-color: #FCFC55; } \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/graphic/add.png b/core/crce-webui/src/main/webapp/graphic/add.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/add.png rename to core/crce-webui/src/main/webapp/graphic/add.png diff --git a/modules/crce-webui/src/main/webapp/graphic/check.png b/core/crce-webui/src/main/webapp/graphic/check.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/check.png rename to core/crce-webui/src/main/webapp/graphic/check.png diff --git a/modules/crce-webui/src/main/webapp/graphic/commit.png b/core/crce-webui/src/main/webapp/graphic/commit.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/commit.png rename to core/crce-webui/src/main/webapp/graphic/commit.png diff --git a/modules/crce-webui/src/main/webapp/graphic/crce.png b/core/crce-webui/src/main/webapp/graphic/crce.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/crce.png rename to core/crce-webui/src/main/webapp/graphic/crce.png diff --git a/modules/crce-webui/src/main/webapp/graphic/del.png b/core/crce-webui/src/main/webapp/graphic/del.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/del.png rename to core/crce-webui/src/main/webapp/graphic/del.png diff --git a/modules/crce-webui/src/main/webapp/graphic/edit.png b/core/crce-webui/src/main/webapp/graphic/edit.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/edit.png rename to core/crce-webui/src/main/webapp/graphic/edit.png diff --git a/modules/crce-webui/src/main/webapp/graphic/heading-bg.png b/core/crce-webui/src/main/webapp/graphic/heading-bg.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/heading-bg.png rename to core/crce-webui/src/main/webapp/graphic/heading-bg.png diff --git a/modules/crce-webui/src/main/webapp/graphic/hlavicka_bg.png b/core/crce-webui/src/main/webapp/graphic/hlavicka_bg.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/hlavicka_bg.png rename to core/crce-webui/src/main/webapp/graphic/hlavicka_bg.png diff --git a/modules/crce-webui/src/main/webapp/graphic/hlavicka_loga.png b/core/crce-webui/src/main/webapp/graphic/hlavicka_loga.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/hlavicka_loga.png rename to core/crce-webui/src/main/webapp/graphic/hlavicka_loga.png diff --git a/modules/crce-webui/src/main/webapp/graphic/logo.png b/core/crce-webui/src/main/webapp/graphic/logo.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/logo.png rename to core/crce-webui/src/main/webapp/graphic/logo.png diff --git a/modules/crce-webui/src/main/webapp/graphic/menu_bg.png b/core/crce-webui/src/main/webapp/graphic/menu_bg.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/menu_bg.png rename to core/crce-webui/src/main/webapp/graphic/menu_bg.png diff --git a/modules/crce-webui/src/main/webapp/graphic/save.png b/core/crce-webui/src/main/webapp/graphic/save.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/save.png rename to core/crce-webui/src/main/webapp/graphic/save.png diff --git a/modules/crce-webui/src/main/webapp/graphic/zoom.png b/core/crce-webui/src/main/webapp/graphic/zoom.png similarity index 100% rename from modules/crce-webui/src/main/webapp/graphic/zoom.png rename to core/crce-webui/src/main/webapp/graphic/zoom.png diff --git a/modules/crce-webui/src/main/webapp/index.jsp b/core/crce-webui/src/main/webapp/index.jsp similarity index 95% rename from modules/crce-webui/src/main/webapp/index.jsp rename to core/crce-webui/src/main/webapp/index.jsp index d2d4d35d..778705d7 100644 --- a/modules/crce-webui/src/main/webapp/index.jsp +++ b/core/crce-webui/src/main/webapp/index.jsp @@ -4,19 +4,15 @@ Author : kalwi --%> -<%@page import="cz.zcu.kiv.crce.metadata.Attribute"%> -<%@page import="java.util.List"%> +<%@page import="cz.zcu.kiv.crce.metadata.*"%> +<%@page import="cz.zcu.kiv.crce.plugin.Plugin"%> <% response.sendRedirect("resource"); %> -<%@page import="cz.zcu.kiv.crce.plugin.Plugin"%> -<%@page import="cz.zcu.kiv.crce.metadata.Requirement"%> -<%@page import="cz.zcu.kiv.crce.metadata.Property"%> -<%@page import="cz.zcu.kiv.crce.metadata.Capability"%> <%@page import="cz.zcu.kiv.crce.repository.Buffer"%> <%@page import="cz.zcu.kiv.crce.webui.internal.Activator"%> -<%@page import="cz.zcu.kiv.crce.metadata.Resource"%> +<%@page import="java.util.List"%> <%@page contentType="text/html" pageEncoding="UTF-8"%> diff --git a/modules/crce-webui/src/main/webapp/js/jquery-1.5.1.js b/core/crce-webui/src/main/webapp/js/jquery-1.5.1.js similarity index 100% rename from modules/crce-webui/src/main/webapp/js/jquery-1.5.1.js rename to core/crce-webui/src/main/webapp/js/jquery-1.5.1.js diff --git a/modules/crce-webui/src/main/webapp/js/plus_minus_form.js b/core/crce-webui/src/main/webapp/js/plus_minus_form.js similarity index 96% rename from modules/crce-webui/src/main/webapp/js/plus_minus_form.js rename to core/crce-webui/src/main/webapp/js/plus_minus_form.js index 535f5fdf..53d96e75 100644 --- a/modules/crce-webui/src/main/webapp/js/plus_minus_form.js +++ b/core/crce-webui/src/main/webapp/js/plus_minus_form.js @@ -1,49 +1,49 @@ -var element_id = 2; - -function plus() { - var x = document.getElementById('options'); - - var name = document.createElement('input'); - name.setAttribute('name', 'name_' + element_id ); - name.setAttribute('type', 'text'); - - var value = document.createElement('input'); - value.setAttribute('name', 'value_' + element_id ); - value.setAttribute('class', 'text'); - value.setAttribute('type', 'text'); - - var nameText = document.createTextNode('Name: '); - var valueText = document.createTextNode('Value: '); - - var tr = document.createElement('tr'); - tr.setAttribute('id', 'option_' + element_id); - var thName = document.createElement('th'); - var thValue = document.createElement('th'); - var tdName = document.createElement('td'); - var tdValue = document.createElement('td'); - - thName.appendChild(nameText); - tdName.appendChild(name); - thValue.appendChild(valueText); - tdValue.appendChild(value); - - tr.appendChild(thName); - tr.appendChild(tdName); - tr.appendChild(thValue); - tr.appendChild(tdValue); - - x.appendChild(tr); - - element_id = element_id + 1; -} - -function minus(){ - if( element_id <= 2 ) - return; - - element_id = element_id - 1; - var d = document.getElementById('options'); - var olddiv = document.getElementById( 'option_' + element_id ); - - d.removeChild(olddiv); +var element_id = 2; + +function plus() { + var x = document.getElementById('options'); + + var name = document.createElement('input'); + name.setAttribute('name', 'name_' + element_id ); + name.setAttribute('type', 'text'); + + var value = document.createElement('input'); + value.setAttribute('name', 'value_' + element_id ); + value.setAttribute('class', 'text'); + value.setAttribute('type', 'text'); + + var nameText = document.createTextNode('Name: '); + var valueText = document.createTextNode('Value: '); + + var tr = document.createElement('tr'); + tr.setAttribute('id', 'option_' + element_id); + var thName = document.createElement('th'); + var thValue = document.createElement('th'); + var tdName = document.createElement('td'); + var tdValue = document.createElement('td'); + + thName.appendChild(nameText); + tdName.appendChild(name); + thValue.appendChild(valueText); + tdValue.appendChild(value); + + tr.appendChild(thName); + tr.appendChild(tdName); + tr.appendChild(thValue); + tr.appendChild(tdValue); + + x.appendChild(tr); + + element_id = element_id + 1; +} + +function minus(){ + if( element_id <= 2 ) + return; + + element_id = element_id - 1; + var d = document.getElementById('options'); + var olddiv = document.getElementById( 'option_' + element_id ); + + d.removeChild(olddiv); } \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/js/slide.js b/core/crce-webui/src/main/webapp/js/slide.js similarity index 96% rename from modules/crce-webui/src/main/webapp/js/slide.js rename to core/crce-webui/src/main/webapp/js/slide.js index b9843914..dda091b8 100644 --- a/modules/crce-webui/src/main/webapp/js/slide.js +++ b/core/crce-webui/src/main/webapp/js/slide.js @@ -1,19 +1,19 @@ -$(document).ready(function(){ - $(".informace").hide(); - - $(".popis").click(function(){ - $(this).parent().next(".informace").slideToggle(500) - return false; - }); - - $(".rozbalit").click(function(){ - $(".informace").slideDown(500) - return false; - }); - - $(".sbalit").click(function(){ - $(".informace").slideUp(500) - return false; - }); - +$(document).ready(function(){ + $(".informace").hide(); + + $(".popis").click(function(){ + $(this).parent().next(".informace").slideToggle(500) + return false; + }); + + $(".rozbalit").click(function(){ + $(".informace").slideDown(500) + return false; + }); + + $(".sbalit").click(function(){ + $(".informace").slideUp(500) + return false; + }); + }); \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/buffer.jsp b/core/crce-webui/src/main/webapp/jsp/buffer.jsp similarity index 100% rename from modules/crce-webui/src/main/webapp/jsp/buffer.jsp rename to core/crce-webui/src/main/webapp/jsp/buffer.jsp diff --git a/modules/crce-webui/src/main/webapp/jsp/compatibility.jsp b/core/crce-webui/src/main/webapp/jsp/compatibility.jsp similarity index 100% rename from modules/crce-webui/src/main/webapp/jsp/compatibility.jsp rename to core/crce-webui/src/main/webapp/jsp/compatibility.jsp index 48e91628..8a33ad76 100644 --- a/modules/crce-webui/src/main/webapp/jsp/compatibility.jsp +++ b/core/crce-webui/src/main/webapp/jsp/compatibility.jsp @@ -1,5 +1,5 @@ -<%@ page import="cz.zcu.kiv.typescmp.Difference" %> <%@ page import="cz.zcu.kiv.crce.compatibility.Compatibility" %> +<%@ page import="cz.zcu.kiv.typescmp.Difference" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> diff --git a/modules/crce-webui/src/main/webapp/jsp/forms/capabilitiesForm.jsp b/core/crce-webui/src/main/webapp/jsp/forms/capabilitiesForm.jsp similarity index 97% rename from modules/crce-webui/src/main/webapp/jsp/forms/capabilitiesForm.jsp rename to core/crce-webui/src/main/webapp/jsp/forms/capabilitiesForm.jsp index 7bf9d7f5..d89513e4 100644 --- a/modules/crce-webui/src/main/webapp/jsp/forms/capabilitiesForm.jsp +++ b/core/crce-webui/src/main/webapp/jsp/forms/capabilitiesForm.jsp @@ -1,47 +1,47 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - -
- -

Capabilities form

- -

Resource: ${resource.presentationName} - ${resource.version}

-

Capability: ${capability.name}

- - -

- [add new property]
-

- -
- - - - - - - - - - - - - - -
NameTypeValue
- - -
-
- - -
- +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + +
+ +

Capabilities form

+ +

Resource: ${resource.presentationName} - ${resource.version}

+

Capability: ${capability.name}

+ + +

+ [add new property]
+

+ +
+ + + + + + + + + + + + + + +
NameTypeValue
+ + +
+
+ + +
+ \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/forms/capabilityForm.jsp b/core/crce-webui/src/main/webapp/jsp/forms/capabilityForm.jsp similarity index 96% rename from modules/crce-webui/src/main/webapp/jsp/forms/capabilityForm.jsp rename to core/crce-webui/src/main/webapp/jsp/forms/capabilityForm.jsp index b4f589b1..8cc6df49 100644 --- a/modules/crce-webui/src/main/webapp/jsp/forms/capabilityForm.jsp +++ b/core/crce-webui/src/main/webapp/jsp/forms/capabilityForm.jsp @@ -1,31 +1,31 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - -
- -

Add new capability

- -

Resource: ${resource.presentationName} - ${resource.version}

- -
- - - - - - - - - - - -
Capability name:${capabilityError}
-
- - -
- +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + +
+ +

Add new capability

+ +

Resource: ${resource.presentationName} - ${resource.version}

+ +
+ + + + + + + + + + + +
Capability name:${capabilityError}
+
+ + +
+ \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/forms/categoriesForm.jsp b/core/crce-webui/src/main/webapp/jsp/forms/categoriesForm.jsp similarity index 97% rename from modules/crce-webui/src/main/webapp/jsp/forms/categoriesForm.jsp rename to core/crce-webui/src/main/webapp/jsp/forms/categoriesForm.jsp index 05846f97..78c82ee7 100644 --- a/modules/crce-webui/src/main/webapp/jsp/forms/categoriesForm.jsp +++ b/core/crce-webui/src/main/webapp/jsp/forms/categoriesForm.jsp @@ -1,25 +1,25 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - -
- -

Existing categories

- -

Resource: ${resource.presentationName} - ${resource.version}

- - - -

- [add new category]
-

- -
- +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + +
+ +

Existing categories

+ +

Resource: ${resource.presentationName} - ${resource.version}

+ + + +

+ [add new category]
+

+ +
+ \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/forms/categoryForm.jsp b/core/crce-webui/src/main/webapp/jsp/forms/categoryForm.jsp similarity index 96% rename from modules/crce-webui/src/main/webapp/jsp/forms/categoryForm.jsp rename to core/crce-webui/src/main/webapp/jsp/forms/categoryForm.jsp index 54247ce4..4c0d7028 100644 --- a/modules/crce-webui/src/main/webapp/jsp/forms/categoryForm.jsp +++ b/core/crce-webui/src/main/webapp/jsp/forms/categoryForm.jsp @@ -1,31 +1,31 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - -
- -

Add new category

- -

Resource: ${resource.presentationName} - ${resource.version}

- -
- - - - - - - - - - - - -
Category name:${categoryError}
-
- -
- +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + +
+ +

Add new category

+ +

Resource: ${resource.presentationName} - ${resource.version}

+ +
+ + + + + + + + + + + + +
Category name:${categoryError}
+
+ +
+ \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/forms/pluginForm.jsp b/core/crce-webui/src/main/webapp/jsp/forms/pluginForm.jsp similarity index 96% rename from modules/crce-webui/src/main/webapp/jsp/forms/pluginForm.jsp rename to core/crce-webui/src/main/webapp/jsp/forms/pluginForm.jsp index 52a5c48e..fc150f19 100644 --- a/modules/crce-webui/src/main/webapp/jsp/forms/pluginForm.jsp +++ b/core/crce-webui/src/main/webapp/jsp/forms/pluginForm.jsp @@ -1,35 +1,35 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - -
- -

Plugin form

- -

Plugin: ${plugin.pluginId}

- -
- - - - - - - - - - - - - - - - -
Priority:${priorityError}
Keywords:${keywordsError}
-
- -
- +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + +
+ +

Plugin form

+ +

Plugin: ${plugin.pluginId}

+ +
+ + + + + + + + + + + + + + + + +
Priority:${priorityError}
Keywords:${keywordsError}
+
+ +
+ \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/forms/propertiesForm.jsp b/core/crce-webui/src/main/webapp/jsp/forms/propertiesForm.jsp similarity index 97% rename from modules/crce-webui/src/main/webapp/jsp/forms/propertiesForm.jsp rename to core/crce-webui/src/main/webapp/jsp/forms/propertiesForm.jsp index aae302b8..86fa9856 100644 --- a/modules/crce-webui/src/main/webapp/jsp/forms/propertiesForm.jsp +++ b/core/crce-webui/src/main/webapp/jsp/forms/propertiesForm.jsp @@ -1,58 +1,58 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - -
- -

Properties form

- -

Resource: ${resource.presentationName} - ${resource.version}

- -
- - - - - - - - - - - - - - - - - - - - - -
Symbolic name:${symbolicNameError}
Version:${versionError}
-
- -
- +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + +
+ +

Properties form

+ +

Resource: ${resource.presentationName} - ${resource.version}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
Symbolic name:${symbolicNameError}
Version:${versionError}
+
+ +
+ \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/forms/propertyForm.jsp b/core/crce-webui/src/main/webapp/jsp/forms/propertyForm.jsp similarity index 97% rename from modules/crce-webui/src/main/webapp/jsp/forms/propertyForm.jsp rename to core/crce-webui/src/main/webapp/jsp/forms/propertyForm.jsp index 1f9b03aa..83a6b418 100644 --- a/modules/crce-webui/src/main/webapp/jsp/forms/propertyForm.jsp +++ b/core/crce-webui/src/main/webapp/jsp/forms/propertyForm.jsp @@ -1,49 +1,49 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - -
- -

Add new property

- -

Resource: ${resource.presentationName} - ${resource.version}

- -
- - - - - - - - - - - - - - - - - - - - - - - -
Name:${nameError}
Type: - - - ${typeError}
Value:${valueError}
-
- -
- +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + +
+ +

Add new property

+ +

Resource: ${resource.presentationName} - ${resource.version}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
Name:${nameError}
Type: + + + ${typeError}
Value:${valueError}
+
+ +
+ \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/forms/requirementForm.jsp b/core/crce-webui/src/main/webapp/jsp/forms/requirementForm.jsp similarity index 97% rename from modules/crce-webui/src/main/webapp/jsp/forms/requirementForm.jsp rename to core/crce-webui/src/main/webapp/jsp/forms/requirementForm.jsp index 5308fa02..16b74252 100644 --- a/modules/crce-webui/src/main/webapp/jsp/forms/requirementForm.jsp +++ b/core/crce-webui/src/main/webapp/jsp/forms/requirementForm.jsp @@ -1,56 +1,56 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - -
- -

Add new requirement

- -

Resource: ${resource.presentationName} - ${resource.version}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name:${nameError}
Filter:${filterError}
Comment:${commentError}
Multiple:checked="checked" />${multipleError}
Optional:checked="checked" />${optionalError}
Extend:checked="checked" />${extendError}
-
- -
- +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + +
+ +

Add new requirement

+ +

Resource: ${resource.presentationName} - ${resource.version}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name:${nameError}
Filter:${filterError}
Comment:${commentError}
Multiple:checked="checked" />${multipleError}
Optional:checked="checked" />${optionalError}
Extend:checked="checked" />${extendError}
+
+ +
+ \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/forms/requirementsForm.jsp b/core/crce-webui/src/main/webapp/jsp/forms/requirementsForm.jsp similarity index 98% rename from modules/crce-webui/src/main/webapp/jsp/forms/requirementsForm.jsp rename to core/crce-webui/src/main/webapp/jsp/forms/requirementsForm.jsp index 6921279f..09c993f9 100644 --- a/modules/crce-webui/src/main/webapp/jsp/forms/requirementsForm.jsp +++ b/core/crce-webui/src/main/webapp/jsp/forms/requirementsForm.jsp @@ -1,40 +1,40 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - -
- -

Requirements form

- -

Resource: ${resource.presentationName} - ${resource.version}

- -

- [add new requirement]
-

- -
- - - - - -
- - - - - - - - - - - -
NameFilterMultipleOptionalExtend
Comment
checked="checked" />checked="checked" />checked="checked" />
-
- -
- +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + +
+ +

Requirements form

+ +

Resource: ${resource.presentationName} - ${resource.version}

+ +

+ [add new requirement]
+

+ +
+ + + + + +
+ + + + + + + + + + + +
NameFilterMultipleOptionalExtend
Comment
checked="checked" />checked="checked" />checked="checked" />
+
+ +
+ \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/forms/testForm.jsp b/core/crce-webui/src/main/webapp/jsp/forms/testForm.jsp similarity index 96% rename from modules/crce-webui/src/main/webapp/jsp/forms/testForm.jsp rename to core/crce-webui/src/main/webapp/jsp/forms/testForm.jsp index d1cbfaa1..4339f5a1 100644 --- a/modules/crce-webui/src/main/webapp/jsp/forms/testForm.jsp +++ b/core/crce-webui/src/main/webapp/jsp/forms/testForm.jsp @@ -1,66 +1,66 @@ -<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - - - - -
- -

Test form

- - - -

Resources

-
    - -
  • ${resource.symbolicName}
  • -
    -
-
- -

No resources selected!

-
-
- - - -

Test plugins

-
- - - - - - - -
${test}
- -

Test parameters:

- - - - - - - -
Name: Value:
- -

- add Add parameter - delete Remove parameter -

- -

- -

- -
-
- -

No test plugins enabled!

-
-
- -
- +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + + + + +
+ +

Test form

+ + + +

Resources

+
    + +
  • ${resource.symbolicName}
  • +
    +
+
+ +

No resources selected!

+
+
+ + + +

Test plugins

+
+ + + + + + + +
${test}
+ +

Test parameters:

+ + + + + + + +
Name: Value:
+ +

+ add Add parameter + delete Remove parameter +

+ +

+ +

+ +
+
+ +

No test plugins enabled!

+
+
+ +
+ \ No newline at end of file diff --git a/modules/crce-webui/src/main/webapp/jsp/include/footer.jsp b/core/crce-webui/src/main/webapp/jsp/include/footer.jsp similarity index 97% rename from modules/crce-webui/src/main/webapp/jsp/include/footer.jsp rename to core/crce-webui/src/main/webapp/jsp/include/footer.jsp index d777bcf4..49d96735 100644 --- a/modules/crce-webui/src/main/webapp/jsp/include/footer.jsp +++ b/core/crce-webui/src/main/webapp/jsp/include/footer.jsp @@ -1,11 +1,11 @@ -<%@ page import="cz.zcu.kiv.crce.webui.internal.VersionInfo" %> - -<% VersionInfo versionInfo = VersionInfo.getVersionInfo(getServletContext()); %> - -
CRCE version <%= versionInfo.getProductVersion() %> build rev. <%= versionInfo.getBuildRevision() %> -
© 2011-2015 University of West Bohemia, Department of Computer Science -- -ReliSA research group
- - - - +<%@ page import="cz.zcu.kiv.crce.webui.internal.VersionInfo" %> + +<% VersionInfo versionInfo = VersionInfo.getVersionInfo(getServletContext()); %> + +
CRCE version <%= versionInfo.getProductVersion() %> build rev. <%= versionInfo.getBuildRevision() %> +
© 2011-2015 University of West Bohemia, Department of Computer Science -- +ReliSA research group
+ + + + diff --git a/modules/crce-webui/src/main/webapp/jsp/include/header.jsp b/core/crce-webui/src/main/webapp/jsp/include/header.jsp similarity index 100% rename from modules/crce-webui/src/main/webapp/jsp/include/header.jsp rename to core/crce-webui/src/main/webapp/jsp/include/header.jsp diff --git a/modules/crce-webui/src/main/webapp/jsp/plugins.jsp b/core/crce-webui/src/main/webapp/jsp/plugins.jsp similarity index 100% rename from modules/crce-webui/src/main/webapp/jsp/plugins.jsp rename to core/crce-webui/src/main/webapp/jsp/plugins.jsp diff --git a/modules/crce-webui/src/main/webapp/jsp/store.jsp b/core/crce-webui/src/main/webapp/jsp/store.jsp similarity index 100% rename from modules/crce-webui/src/main/webapp/jsp/store.jsp rename to core/crce-webui/src/main/webapp/jsp/store.jsp diff --git a/modules/crce-webui/src/main/webapp/jsp/tags.jsp b/core/crce-webui/src/main/webapp/jsp/tags.jsp similarity index 100% rename from modules/crce-webui/src/main/webapp/jsp/tags.jsp rename to core/crce-webui/src/main/webapp/jsp/tags.jsp diff --git a/modules/crce-webui/src/main/webapp/test.jsp b/core/crce-webui/src/main/webapp/test.jsp similarity index 100% rename from modules/crce-webui/src/main/webapp/test.jsp rename to core/crce-webui/src/main/webapp/test.jsp index d6d47d25..4f8fecf2 100644 --- a/modules/crce-webui/src/main/webapp/test.jsp +++ b/core/crce-webui/src/main/webapp/test.jsp @@ -1,10 +1,10 @@ -<%@page import="cz.zcu.kiv.crce.plugin.Plugin"%> -<%@page import="cz.zcu.kiv.crce.metadata.Requirement"%> -<%@page import="cz.zcu.kiv.crce.metadata.Property"%> <%@page import="cz.zcu.kiv.crce.metadata.Capability"%> +<%@page import="cz.zcu.kiv.crce.metadata.Property"%> +<%@page import="cz.zcu.kiv.crce.metadata.Requirement"%> +<%@page import="cz.zcu.kiv.crce.metadata.Resource"%> +<%@page import="cz.zcu.kiv.crce.plugin.Plugin"%> <%@page import="cz.zcu.kiv.crce.repository.Buffer"%> <%@page import="cz.zcu.kiv.crce.webui.internal.Activator"%> -<%@page import="cz.zcu.kiv.crce.metadata.Resource"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> diff --git a/modules/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java b/core/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java similarity index 100% rename from modules/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java rename to core/crce-webui/src/test/java/cz/zcu/kiv/crce/webui/internal/ResourceServletTest.java diff --git a/modules/crce-default-modules/pom.xml b/modules/crce-default-modules/pom.xml index 876e8f61..2bdea37b 100644 --- a/modules/crce-default-modules/pom.xml +++ b/modules/crce-default-modules/pom.xml @@ -58,7 +58,7 @@ ${project.groupId} crce-webui - 2.1.1-SNAPSHOT + 2.1.2-SNAPSHOT war diff --git a/modules/pom.xml b/modules/pom.xml index 8d63ab37..c5416078 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -57,7 +57,7 @@ - crce-webui + crce-rest-v2 From 8632d3e7a0cf4cd8ba31d64baa56192125b537b8 Mon Sep 17 00:00:00 2001 From: Radek Vais Date: Mon, 7 Jan 2019 10:43:15 +0100 Subject: [PATCH 56/85] no issue - linux auto build script --- build.bash | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 build.bash diff --git a/build.bash b/build.bash new file mode 100644 index 00000000..703b8e56 --- /dev/null +++ b/build.bash @@ -0,0 +1,61 @@ +#!/bin/bash + +echo "Building crce-parent in ./pom" +cd pom +mvn clean install +retVal=$? +cd .. +if [ $retVal -ne 0 ]; then + echo "Error"; + exit $retVal; +fi + +#============================================================== + +echo "Building shared-build-settings in ./build" +cd build +mvn clean install +retVal=$? +cd .. +if [ $retVal -ne 0 ]; then + echo "Error"; + exit $retVal; +fi + +#============================================================== + +echo "Building third party libraries in ./third-party" +cd third-party +for d in * ; do cd $d ; mvn clean install ; cd .. ; done +retVal=$? +cd .. +if [ $retVal -ne 0 ]; then + echo "Error"; + exit $retVal; +fi + +#============================================================== + +echo "Building crce-core-reactor in ./core" +cd core +mvn clean install +retVal=$? +cd .. +if [ $retVal -ne 0 ]; then + echo "Error"; + exit $retVal; +fi + +#============================================================== + +echo "Building crce-modules-reactor in ./modules" +cd modules +mvn clean install +retVal=$? +cd .. +if [ $retVal -ne 0 ]; then + echo "Error"; + exit $retVal; +fi + +echo "Done building" From 2e225750c71549958f34f16be8aac2e24faa5b46 Mon Sep 17 00:00:00 2001 From: Radek Vais Date: Mon, 7 Jan 2019 13:16:29 +0100 Subject: [PATCH 57/85] documentation base --- arch/Modules.png | Bin 0 -> 137975 bytes arch/favlogo.jpg | Bin 0 -> 74124 bytes arch/sar-2018.pdf | Bin 131865 -> 869437 bytes arch/sar-2018.tex | 50 ++++++++++++++++++++++++++++++++++++++++++--- arch/wholeCRCE.png | Bin 0 -> 560130 bytes 5 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 arch/Modules.png create mode 100644 arch/favlogo.jpg create mode 100644 arch/wholeCRCE.png diff --git a/arch/Modules.png b/arch/Modules.png new file mode 100644 index 0000000000000000000000000000000000000000..716645acaa0acc7eb023104483199a4c34eb8439 GIT binary patch literal 137975 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
sna7U} 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 literal 0 HcmV?d00001 diff --git a/arch/favlogo.jpg b/arch/favlogo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b70db90802154324fcde22d3d697a85c8a943f5c GIT binary patch literal 74124 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 |i#N@GQX}LiB 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 z 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

p2c&m!Tse|m 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 HWii@8G98E}= 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