removed jwt interface
This commit is contained in:
86
build.gradle
86
build.gradle
@@ -1,86 +0,0 @@
|
|||||||
apply plugin: 'java'
|
|
||||||
apply plugin: 'war'
|
|
||||||
apply plugin: 'maven-publish'
|
|
||||||
|
|
||||||
group='org.jpacrepo'
|
|
||||||
|
|
||||||
sourceCompatibility = 1.8
|
|
||||||
|
|
||||||
logging.captureStandardOutput LogLevel.INFO
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
mavenLocal()
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
|
||||||
testLogging {
|
|
||||||
exceptionFormat = 'full'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
testCompile group: 'junit', name: 'junit', version: '4.11'
|
|
||||||
compile 'org.apache.commons:commons-compress:1.9'
|
|
||||||
compile 'org.tukaani:xz:1.5'
|
|
||||||
compile 'javax:javaee-api:7.0'
|
|
||||||
//compile 'commons-io:commons-io:2.4'
|
|
||||||
//compile 'commons-codec:commons-codec:1.10'
|
|
||||||
compile 'eu.webtoolkit:jwt:3.3.5'
|
|
||||||
compile 'org.projectlombok:lombok:1.16.4'
|
|
||||||
//compile 'commons-fileupload:commons-fileupload:1.3.1'
|
|
||||||
//compile 'org.ops4j.orient:orient-ra-api:0.3.0'
|
|
||||||
|
|
||||||
|
|
||||||
testCompile 'com.thoughtworks.xstream:xstream:1.4.8'
|
|
||||||
testCompile 'org.jboss.resteasy:resteasy-jaxrs:3.0.11.Final'
|
|
||||||
testCompile 'org.jboss.resteasy:resteasy-client:3.0.11.Final'
|
|
||||||
testCompile 'org.jboss.resteasy:resteasy-jackson-provider:3.0.11.Final'
|
|
||||||
testCompile 'org.jboss.resteasy:resteasy-jaxb-provider:3.0.11.Final'
|
|
||||||
|
|
||||||
testCompile files('/opt/wildfly/bin/client/jboss-client.jar')
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
task deployWildfly(dependsOn: 'war') << {
|
|
||||||
def username = 'admin', password = '123456'
|
|
||||||
def sout = new StringBuffer(), serr = new StringBuffer()
|
|
||||||
def cmd = sprintf("/opt/wildfly/bin/jboss-cli.sh --controller=localhost:9990 --connect --user=%s --password=%s --command=\'deploy %s --force\'", username, password, tasks['war'].archivePath)
|
|
||||||
def proc = cmd.execute()
|
|
||||||
proc.consumeProcessOutput(sout, serr)
|
|
||||||
proc.waitFor()
|
|
||||||
if(proc.exitValue() != 0)
|
|
||||||
{
|
|
||||||
println "$serr"
|
|
||||||
throw new RuntimeException("Error occurred during deployment")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// client.jar
|
|
||||||
task clientJar(type: Jar) {
|
|
||||||
from(sourceSets.main.output) {
|
|
||||||
archiveName project.name + "-common.jar"
|
|
||||||
include 'org/jpacrepo/model/**', 'org/jpacrepo/pacbase/**', 'org/jpacrepo/context/ApplicationContext.class'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// server.jar
|
|
||||||
task serverJar(type: Jar) {
|
|
||||||
from(sourceSets.main.output) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
maven(MavenPublication) {
|
|
||||||
groupId project.group
|
|
||||||
artifactId project.name + "-common"
|
|
||||||
version "1.0"
|
|
||||||
|
|
||||||
artifact clientJar {
|
|
||||||
//classifier "sources"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
58
build.sbt
Normal file
58
build.sbt
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
name := "jpacrepo"
|
||||||
|
|
||||||
|
organization := "com.oggio88"
|
||||||
|
|
||||||
|
version := "2.0"
|
||||||
|
|
||||||
|
resolvers += Resolver.mavenLocal
|
||||||
|
scalaVersion := "2.12.2"
|
||||||
|
|
||||||
|
libraryDependencies += "org.tukaani" % "xz" % "1.6"
|
||||||
|
libraryDependencies += "org.apache.commons" % "commons-compress" % "1.14"
|
||||||
|
libraryDependencies += "org.projectlombok" % "lombok" % "1.16.18" % "provided"
|
||||||
|
//libraryDependencies += "javax" % "javaee-api" % "7.0" % "provided"
|
||||||
|
libraryDependencies += "javax" % "javaee-api" % "7.0"
|
||||||
|
|
||||||
|
libraryDependencies += "junit" % "junit" % "4.12" % "test"
|
||||||
|
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test"
|
||||||
|
libraryDependencies += "com.thoughtworks.xstream" % "xstream" % "1.4.10"
|
||||||
|
libraryDependencies += "commons-io" % "commons-io" % "2.5" % "test"
|
||||||
|
|
||||||
|
//libraryDependencies += "org.jboss.resteasy" % "resteasy-jaxrs" % "3.1.3.Final" % "test"
|
||||||
|
//libraryDependencies += "org.jboss.resteasy" % "resteasy-client" % "3.1.3.Final"
|
||||||
|
//libraryDependencies += "org.jboss.resteasy" % "resteasy-jackson-provider" % "3.1.3.Final" % "test"
|
||||||
|
//libraryDependencies += "com.fasterxml.jackson.core" % "jackson-core" % "2.9.0.pr4"
|
||||||
|
|
||||||
|
//libraryDependencies += "org.jboss.resteasy" % "resteasy-jaxb-provider" % "3.1.3.Final" % "test"
|
||||||
|
//libraryDependencies += "org.jboss.spec.javax.servlet" % "jboss-servlet-api_3.1_spec" % "1.0.0.Final" % "provided"
|
||||||
|
//libraryDependencies += "org.jboss.spec.javax.ws.rs" % "jboss-jaxrs-api_2.0_spec" % "1.0.0.Final"
|
||||||
|
|
||||||
|
libraryDependencies += "org.jboss.resteasy" % "resteasy-jaxrs" % "3.0.11.Final"
|
||||||
|
libraryDependencies += "org.jboss.resteasy" % "resteasy-client" % "3.0.11.Final"
|
||||||
|
libraryDependencies += "org.jboss.resteasy" % "resteasy-jackson-provider" % "3.0.11.Final"
|
||||||
|
libraryDependencies += "org.jboss.resteasy" % "resteasy-jaxb-provider" % "3.0.11.Final"
|
||||||
|
|
||||||
|
enablePlugins(WarPlugin)
|
||||||
|
|
||||||
|
val wildflyUsername = SettingKey[String]("wildfly-username", "The account username to use to connect to wildfly with jboss-cli.sh")
|
||||||
|
val wildflyPassword = SettingKey[String]("wildfly-password", "The account password to use to connect to wildfly with jboss-cli.sh")
|
||||||
|
val wildflyURL = SettingKey[String]("wildfly-url", "The username to use to connect to wildfly with jboss-cli.sh")
|
||||||
|
|
||||||
|
wildflyUsername := "admin"
|
||||||
|
wildflyPassword := "123456"
|
||||||
|
wildflyURL := "localhost:9990"
|
||||||
|
|
||||||
|
val deploy2Wildfly = TaskKey[Unit]("deploy2Wildfly", "Deploy to a wildfly server instance", KeyRanks.ATask)
|
||||||
|
|
||||||
|
deploy2Wildfly <<= (packagedArtifact in(Compile, Keys.`package`), wildflyURL, wildflyUsername, wildflyPassword) map
|
||||||
|
{
|
||||||
|
case ((art: Artifact, warFile: File), url: String, username: String, password: String) =>
|
||||||
|
//val warFile = (artifactPath in Keys.`package` in Compile).value//(artifactPath in `package`).value.absolutePath //(packageBin in Compile).value //(artifactPath in (Compile, package)).value
|
||||||
|
val cmd = s"/opt/wildfly/bin/jboss-cli.sh --controller='${url}' --connect --user='${username}' --password='${password}' --command=\'deploy ${warFile.absolutePath} --force\'"
|
||||||
|
println(cmd)
|
||||||
|
sys.process.stringToProcess(cmd).! match
|
||||||
|
{
|
||||||
|
case 0 => "OK"
|
||||||
|
case _ => throw new RuntimeException("Error occurred during deploy")
|
||||||
|
}
|
||||||
|
}
|
1
project/build.properties
Normal file
1
project/build.properties
Normal file
@@ -0,0 +1 @@
|
|||||||
|
sbt.version=0.13.13
|
1
project/plugins.sbt
Normal file
1
project/plugins.sbt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "2.1.0")
|
@@ -1,2 +0,0 @@
|
|||||||
rootProject.name = 'jpacrepo'
|
|
||||||
|
|
@@ -1,9 +1,9 @@
|
|||||||
package org.jpacrepo.context;
|
package com.oggio88.jpacrepo.context;
|
||||||
|
|
||||||
|
import com.oggio88.jpacrepo.model.PkgData;
|
||||||
|
import com.oggio88.jpacrepo.service.PacmanServiceView;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.jpacrepo.model.PkgData;
|
|
||||||
import org.jpacrepo.service.PacmanServiceView;
|
|
||||||
|
|
||||||
import javax.enterprise.context.ApplicationScoped;
|
import javax.enterprise.context.ApplicationScoped;
|
||||||
import java.io.File;
|
import java.io.File;
|
@@ -1,6 +1,6 @@
|
|||||||
package org.jpacrepo.context;
|
package com.oggio88.jpacrepo.context;
|
||||||
|
|
||||||
import org.jpacrepo.service.PacmanServiceView;
|
import com.oggio88.jpacrepo.service.PacmanServiceView;
|
||||||
|
|
||||||
import javax.ejb.EJB;
|
import javax.ejb.EJB;
|
||||||
import javax.enterprise.inject.Produces;
|
import javax.enterprise.inject.Produces;
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.context;
|
package com.oggio88.jpacrepo.context;
|
||||||
|
|
||||||
import javax.inject.Qualifier;
|
import javax.inject.Qualifier;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.model;
|
package com.oggio88.jpacrepo.model;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.model;
|
package com.oggio88.jpacrepo.model;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import javax.annotation.Generated;
|
import javax.annotation.Generated;
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.model;
|
package com.oggio88.jpacrepo.model;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.model;
|
package com.oggio88.jpacrepo.model;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.model;
|
package com.oggio88.jpacrepo.model;
|
||||||
|
|
||||||
import javax.annotation.Generated;
|
import javax.annotation.Generated;
|
||||||
import javax.persistence.metamodel.SingularAttribute;
|
import javax.persistence.metamodel.SingularAttribute;
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.model;
|
package com.oggio88.jpacrepo.model;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
@@ -1,8 +1,7 @@
|
|||||||
package org.jpacrepo.pacbase;
|
package com.oggio88.jpacrepo.pacbase;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.DigestInputStream;
|
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.pacbase;
|
package com.oggio88.jpacrepo.pacbase;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.DigestInputStream;
|
import java.security.DigestInputStream;
|
@@ -1,10 +1,10 @@
|
|||||||
package org.jpacrepo.pacbase;
|
package com.oggio88.jpacrepo.pacbase;
|
||||||
|
|
||||||
|
import com.oggio88.jpacrepo.model.PkgData;
|
||||||
|
import com.oggio88.jpacrepo.model.PkgName;
|
||||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||||
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
|
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
|
||||||
import org.jpacrepo.model.PkgData;
|
|
||||||
import org.jpacrepo.model.PkgName;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.persistence;
|
package com.oggio88.jpacrepo.persistence;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.service;
|
package com.oggio88.jpacrepo.service;
|
||||||
|
|
||||||
import javax.ws.rs.ApplicationPath;
|
import javax.ws.rs.ApplicationPath;
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
@@ -1,10 +1,10 @@
|
|||||||
package org.jpacrepo.service;
|
package com.oggio88.jpacrepo.service;
|
||||||
|
|
||||||
import org.jpacrepo.context.ApplicationContext;
|
import com.oggio88.jpacrepo.context.ApplicationContext;
|
||||||
import org.jpacrepo.context.DefaultConfiguration;
|
import com.oggio88.jpacrepo.context.DefaultConfiguration;
|
||||||
import org.jpacrepo.model.PkgData;
|
import com.oggio88.jpacrepo.model.PkgData;
|
||||||
import org.jpacrepo.model.PkgName;
|
import com.oggio88.jpacrepo.model.PkgName;
|
||||||
import org.jpacrepo.pacbase.Parser;
|
import com.oggio88.jpacrepo.pacbase.Parser;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.ejb.*;
|
import javax.ejb.*;
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.service;
|
package com.oggio88.jpacrepo.service;
|
||||||
|
|
||||||
import javax.ejb.Remote;
|
import javax.ejb.Remote;
|
||||||
|
|
@@ -1,6 +1,6 @@
|
|||||||
package org.jpacrepo.service;
|
package com.oggio88.jpacrepo.service;
|
||||||
|
|
||||||
import org.jpacrepo.model.PkgData;
|
import com.oggio88.jpacrepo.model.PkgData;
|
||||||
|
|
||||||
import javax.ejb.Local;
|
import javax.ejb.Local;
|
||||||
import java.util.List;
|
import java.util.List;
|
@@ -1,14 +1,13 @@
|
|||||||
package org.jpacrepo.service;
|
package com.oggio88.jpacrepo.service;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import com.oggio88.jpacrepo.model.PkgName;
|
||||||
import org.jpacrepo.context.ApplicationContext;
|
import com.oggio88.jpacrepo.context.ApplicationContext;
|
||||||
import org.jpacrepo.context.DefaultConfiguration;
|
import com.oggio88.jpacrepo.context.DefaultConfiguration;
|
||||||
import org.jpacrepo.model.StringList;
|
import com.oggio88.jpacrepo.model.StringList;
|
||||||
import org.jpacrepo.model.PkgData;
|
import com.oggio88.jpacrepo.model.PkgData;
|
||||||
import org.jpacrepo.model.PkgList;
|
import com.oggio88.jpacrepo.model.PkgList;
|
||||||
import org.jpacrepo.model.PkgName;
|
import com.oggio88.jpacrepo.pacbase.Parser;
|
||||||
import org.jpacrepo.pacbase.Parser;
|
import com.oggio88.jpacrepo.persistence.QueryEngine;
|
||||||
import org.jpacrepo.persistence.QueryEngine;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.ejb.*;
|
import javax.ejb.*;
|
||||||
@@ -137,10 +136,12 @@ public class PacmanWebService
|
|||||||
FileInputStream input = new FileInputStream(ctx.getFile(pkg));
|
FileInputStream input = new FileInputStream(ctx.getFile(pkg));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] bytes = new byte[128000];
|
byte[] bytes = new byte[1024];
|
||||||
while ((input.read(bytes)) != -1)
|
while (true)
|
||||||
{
|
{
|
||||||
output.write(bytes);
|
int size = input.read(bytes);
|
||||||
|
if (size < 0) break;
|
||||||
|
else output.write(bytes, 0, size);
|
||||||
}
|
}
|
||||||
output.close();
|
output.close();
|
||||||
}
|
}
|
||||||
@@ -192,7 +193,13 @@ public class PacmanWebService
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
FileOutputStream fos = new FileOutputStream(file);
|
FileOutputStream fos = new FileOutputStream(file);
|
||||||
IOUtils.copy(input, fos);
|
while (true)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int size = input.read(buffer);
|
||||||
|
if (size < 0) break;
|
||||||
|
else fos.write(buffer, 0, size);
|
||||||
|
}
|
||||||
fos.close();
|
fos.close();
|
||||||
|
|
||||||
ut.begin();
|
ut.begin();
|
||||||
@@ -216,7 +223,7 @@ public class PacmanWebService
|
|||||||
{
|
{
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Files.delete(file.toPath());
|
Files.delete(file.toPath());
|
||||||
if(ut.getStatus() != Status.STATUS_NO_TRANSACTION)
|
if (ut.getStatus() != Status.STATUS_NO_TRANSACTION)
|
||||||
{
|
{
|
||||||
ut.rollback();
|
ut.rollback();
|
||||||
}
|
}
|
@@ -1,4 +1,4 @@
|
|||||||
package org.jpacrepo.util;
|
package com.oggio88.jpacrepo.util;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
@@ -1,220 +0,0 @@
|
|||||||
package org.jpacrepo.frontend.component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by walter on 06/06/15.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
import eu.webtoolkit.jwt.*;
|
|
||||||
import org.jpacrepo.context.ApplicationContext;
|
|
||||||
import org.jpacrepo.model.PkgName;
|
|
||||||
import org.jpacrepo.util.Utility;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by walter on 03/01/15.
|
|
||||||
*/
|
|
||||||
public class JPacRepoApp extends WApplication
|
|
||||||
{
|
|
||||||
private ApplicationContext ctx;
|
|
||||||
private PackageTable table;
|
|
||||||
private WPushButton searchButton;
|
|
||||||
private WMenu pageMenu;
|
|
||||||
private WMenu pagerMenu;
|
|
||||||
private WComboBox pageCombo;
|
|
||||||
|
|
||||||
private String lastName;
|
|
||||||
|
|
||||||
private WSuggestionPopup nameSuggestion, versionSuggestion, archSuggestion;
|
|
||||||
|
|
||||||
private int pageSize = 10;
|
|
||||||
|
|
||||||
private WLineEdit packageNameEdit, packageVersionEdit, packageArchEdit;
|
|
||||||
|
|
||||||
public JPacRepoApp(WEnvironment env, ApplicationContext ctx)
|
|
||||||
{
|
|
||||||
super(env);
|
|
||||||
this.ctx = ctx;
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init()
|
|
||||||
{
|
|
||||||
WBootstrapTheme theme = new WBootstrapTheme();
|
|
||||||
theme.setVersion(WBootstrapTheme.Version.Version3);
|
|
||||||
setTheme(theme);
|
|
||||||
useStyleSheet(new WLink("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"));
|
|
||||||
useStyleSheet(new WLink("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"));
|
|
||||||
require("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js");
|
|
||||||
// useStyleSheet(new WLink(WApplication.getRelativeResourcesUrl() + "/themes/bootstrap/3/bootstrap-theme.min.css"));
|
|
||||||
useStyleSheet(new WLink("css/jpacrepo-web.css"));
|
|
||||||
createView();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createView()
|
|
||||||
{
|
|
||||||
WTemplate jumbotron = new WTemplate(Utility.getTemplate("jumbotron.html"));
|
|
||||||
packageArchEdit = new WLineEdit();
|
|
||||||
packageArchEdit.setWidth(new WLength("100%"));
|
|
||||||
packageNameEdit = new WLineEdit();
|
|
||||||
packageNameEdit.setWidth(new WLength("100%"));
|
|
||||||
packageVersionEdit = new WLineEdit();
|
|
||||||
packageVersionEdit.setWidth(new WLength("100%"));
|
|
||||||
searchButton = new WPushButton("Search");
|
|
||||||
pageCombo = new WComboBox();
|
|
||||||
for (int i = 1; i <= 10; i++)
|
|
||||||
{
|
|
||||||
pageCombo.addItem(Integer.toString(i * 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
searchButton.clicked().addListener(this, () ->
|
|
||||||
{
|
|
||||||
pageSize = Integer.parseInt(pageCombo.getCurrentText().toString());
|
|
||||||
while (pageMenu.getCount() > 0)
|
|
||||||
{
|
|
||||||
pageMenu.removeItem(pageMenu.itemAt(0));
|
|
||||||
}
|
|
||||||
while (pagerMenu.getCount() > 0)
|
|
||||||
{
|
|
||||||
pagerMenu.removeItem(pagerMenu.itemAt(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
long resultNumber = ctx.getPacmanService().countResults(packageNameEdit.getDisplayText(), packageVersionEdit.getDisplayText(), packageArchEdit.getDisplayText());
|
|
||||||
if (resultNumber < pageSize)
|
|
||||||
{
|
|
||||||
table.showPackages(ctx.getPacmanService().searchPackage(packageNameEdit.getDisplayText(), packageVersionEdit.getDisplayText(), packageArchEdit.getDisplayText(), -1, -1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int remaining = (int) resultNumber;
|
|
||||||
int i = 1;
|
|
||||||
while (remaining > 0)
|
|
||||||
{
|
|
||||||
final int logicalPageNumber = i - 1;
|
|
||||||
WMenuItem menuItem = new WMenuItem(Integer.toString(i++));
|
|
||||||
pageMenu.addItem(menuItem);
|
|
||||||
menuItem.clicked().addListener(this, () ->
|
|
||||||
{
|
|
||||||
table.showPackages(ctx.getPacmanService().searchPackage(packageNameEdit.getText(), packageVersionEdit.getText(), packageArchEdit.getText(), logicalPageNumber, pageSize));
|
|
||||||
});
|
|
||||||
remaining -= pageSize;
|
|
||||||
}
|
|
||||||
pageMenu.select(0);
|
|
||||||
|
|
||||||
WMenuItem previousItem = new WMenuItem("Previous"), nextItem = new WMenuItem("Next");
|
|
||||||
previousItem.setStyleClass("previous");
|
|
||||||
nextItem.setStyleClass("next");
|
|
||||||
|
|
||||||
previousItem.clicked().addListener(this, () ->
|
|
||||||
{
|
|
||||||
int newIndex = pageMenu.getCurrentIndex() - 1;
|
|
||||||
if (newIndex >= 0)
|
|
||||||
{
|
|
||||||
pageMenu.select(newIndex);
|
|
||||||
pageMenu.itemAt(newIndex).clicked().trigger(new WMouseEvent());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
nextItem.clicked().addListener(this, () ->
|
|
||||||
{
|
|
||||||
int newIndex = pageMenu.getCurrentIndex() + 1;
|
|
||||||
if (newIndex < pageMenu.getCount())
|
|
||||||
{
|
|
||||||
pageMenu.select(newIndex);
|
|
||||||
pageMenu.itemAt(newIndex).clicked().trigger(new WMouseEvent());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pagerMenu.addItem(previousItem);
|
|
||||||
pagerMenu.addItem(nextItem);
|
|
||||||
|
|
||||||
table.showPackages(ctx.getPacmanService().searchPackage(packageNameEdit.getText(), packageVersionEdit.getText(), packageArchEdit.getText(), 0, pageSize));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
table = new PackageTable();
|
|
||||||
WTemplate inputTemplate = new WTemplate(Utility.getTemplate("package-search-form.html"));
|
|
||||||
inputTemplate.bindWidget("nameInput", packageNameEdit);
|
|
||||||
inputTemplate.bindWidget("versionInput", packageVersionEdit);
|
|
||||||
inputTemplate.bindWidget("archInput", packageArchEdit);
|
|
||||||
inputTemplate.bindWidget("searchButton", searchButton);
|
|
||||||
inputTemplate.bindWidget("pageInput", pageCombo);
|
|
||||||
|
|
||||||
WContainerWidget res = new WContainerWidget();
|
|
||||||
|
|
||||||
List<PkgName> nameList = ctx.getPacmanService().listProperty("name", new HashMap<>(), PkgName.class);
|
|
||||||
List<String> nameTxtList = new ArrayList<>();
|
|
||||||
nameList.forEach((p) -> nameTxtList.add(p.id));
|
|
||||||
nameSuggestion = getSuggestionPopup(nameTxtList, res, packageNameEdit);
|
|
||||||
nameSuggestion.setFilterLength(3);
|
|
||||||
nameSuggestion.setMaximumSize(WLength.Auto, new WLength("70%"));
|
|
||||||
|
|
||||||
versionSuggestion = getSuggestionPopup(new ArrayList<>(), res, packageVersionEdit);
|
|
||||||
versionSuggestion.setMaximumSize(WLength.Auto, new WLength("70%"));
|
|
||||||
|
|
||||||
packageNameEdit.blurred().addListener(this, () ->
|
|
||||||
{
|
|
||||||
if (!packageNameEdit.getDisplayText().equals(lastName))
|
|
||||||
{
|
|
||||||
lastName = packageNameEdit.getDisplayText();
|
|
||||||
Map<String, String> predicateMap = new HashMap<>();
|
|
||||||
predicateMap.put("name", packageNameEdit.getDisplayText());
|
|
||||||
List<String> versions = ctx.getPacmanService().listProperty("version", predicateMap, String.class);
|
|
||||||
|
|
||||||
versionSuggestion.getModel().removeRows(0, versionSuggestion.getModel().getRowCount());
|
|
||||||
versions.forEach((e) -> versionSuggestion.addSuggestion(e));
|
|
||||||
packageVersionEdit.setText("");
|
|
||||||
packageArchEdit.setText("");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
List<String> archs = ctx.getPacmanService().listProperty("arch", new HashMap<>(), String.class);
|
|
||||||
archSuggestion = getSuggestionPopup(archs, res, packageArchEdit);
|
|
||||||
|
|
||||||
res.addWidget(jumbotron);
|
|
||||||
res.addWidget(inputTemplate);
|
|
||||||
WContainerWidget containerWidget = new WContainerWidget();
|
|
||||||
containerWidget.addWidget(table);
|
|
||||||
containerWidget.setStyleClass("row");
|
|
||||||
res.addWidget(containerWidget);
|
|
||||||
res.setStyleClass("container main-container");
|
|
||||||
|
|
||||||
pageMenu = new WMenu();
|
|
||||||
pageMenu.setStyleClass("pagination");
|
|
||||||
res.addWidget(pageMenu);
|
|
||||||
|
|
||||||
pagerMenu = new WMenu();
|
|
||||||
pageCombo.setWidth(new WLength("100%"));
|
|
||||||
pagerMenu.setStyleClass("pager");
|
|
||||||
res.addWidget(pagerMenu);
|
|
||||||
|
|
||||||
getRoot().addWidget(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
WSuggestionPopup getSuggestionPopup(List<String> suggestions, WWidget parent, WFormWidget linkedFormWidget)
|
|
||||||
{
|
|
||||||
WSuggestionPopup.Options contactOptions = new WSuggestionPopup.Options();
|
|
||||||
contactOptions.highlightBeginTag = "<u><strong>";
|
|
||||||
contactOptions.highlightEndTag = "</strong></u>";
|
|
||||||
contactOptions.listSeparator = ',';
|
|
||||||
contactOptions.whitespace = " \\n";
|
|
||||||
contactOptions.wordSeparators = "-., \"@\\n;";
|
|
||||||
//contactOptions.appendReplacedText = ", ";
|
|
||||||
WSuggestionPopup popup = new WSuggestionPopup(WSuggestionPopup
|
|
||||||
.generateMatcherJS(contactOptions), WSuggestionPopup
|
|
||||||
.generateReplacerJS(contactOptions), parent);
|
|
||||||
popup.forEdit(linkedFormWidget, EnumSet.of(WSuggestionPopup.PopupTrigger.Editing, WSuggestionPopup.PopupTrigger.DropDownIcon));
|
|
||||||
List<WString> wstrings = new ArrayList<>();
|
|
||||||
for (String suggestion : suggestions)
|
|
||||||
{
|
|
||||||
wstrings.add(new WString(suggestion));
|
|
||||||
// popup.addSuggestion(suggestion);
|
|
||||||
}
|
|
||||||
popup.setModel(new WStringListModel(wstrings));
|
|
||||||
return popup;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@@ -1,82 +0,0 @@
|
|||||||
package org.jpacrepo.frontend.component;
|
|
||||||
|
|
||||||
import eu.webtoolkit.jwt.*;
|
|
||||||
import org.jpacrepo.model.PkgData;
|
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by walter on 06/06/15.
|
|
||||||
*/
|
|
||||||
public class PackageTable extends WTable
|
|
||||||
{
|
|
||||||
public PackageTable()
|
|
||||||
{
|
|
||||||
toggleStyleClass("table-bordered", true);
|
|
||||||
toggleStyleClass("table-condensed", true);
|
|
||||||
toggleStyleClass("table-hover", true);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showPackages(List<PkgData> pkgs)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
setHeaderCount(1);
|
|
||||||
setWidth(new WLength("100%"));
|
|
||||||
|
|
||||||
getElementAt(0, 0).addWidget(new WText("Name"));
|
|
||||||
getElementAt(0, 1).addWidget(new WText("Version"));
|
|
||||||
getElementAt(0, 2).addWidget(new WText("Arch"));
|
|
||||||
getElementAt(0, 3).addWidget(new WText("Description"));
|
|
||||||
getElementAt(0, 4).addWidget(new WText("Size"));
|
|
||||||
getElementAt(0, 5).addWidget(new WText(""));
|
|
||||||
getElementAt(0, 5).setStyleClass("no-border");
|
|
||||||
|
|
||||||
|
|
||||||
for(int row =1 ; row<pkgs.size()+1; row++)
|
|
||||||
{
|
|
||||||
PkgData pkg = pkgs.get(row-1);
|
|
||||||
getElementAt(row, 0).addWidget(getCellText(pkg.name.id, "text-center"));
|
|
||||||
getElementAt(row, 1).addWidget(getCellText(pkg.version, "text-center"));
|
|
||||||
getElementAt(row, 2).addWidget(getCellText(pkg.arch, "text-center"));
|
|
||||||
getElementAt(row, 3).addWidget(getCellText(pkg.description, "text-center"));
|
|
||||||
getElementAt(row, 4).addWidget(getCellText(readableFileSize(pkg.size), "text-center"));
|
|
||||||
//WPushButton button = new WPushButton("Download");
|
|
||||||
|
|
||||||
WAnchor button = new WAnchor();
|
|
||||||
button.setStyleClass("btn btn-primary");
|
|
||||||
//text.setStyleClass("glyphicon glyphicon-download-alt");
|
|
||||||
// WText text = new WText();
|
|
||||||
// text.setStyleClass("glyphicons glyphicons-save");
|
|
||||||
// button.addWidget(text);
|
|
||||||
|
|
||||||
WImage img = new WImage("img/download.svg");
|
|
||||||
img.setStyleClass("download-icon");
|
|
||||||
img.setWidth(new WLength("16px"));
|
|
||||||
button.setImage(img);
|
|
||||||
button.setLink(new WLink(WLink.Type.Url, "archive/" + pkg.fileName));
|
|
||||||
button.addStyleClass("text-center");
|
|
||||||
new WText("Download",button);
|
|
||||||
getElementAt(row, 5).addWidget(button);
|
|
||||||
// getElementAt(row,5).setStyleClass("no-border");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private WText getCellText(String text, String styleClass)
|
|
||||||
{
|
|
||||||
WText res = new WText(text);
|
|
||||||
res.setWidth(new WLength("100%"));
|
|
||||||
res.setStyleClass(styleClass);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String readableFileSize(long size)
|
|
||||||
{
|
|
||||||
if (size <= 0) return "0";
|
|
||||||
final String[] units = new String[]{"B", "kB", "MB", "GB", "TB"};
|
|
||||||
int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
|
|
||||||
return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,656 +0,0 @@
|
|||||||
package org.jpacrepo.frontend.servlet;
|
|
||||||
|
|
||||||
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 java.io.*;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.channels.Channels;
|
|
||||||
import java.nio.channels.FileChannel;
|
|
||||||
import java.nio.channels.ReadableByteChannel;
|
|
||||||
import java.nio.channels.WritableByteChannel;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* The well known "<a href="http://balusc.omnifaces.org/2009/02/fileservlet-supporting-resume-and.html">BalusC FileServlet</a>",
|
|
||||||
* as an abstract template, slightly refactored, rewritten and modernized with a.o. fast NIO stuff instead of legacy
|
|
||||||
* RandomAccessFile.
|
|
||||||
* <p>
|
|
||||||
* This servlet properly deals with <code>ETag</code>, <code>If-None-Match</code> and <code>If-Modified-Since</code>
|
|
||||||
* caching requests, hereby improving browser caching. This servlet also properly deals with <code>Range</code> and
|
|
||||||
* <code>If-Range</code> ranging requests (<a href="https://tools.ietf.org/html/rfc7233">RFC7233</a>), which is required
|
|
||||||
* by most media players for proper audio/video streaming, and by webbrowsers and for a proper resume of an paused
|
|
||||||
* download, and by download accelerators to be able to request smaller parts simultaneously. This servlet is ideal when
|
|
||||||
* you have large files like media files placed outside the web application and you can't use the default servlet.
|
|
||||||
* <p>
|
|
||||||
* <h3>Usage</h3>
|
|
||||||
* <p>
|
|
||||||
* Just extend this class and override the {@link #getFile(HttpServletRequest)} method to return the desired file. If
|
|
||||||
* you want to trigger a HTTP 400 "Bad Request" error, simply throw {@link IllegalArgumentException}. If you want to
|
|
||||||
* trigger a HTTP 404 "Not Found" error, simply return <code>null</code>, or a non-existent file.
|
|
||||||
* <p>
|
|
||||||
* Here's a concrete example which serves it via an URL like <code>/media/foo.ext</code>:
|
|
||||||
* <p>
|
|
||||||
* <pre>
|
|
||||||
* @WebServlet("/media/*")
|
|
||||||
* public class MediaFileServlet extends FileServlet {
|
|
||||||
*
|
|
||||||
* private File folder;
|
|
||||||
*
|
|
||||||
* @Override
|
|
||||||
* public void init() throws ServletException {
|
|
||||||
* folder = new File("/var/webapp/media");
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* @Override
|
|
||||||
* protected File getFile(HttpServletRequest request) throws IllegalArgumentException {
|
|
||||||
* String pathInfo = request.getPathInfo();
|
|
||||||
*
|
|
||||||
* if (pathInfo == null || pathInfo.isEmpty() || "/".equals(pathInfo)) {
|
|
||||||
* throw new IllegalArgumentException();
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* return new File(folder, pathInfo);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
* <p>
|
|
||||||
* You can embed it in e.g. HTML5 video tag as below:
|
|
||||||
* <pre>
|
|
||||||
* <video src="#{request.contextPath}/media/video.mp4" controls="controls" />
|
|
||||||
* </pre>
|
|
||||||
* <p>
|
|
||||||
* <h3>Customizing <code>FileServlet</code></h3>
|
|
||||||
* <p>
|
|
||||||
* If more fine grained control is desired for handling "file not found" error, determining the cache expire time, the
|
|
||||||
* content type, whether the file should be supplied as an attachment and the attachment's file name, then the developer
|
|
||||||
* can opt to override one or more of the following protected methods:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@link #handleFileNotFound(HttpServletRequest, HttpServletResponse)}
|
|
||||||
* <li>{@link #getExpireTime(HttpServletRequest, File)}
|
|
||||||
* <li>{@link #getContentType(HttpServletRequest, File)}
|
|
||||||
* <li>{@link #isAttachment(HttpServletRequest, String)}
|
|
||||||
* <li>{@link #getAttachmentName(HttpServletRequest, File)}
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* <p><strong>See also</strong>:
|
|
||||||
* <ul>
|
|
||||||
* <li><a href="http://stackoverflow.com/q/13588149/157882">How to stream audio/video files such as MP3, MP4, AVI, etc using a Servlet</a>
|
|
||||||
* <li><a href="http://stackoverflow.com/a/29991447/157882">Abstract template for a static resource servlet</a>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @author Bauke Scholtz
|
|
||||||
* @since 2.2
|
|
||||||
*/
|
|
||||||
public abstract class AbstractFileServlet extends HttpServlet
|
|
||||||
{
|
|
||||||
|
|
||||||
// Constants ------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private static final int DEFAULT_STREAM_BUFFER_SIZE = 10240;
|
|
||||||
private static final String ERROR_UNSUPPORTED_ENCODING = "UTF-8 is apparently not supported on this platform.";
|
|
||||||
private static final Long DEFAULT_EXPIRE_TIME_IN_SECONDS = TimeUnit.DAYS.toSeconds(30);
|
|
||||||
private static final long ONE_SECOND_IN_MILLIS = TimeUnit.SECONDS.toMillis(1);
|
|
||||||
private static final String ETAG = "W/\"%s-%s\"";
|
|
||||||
private static final Pattern RANGE_PATTERN = Pattern.compile("^bytes=[0-9]*-[0-9]*(,[0-9]*-[0-9]*)*$");
|
|
||||||
private static final String CONTENT_DISPOSITION_HEADER = "%s;filename=\"%2$s\"; filename*=UTF-8''%2$s";
|
|
||||||
private static final String MULTIPART_BOUNDARY = UUID.randomUUID().toString();
|
|
||||||
|
|
||||||
private static long stream(InputStream input, OutputStream output) throws IOException
|
|
||||||
{
|
|
||||||
try (ReadableByteChannel inputChannel = Channels.newChannel(input);
|
|
||||||
WritableByteChannel outputChannel = Channels.newChannel(output))
|
|
||||||
{
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocateDirect(DEFAULT_STREAM_BUFFER_SIZE);
|
|
||||||
long size = 0;
|
|
||||||
|
|
||||||
while (inputChannel.read(buffer) != -1)
|
|
||||||
{
|
|
||||||
buffer.flip();
|
|
||||||
size += outputChannel.write(buffer);
|
|
||||||
buffer.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stream a specified range of the given file to the given output via NIO {@link Channels} and a directly allocated
|
|
||||||
* NIO {@link ByteBuffer}. The output stream will only implicitly be closed after streaming when the specified range
|
|
||||||
* represents the whole file, regardless of whether an exception is been thrown or not.
|
|
||||||
*
|
|
||||||
* @param file The file.
|
|
||||||
* @param output The output stream.
|
|
||||||
* @param start The start position (offset).
|
|
||||||
* @param length The (intented) length of written bytes.
|
|
||||||
* @return The (actual) length of the written bytes. This may be smaller when the given length is too large.
|
|
||||||
* @throws IOException When an I/O error occurs.
|
|
||||||
* @since 2.2
|
|
||||||
*/
|
|
||||||
public static long stream(File file, OutputStream output, long start, long length) throws IOException
|
|
||||||
{
|
|
||||||
if (start == 0 && length >= file.length())
|
|
||||||
{
|
|
||||||
return stream(new FileInputStream(file), output);
|
|
||||||
}
|
|
||||||
|
|
||||||
try (FileChannel fileChannel = (FileChannel) Files.newByteChannel(file.toPath(), StandardOpenOption.READ))
|
|
||||||
{
|
|
||||||
WritableByteChannel outputChannel = Channels.newChannel(output);
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocateDirect(DEFAULT_STREAM_BUFFER_SIZE);
|
|
||||||
long size = 0;
|
|
||||||
|
|
||||||
while (fileChannel.read(buffer, start + size) != -1)
|
|
||||||
{
|
|
||||||
buffer.flip();
|
|
||||||
|
|
||||||
if (size + buffer.limit() > length)
|
|
||||||
{
|
|
||||||
buffer.limit((int) (length - size));
|
|
||||||
}
|
|
||||||
|
|
||||||
size += outputChannel.write(buffer);
|
|
||||||
|
|
||||||
if (size >= length)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static String encodeURL(String string)
|
|
||||||
{
|
|
||||||
if (string == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return URLEncoder.encode(string, UTF_8.name());
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException e)
|
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException(ERROR_UNSUPPORTED_ENCODING, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String encodeURI(String string)
|
|
||||||
{
|
|
||||||
if (string == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return encodeURL(string)
|
|
||||||
.replace("+", "%20")
|
|
||||||
.replace("%21", "!")
|
|
||||||
.replace("%27", "'")
|
|
||||||
.replace("%28", "(")
|
|
||||||
.replace("%29", ")")
|
|
||||||
.replace("%7E", "~");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actions --------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doHead(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
|
||||||
{
|
|
||||||
doRequest(request, response, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
|
||||||
{
|
|
||||||
doRequest(request, response, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doRequest(HttpServletRequest request, HttpServletResponse response, boolean head) throws IOException
|
|
||||||
{
|
|
||||||
response.reset();
|
|
||||||
Resource resource;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
resource = new Resource(getFile(request));
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resource.file == null)
|
|
||||||
{
|
|
||||||
handleFileNotFound(request, response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preconditionFailed(request, resource))
|
|
||||||
{
|
|
||||||
response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setCacheHeaders(response, resource, getExpireTime(request, resource.file));
|
|
||||||
|
|
||||||
if (notModified(request, resource))
|
|
||||||
{
|
|
||||||
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Range> ranges = getRanges(request, resource);
|
|
||||||
|
|
||||||
if (ranges == null)
|
|
||||||
{
|
|
||||||
response.setHeader("Content-Range", "bytes */" + resource.length);
|
|
||||||
response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ranges.isEmpty())
|
|
||||||
{
|
|
||||||
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ranges.add(new Range(0, resource.length - 1)); // Full content.
|
|
||||||
}
|
|
||||||
|
|
||||||
String contentType = setContentHeaders(request, response, resource, ranges);
|
|
||||||
|
|
||||||
if (head)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
writeContent(response, resource, ranges, contentType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the file associated with the given HTTP servlet request.
|
|
||||||
* If this method throws {@link IllegalArgumentException}, then the servlet will return a HTTP 400 error.
|
|
||||||
* If this method returns <code>null</code>, or if {@link File#isFile()} returns <code>false</code>, then the
|
|
||||||
* servlet will invoke {@link #handleFileNotFound(HttpServletRequest, HttpServletResponse)}.
|
|
||||||
*
|
|
||||||
* @param request The involved HTTP servlet request.
|
|
||||||
* @return The file associated with the given HTTP servlet request.
|
|
||||||
* @throws IllegalArgumentException When the request is mangled in such way that it's not recognizable as a valid
|
|
||||||
* file request. The servlet will then return a HTTP 400 error.
|
|
||||||
*/
|
|
||||||
protected abstract File getFile(HttpServletRequest request) throws IllegalArgumentException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the case when the file is not found.
|
|
||||||
* <p>
|
|
||||||
* The default implementation sends a HTTP 404 error.
|
|
||||||
*
|
|
||||||
* @param request The involved HTTP servlet request.
|
|
||||||
* @param response The involved HTTP servlet response.
|
|
||||||
* @throws IOException When something fails at I/O level.
|
|
||||||
* @since 2.3
|
|
||||||
*/
|
|
||||||
protected void handleFileNotFound(HttpServletRequest request, HttpServletResponse response) throws IOException
|
|
||||||
{
|
|
||||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns how long the resource may be cached by the client before it expires, in seconds.
|
|
||||||
* <p>
|
|
||||||
* The default implementation returns 30 days in seconds.
|
|
||||||
*
|
|
||||||
* @param request The involved HTTP servlet request.
|
|
||||||
* @param file The involved file.
|
|
||||||
* @return The client cache expire time in seconds (not milliseconds!).
|
|
||||||
*/
|
|
||||||
protected long getExpireTime(HttpServletRequest request, File file)
|
|
||||||
{
|
|
||||||
return DEFAULT_EXPIRE_TIME_IN_SECONDS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the content type associated with the given HTTP servlet request and file.
|
|
||||||
* <p>
|
|
||||||
* The default implementation delegates {@link File#getName()} to {@link ServletContext#getMimeType(String)} with a
|
|
||||||
* fallback default value of <code>application/octet-stream</code>.
|
|
||||||
*
|
|
||||||
* @param request The involved HTTP servlet request.
|
|
||||||
* @param file The involved file.
|
|
||||||
* @return The content type associated with the given HTTP servlet request and file.
|
|
||||||
*/
|
|
||||||
protected String getContentType(HttpServletRequest request, File file)
|
|
||||||
{
|
|
||||||
String type = request.getServletContext().getMimeType(file.getName());
|
|
||||||
if (type != null)
|
|
||||||
{
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return "application/octet-stream";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns <code>true</code> if we must force a "Save As" dialog based on the given HTTP servlet request and content
|
|
||||||
* type as obtained from {@link #getContentType(HttpServletRequest, File)}.
|
|
||||||
* <p>
|
|
||||||
* The default implementation will return <code>true</code> if the content type does <strong>not</strong> start with
|
|
||||||
* <code>text</code> or <code>image</code>, and the <code>Accept</code> request header is either <code>null</code>
|
|
||||||
* or does not match the given content type.
|
|
||||||
*
|
|
||||||
* @param request The involved HTTP servlet request.
|
|
||||||
* @param contentType The content type of the involved file.
|
|
||||||
* @return <code>true</code> if we must force a "Save As" dialog based on the given HTTP servlet request and content
|
|
||||||
* type.
|
|
||||||
*/
|
|
||||||
protected boolean isAttachment(HttpServletRequest request, String contentType)
|
|
||||||
{
|
|
||||||
String accept = request.getHeader("Accept");
|
|
||||||
return (!contentType.startsWith("text") && !contentType.startsWith("image")) && (accept == null || !accepts(accept, contentType));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the file name to be used in <code>Content-Disposition</code> header.
|
|
||||||
* This does not need to be URL-encoded as this will be taken care of.
|
|
||||||
* <p>
|
|
||||||
* The default implementation returns {@link File#getName()}.
|
|
||||||
*
|
|
||||||
* @param request The involved HTTP servlet request.
|
|
||||||
* @param file The involved file.
|
|
||||||
* @return The file name to be used in <code>Content-Disposition</code> header.
|
|
||||||
* @since 2.3
|
|
||||||
*/
|
|
||||||
protected String getAttachmentName(HttpServletRequest request, File file)
|
|
||||||
{
|
|
||||||
return file.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sub-actions ----------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if it's a conditional request which must return 412.
|
|
||||||
*/
|
|
||||||
private boolean preconditionFailed(HttpServletRequest request, Resource resource)
|
|
||||||
{
|
|
||||||
String match = request.getHeader("If-Match");
|
|
||||||
long unmodified = request.getDateHeader("If-Unmodified-Since");
|
|
||||||
return (match != null) ? !matches(match, resource.eTag) : (unmodified != -1 && modified(unmodified, resource.lastModified));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set cache headers.
|
|
||||||
*/
|
|
||||||
private void setCacheHeaders(HttpServletResponse response, Resource resource, long expires)
|
|
||||||
{
|
|
||||||
//Servlets.setCacheHeaders(response, expires);
|
|
||||||
response.setHeader("ETag", resource.eTag);
|
|
||||||
response.setDateHeader("Last-Modified", resource.lastModified);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if it's a conditional request which must return 304.
|
|
||||||
*/
|
|
||||||
private boolean notModified(HttpServletRequest request, Resource resource)
|
|
||||||
{
|
|
||||||
String noMatch = request.getHeader("If-None-Match");
|
|
||||||
long modified = request.getDateHeader("If-Modified-Since");
|
|
||||||
return (noMatch != null) ? matches(noMatch, resource.eTag) : (modified != -1 && !modified(modified, resource.lastModified));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get requested ranges. If this is null, then we must return 416. If this is empty, then we must return full file.
|
|
||||||
*/
|
|
||||||
private List<Range> getRanges(HttpServletRequest request, Resource resource)
|
|
||||||
{
|
|
||||||
List<Range> ranges = new ArrayList<>(1);
|
|
||||||
String rangeHeader = request.getHeader("Range");
|
|
||||||
|
|
||||||
if (rangeHeader == null)
|
|
||||||
{
|
|
||||||
return ranges;
|
|
||||||
}
|
|
||||||
else if (!RANGE_PATTERN.matcher(rangeHeader).matches())
|
|
||||||
{
|
|
||||||
return null; // Syntax error.
|
|
||||||
}
|
|
||||||
|
|
||||||
String ifRange = request.getHeader("If-Range");
|
|
||||||
|
|
||||||
if (ifRange != null && !ifRange.equals(resource.eTag))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
long ifRangeTime = request.getDateHeader("If-Range");
|
|
||||||
|
|
||||||
if (ifRangeTime != -1 && modified(ifRangeTime, resource.lastModified))
|
|
||||||
{
|
|
||||||
return ranges;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IllegalArgumentException ifRangeHeaderIsInvalid)
|
|
||||||
{
|
|
||||||
return ranges;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String rangeHeaderPart : rangeHeader.split("=")[1].split(","))
|
|
||||||
{
|
|
||||||
Range range = parseRange(rangeHeaderPart, resource.length);
|
|
||||||
|
|
||||||
if (range == null)
|
|
||||||
{
|
|
||||||
return null; // Logic error.
|
|
||||||
}
|
|
||||||
|
|
||||||
ranges.add(range);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ranges;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse range header part. Returns null if there's a logic error (i.e. start after end).
|
|
||||||
*/
|
|
||||||
private Range parseRange(String range, long length)
|
|
||||||
{
|
|
||||||
long start = sublong(range, 0, range.indexOf('-'));
|
|
||||||
long end = sublong(range, range.indexOf('-') + 1, range.length());
|
|
||||||
|
|
||||||
if (start == -1)
|
|
||||||
{
|
|
||||||
start = length - end;
|
|
||||||
end = length - 1;
|
|
||||||
}
|
|
||||||
else if (end == -1 || end > length - 1)
|
|
||||||
{
|
|
||||||
end = length - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start > end)
|
|
||||||
{
|
|
||||||
return null; // Logic error.
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Range(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set content headers.
|
|
||||||
*/
|
|
||||||
private String setContentHeaders(HttpServletRequest request, HttpServletResponse response, Resource resource, List<Range> ranges)
|
|
||||||
{
|
|
||||||
String contentType = getContentType(request, resource.file);
|
|
||||||
String disposition = isAttachment(request, contentType) ? "attachment" : "inline";
|
|
||||||
String filename = encodeURI(getAttachmentName(request, resource.file));
|
|
||||||
response.setHeader("Content-Disposition", String.format(CONTENT_DISPOSITION_HEADER, disposition, filename));
|
|
||||||
response.setHeader("Accept-Ranges", "bytes");
|
|
||||||
|
|
||||||
if (ranges.size() == 1)
|
|
||||||
{
|
|
||||||
Range range = ranges.get(0);
|
|
||||||
response.setContentType(contentType);
|
|
||||||
response.setHeader("Content-Length", String.valueOf(range.length));
|
|
||||||
|
|
||||||
if (response.getStatus() == HttpServletResponse.SC_PARTIAL_CONTENT)
|
|
||||||
{
|
|
||||||
response.setHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + resource.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY);
|
|
||||||
}
|
|
||||||
|
|
||||||
return contentType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write given file to response with given content type and ranges.
|
|
||||||
*/
|
|
||||||
private void writeContent(HttpServletResponse response, Resource resource, List<Range> ranges, String contentType) throws IOException
|
|
||||||
{
|
|
||||||
ServletOutputStream output = response.getOutputStream();
|
|
||||||
|
|
||||||
if (ranges.size() == 1)
|
|
||||||
{
|
|
||||||
Range range = ranges.get(0);
|
|
||||||
stream(resource.file, output, range.start, range.length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (Range range : ranges)
|
|
||||||
{
|
|
||||||
output.println();
|
|
||||||
output.println("--" + MULTIPART_BOUNDARY);
|
|
||||||
output.println("Content-Type: " + contentType);
|
|
||||||
output.println("Content-Range: bytes " + range.start + "-" + range.end + "/" + resource.length);
|
|
||||||
stream(resource.file, output, range.start, range.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
output.println();
|
|
||||||
output.println("--" + MULTIPART_BOUNDARY + "--");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helpers --------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the given match header matches the given ETag value.
|
|
||||||
*/
|
|
||||||
private static boolean matches(String matchHeader, String eTag)
|
|
||||||
{
|
|
||||||
String[] matchValues = matchHeader.split("\\s*,\\s*");
|
|
||||||
Arrays.sort(matchValues);
|
|
||||||
return Arrays.binarySearch(matchValues, eTag) > -1
|
|
||||||
|| Arrays.binarySearch(matchValues, "*") > -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the given modified header is older than the given last modified value.
|
|
||||||
*/
|
|
||||||
private static boolean modified(long modifiedHeader, long lastModified)
|
|
||||||
{
|
|
||||||
return (modifiedHeader + ONE_SECOND_IN_MILLIS <= lastModified); // That second is because the header is in seconds, not millis.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a substring of the given string value from the given begin index to the given end index as a long.
|
|
||||||
* If the substring is empty, then -1 will be returned.
|
|
||||||
*/
|
|
||||||
private static long sublong(String value, int beginIndex, int endIndex)
|
|
||||||
{
|
|
||||||
String substring = value.substring(beginIndex, endIndex);
|
|
||||||
return substring.isEmpty() ? -1 : Long.parseLong(substring);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the given accept header accepts the given value.
|
|
||||||
*/
|
|
||||||
private static boolean accepts(String acceptHeader, String toAccept)
|
|
||||||
{
|
|
||||||
String[] acceptValues = acceptHeader.split("\\s*(,|;)\\s*");
|
|
||||||
Arrays.sort(acceptValues);
|
|
||||||
return Arrays.binarySearch(acceptValues, toAccept) > -1
|
|
||||||
|| Arrays.binarySearch(acceptValues, toAccept.replaceAll("/.*$", "/*")) > -1
|
|
||||||
|| Arrays.binarySearch(acceptValues, "*/*") > -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nested classes -------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience class for a file resource.
|
|
||||||
*/
|
|
||||||
private static class Resource
|
|
||||||
{
|
|
||||||
private final File file;
|
|
||||||
private final long length;
|
|
||||||
private final long lastModified;
|
|
||||||
private final String eTag;
|
|
||||||
|
|
||||||
public Resource(File file)
|
|
||||||
{
|
|
||||||
if (file != null && file.isFile())
|
|
||||||
{
|
|
||||||
this.file = file;
|
|
||||||
length = file.length();
|
|
||||||
lastModified = file.lastModified();
|
|
||||||
eTag = String.format(ETAG, encodeURL(file.getName()), lastModified);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.file = null;
|
|
||||||
length = 0;
|
|
||||||
lastModified = 0;
|
|
||||||
eTag = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience class for a byte range.
|
|
||||||
*/
|
|
||||||
private static class Range
|
|
||||||
{
|
|
||||||
private final long start;
|
|
||||||
private final long end;
|
|
||||||
private final long length;
|
|
||||||
|
|
||||||
public Range(long start, long end)
|
|
||||||
{
|
|
||||||
this.start = start;
|
|
||||||
this.end = end;
|
|
||||||
length = end - start + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@@ -1,38 +0,0 @@
|
|||||||
package org.jpacrepo.frontend.servlet;
|
|
||||||
|
|
||||||
import org.jpacrepo.context.ApplicationContext;
|
|
||||||
import org.jpacrepo.context.DefaultConfiguration;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.servlet.ServletContext;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.ServletOutputStream;
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by walter on 29/07/15.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
@WebServlet("/archive/*")
|
|
||||||
public class FileServlet extends AbstractFileServlet
|
|
||||||
{
|
|
||||||
@Inject
|
|
||||||
@DefaultConfiguration
|
|
||||||
private ApplicationContext ctx;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected File getFile(HttpServletRequest request) throws IllegalArgumentException
|
|
||||||
{
|
|
||||||
return new File(ctx.getSystemProperties().getProperty("RepoFolder"), request.getPathInfo().substring(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,38 +0,0 @@
|
|||||||
package org.jpacrepo.frontend.servlet;
|
|
||||||
|
|
||||||
import eu.webtoolkit.jwt.WApplication;
|
|
||||||
import eu.webtoolkit.jwt.WEnvironment;
|
|
||||||
import eu.webtoolkit.jwt.WtServlet;
|
|
||||||
import org.jpacrepo.context.ApplicationContext;
|
|
||||||
import org.jpacrepo.context.DefaultConfiguration;
|
|
||||||
import org.jpacrepo.frontend.component.JPacRepoApp;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.servlet.annotation.WebServlet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by walter on 06/06/15.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
@WebServlet(urlPatterns = {"/view/*"})
|
|
||||||
public class JPacRepoServlet extends WtServlet
|
|
||||||
{
|
|
||||||
@Inject
|
|
||||||
@DefaultConfiguration
|
|
||||||
ApplicationContext ctx;
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1236894561762L;
|
|
||||||
|
|
||||||
public JPacRepoServlet()
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WApplication createApplication(WEnvironment env)
|
|
||||||
{
|
|
||||||
return new JPacRepoApp(env, ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -3,16 +3,12 @@
|
|||||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||||
version="3.1">
|
version="3.1">
|
||||||
|
|
||||||
<listener>
|
|
||||||
<listener-class>eu.webtoolkit.jwt.ServletInit</listener-class>
|
|
||||||
</listener>
|
|
||||||
|
|
||||||
<display-name>jpacrepo</display-name>
|
<display-name>jpacrepo</display-name>
|
||||||
<description>jpacrepo</description>
|
<description>jpacrepo</description>
|
||||||
|
|
||||||
<!--<session-config>-->
|
<session-config>
|
||||||
<!--<tracking-mode>URL</tracking-mode>-->
|
<tracking-mode>COOKIE</tracking-mode>
|
||||||
<!--</session-config>-->
|
</session-config>
|
||||||
|
|
||||||
<error-page>
|
<error-page>
|
||||||
<error-code>404</error-code>
|
<error-code>404</error-code>
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
<a class="btn btn-default" href="${link}">
|
|
||||||
<span class="glyphicons glyphicon-save"></span> Download
|
|
||||||
</a>
|
|
@@ -1,4 +0,0 @@
|
|||||||
<div class="jumbotron text-center">
|
|
||||||
<h1>JPacRepo</h1>
|
|
||||||
<p>The personal archlinux package repository</p>
|
|
||||||
</div>
|
|
@@ -1,46 +0,0 @@
|
|||||||
<div class="input-control search-input">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-5">
|
|
||||||
<label>
|
|
||||||
Name:
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<label>
|
|
||||||
Version:
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<label>
|
|
||||||
Arch:
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<label>
|
|
||||||
Page size:
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-1">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<form class="form-inline">
|
|
||||||
<div class="form-group col-sm-5">
|
|
||||||
${nameInput}
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-sm-2">
|
|
||||||
${versionInput}
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-sm-2">
|
|
||||||
${archInput}
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-sm-2">
|
|
||||||
${pageInput}
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-sm-1">
|
|
||||||
${searchButton}
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@@ -2,11 +2,11 @@ import com.thoughtworks.xstream.XStream;
|
|||||||
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
|
import org.jboss.resteasy.plugins.providers.RegisterBuiltin;
|
||||||
import org.jboss.resteasy.plugins.providers.jackson.ResteasyJacksonProvider;
|
import org.jboss.resteasy.plugins.providers.jackson.ResteasyJacksonProvider;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.jpacrepo.model.PkgData;
|
import com.oggio88.jpacrepo.model.PkgData;
|
||||||
import org.jpacrepo.pacbase.Hasher;
|
import com.oggio88.jpacrepo.pacbase.Hasher;
|
||||||
import org.jpacrepo.pacbase.MD5InputStream;
|
import com.oggio88.jpacrepo.pacbase.MD5InputStream;
|
||||||
import org.jpacrepo.pacbase.Parser;
|
import com.oggio88.jpacrepo.pacbase.Parser;
|
||||||
import org.jpacrepo.service.PacmanServiceView;
|
import com.oggio88.jpacrepo.service.PacmanServiceView;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import javax.naming.*;
|
import javax.naming.*;
|
||||||
|
@@ -2,11 +2,12 @@ import com.thoughtworks.xstream.XStream;
|
|||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.filefilter.DirectoryFileFilter;
|
import org.apache.commons.io.filefilter.DirectoryFileFilter;
|
||||||
import org.apache.commons.io.filefilter.RegexFileFilter;
|
import org.apache.commons.io.filefilter.RegexFileFilter;
|
||||||
import org.jpacrepo.model.PkgData;
|
import com.oggio88.jpacrepo.model.PkgData;
|
||||||
import org.jpacrepo.pacbase.Parser;
|
import com.oggio88.jpacrepo.pacbase.Parser;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -19,7 +20,6 @@ public class ParseTest
|
|||||||
// @Test
|
// @Test
|
||||||
public void test() throws Exception
|
public void test() throws Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
Collection<File> ls = FileUtils.listFiles(new File("/var/cache/pacman/pkg"), new RegexFileFilter(".*\\.pkg\\.tar\\.xz"), DirectoryFileFilter.DIRECTORY);
|
Collection<File> ls = FileUtils.listFiles(new File("/var/cache/pacman/pkg"), new RegexFileFilter(".*\\.pkg\\.tar\\.xz"), DirectoryFileFilter.DIRECTORY);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
List<PkgData> lista = new ArrayList<>();
|
List<PkgData> lista = new ArrayList<>();
|
||||||
|
Reference in New Issue
Block a user