initial commit
This commit is contained in:
51
Readme.md
Normal file
51
Readme.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# Projet ESIR MDI Docker
|
||||||
|
|
||||||
|
## How to compile this project
|
||||||
|
|
||||||
|
Simple example of using OpenCV in a Web application build using jersey.
|
||||||
|
|
||||||
|
This application takes a picture using web browsers camera API (available in modern browsers)
|
||||||
|
and runs OpenCV face recognition algorithm (using [CascadeClassifier](http://docs.opencv.org/java/org/opencv/objdetect/CascadeClassifier.html) ) for it. If a face is detected a "troll face" is added on top of it.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
This application was inspired by the ingenious ["Trollator" mobile Android application](https://play.google.com/store/apps/details?id=com.fredagapps.android.trollator).
|
||||||
|
|
||||||
|
1. OpenCV Installation for local Maven repository
|
||||||
|
---
|
||||||
|
OpenCV is a native library with Java bindings so you need to install this to your system.
|
||||||
|
- *libopencv_java300.so* installed in you java.library.path (
|
||||||
|
- *opencv-300.jar* availble for application
|
||||||
|
|
||||||
|
There are good instructions how to build OpenCV with Java bindings for your own platform here: http://docs.opencv.org/doc/tutorials/introduction/desktop_java/java_dev_intro.html
|
||||||
|
|
||||||
|
Once you have built the Java library you can install the resulting jar file to your local Maven repository using
|
||||||
|
mvn install:install-file -Dfile=./bin/opencv-300.jar \
|
||||||
|
-DgroupId=org.opencv -DartifactId=opencv -Dversion=3.0.0 -Dpackaging=jar
|
||||||
|
|
||||||
|
|
||||||
|
2. Building this application
|
||||||
|
----
|
||||||
|
Once OpenCV jar library is available as a local Maven dependency, you can clone and build this application simply using Git and Maven:
|
||||||
|
|
||||||
|
|
||||||
|
mvn install
|
||||||
|
|
||||||
|
And run the application using the embedded Jetty plugin in http://localhost:8888
|
||||||
|
|
||||||
|
mvn package
|
||||||
|
java -Djava.library.path=/home/barais/git/opencv/build/lib/ -jar target/fatjar-0.0.1-SNAPSHOT.jar
|
||||||
|
# Do not forget to update the path to your opencv install in Main.java
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
If you fork this repo, to be up to date.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git remote add upstream https://github.com/barais/projetWE
|
||||||
|
git fetch upstream
|
||||||
|
git checkout master
|
||||||
|
git merge upstream/master
|
||||||
|
```
|
||||||
|
|
||||||
66
dependency-reduced-pom.xml
Normal file
66
dependency-reduced-pom.xml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>fr.ensai</groupId>
|
||||||
|
<artifactId>projetESIR</artifactId>
|
||||||
|
<name>projetWE</name>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
<build>
|
||||||
|
<finalName>fatjar-${project.version}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-maven-plugin</artifactId>
|
||||||
|
<version>9.4.15.v20190215</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.2.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<transformers>
|
||||||
|
<transformer />
|
||||||
|
<transformer>
|
||||||
|
<manifestEntries>
|
||||||
|
<Main-Class>main.Main</Main-Class>
|
||||||
|
</manifestEntries>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<createDependencyReducedPom>true</createDependencyReducedPom>
|
||||||
|
<filters>
|
||||||
|
<filter>
|
||||||
|
<artifact>*:*</artifact>
|
||||||
|
<excludes>
|
||||||
|
<exclude>META-INF/*.SF</exclude>
|
||||||
|
<exclude>META-INF/*.DSA</exclude>
|
||||||
|
<exclude>META-INF/*.RSA</exclude>
|
||||||
|
</excludes>
|
||||||
|
</filter>
|
||||||
|
</filters>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<version.jetty>9.4.15.v20190215</version.jetty>
|
||||||
|
</properties>
|
||||||
|
</project>
|
||||||
163
pom.xml
Normal file
163
pom.xml
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<!-- author Martin Delsart -->
|
||||||
|
<groupId>fr.ensai</groupId>
|
||||||
|
<artifactId>projetESIR</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>projetWE</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<version.jetty>9.4.15.v20190215</version.jetty>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-multipart -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
|
<artifactId>jersey-media-multipart</artifactId>
|
||||||
|
<version>2.28</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-multipart -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
|
<artifactId>jersey-media-multipart</artifactId>
|
||||||
|
<version>2.28</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.containers</groupId>
|
||||||
|
<artifactId>jersey-container-servlet</artifactId>
|
||||||
|
<version>2.28</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
|
<artifactId>jersey-media-json-processing</artifactId>
|
||||||
|
<version>2.28</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish</groupId>
|
||||||
|
<artifactId>javax.json</artifactId>
|
||||||
|
<version>1.1.4</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.opencv</groupId>
|
||||||
|
<artifactId>opencv</artifactId>
|
||||||
|
<version>3.4.6</version>
|
||||||
|
<type>jar</type>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.inject</groupId>
|
||||||
|
<artifactId>jersey-hk2</artifactId>
|
||||||
|
<version>2.28</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-server</artifactId>
|
||||||
|
<version>${version.jetty}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-webapp</artifactId>
|
||||||
|
<version>${version.jetty}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-servlet</artifactId>
|
||||||
|
<version>${version.jetty}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-util</artifactId>
|
||||||
|
<version>${version.jetty}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-servlets</artifactId>
|
||||||
|
<version>${version.jetty}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-http</artifactId>
|
||||||
|
<version>${version.jetty}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- add comment -->
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>fatjar-${project.version}</finalName>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<!-- * Start of user code for plugins -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-maven-plugin</artifactId>
|
||||||
|
<version>9.4.15.v20190215</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.2.1</version>
|
||||||
|
<configuration>
|
||||||
|
<createDependencyReducedPom>
|
||||||
|
true
|
||||||
|
</createDependencyReducedPom>
|
||||||
|
<filters>
|
||||||
|
<filter>
|
||||||
|
<artifact>*:*</artifact>
|
||||||
|
<excludes>
|
||||||
|
<exclude>META-INF/*.SF</exclude>
|
||||||
|
<exclude>META-INF/*.DSA</exclude>
|
||||||
|
<exclude>META-INF/*.RSA</exclude>
|
||||||
|
</excludes>
|
||||||
|
</filter>
|
||||||
|
</filters>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<transformers>
|
||||||
|
<transformer
|
||||||
|
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
|
||||||
|
<transformer
|
||||||
|
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
|
<manifestEntries>
|
||||||
|
<Main-Class>main.Main</Main-Class>
|
||||||
|
</manifestEntries>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
85
src/main/java/fr/esir/mdi/rest/SampleWebService.java
Normal file
85
src/main/java/fr/esir/mdi/rest/SampleWebService.java
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
package fr.esir.mdi.rest;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
|
import org.opencv.core.Core;
|
||||||
|
import org.opencv.core.Mat;
|
||||||
|
import org.opencv.core.MatOfByte;
|
||||||
|
import org.opencv.imgcodecs.Imgcodecs;
|
||||||
|
|
||||||
|
@Path("/hello")
|
||||||
|
public class SampleWebService {
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public SampleWebService() {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Path("/photo")
|
||||||
|
@POST
|
||||||
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
// @Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
public String fileSize( @FormDataParam("imageData") String f) {
|
||||||
|
|
||||||
|
String base64Image = f.split(",")[1];
|
||||||
|
byte[] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(base64Image);
|
||||||
|
try {
|
||||||
|
BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageBytes));
|
||||||
|
|
||||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
|
ImageIO.write(img, "png", byteArrayOutputStream);
|
||||||
|
byteArrayOutputStream.flush();
|
||||||
|
Mat m = Imgcodecs.imdecode(new MatOfByte(byteArrayOutputStream.toByteArray()), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED);
|
||||||
|
String s = encodeToString(main.Main.drawNewImage(m),"png");
|
||||||
|
// System.err.println(s);
|
||||||
|
return "data:image/png;base64,"+s;
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encodeToString(BufferedImage image, String type) {
|
||||||
|
String imageString = null;
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ImageIO.write(image, type, bos);
|
||||||
|
byte[] imageBytes = bos.toByteArray();
|
||||||
|
|
||||||
|
Base64.Encoder encoder = Base64.getEncoder();
|
||||||
|
imageString = encoder.encodeToString(imageBytes);
|
||||||
|
|
||||||
|
bos.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return imageString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
121
src/main/java/main/Main.java
Normal file
121
src/main/java/main/Main.java
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
package main;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
import org.opencv.core.Core;
|
||||||
|
import org.opencv.core.Mat;
|
||||||
|
import org.opencv.core.MatOfByte;
|
||||||
|
import org.opencv.core.MatOfRect;
|
||||||
|
import org.opencv.core.Rect;
|
||||||
|
import org.opencv.imgcodecs.Imgcodecs;
|
||||||
|
import org.opencv.objdetect.CascadeClassifier;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
private static final String TROLL_IMAGE = "trollface.jpg";
|
||||||
|
private static final String OPENCV_HAARCASCADES_HOME = "/home/barais/git/opencv/data/haarcascades/";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
||||||
|
}
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
//Mat original = Imgcodecs.imread("/home/barais/Images/PhotosLancieux/IMG_4514.JPG");
|
||||||
|
|
||||||
|
// drawNewImage(original);
|
||||||
|
Server server = new Server(8080);
|
||||||
|
|
||||||
|
WebAppContext root = new WebAppContext();
|
||||||
|
root.setContextPath("/");
|
||||||
|
root.setDescriptor("src/main/webapp/WEB-INF/web.xml");
|
||||||
|
URL webAppDir = Thread.currentThread().getContextClassLoader().getResource("webapp");
|
||||||
|
if (webAppDir == null) {
|
||||||
|
throw new RuntimeException("No webapp directory was found into the JAR file");
|
||||||
|
}
|
||||||
|
root.setResourceBase(webAppDir.toURI().toString());
|
||||||
|
root.setParentLoaderPriority(true);
|
||||||
|
|
||||||
|
server.setHandler(root);
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufferedImage drawNewImage(Mat original) {
|
||||||
|
Rect[] faces = faceDetect(original);
|
||||||
|
BufferedImage detectedImage = toBufferedImage(original);
|
||||||
|
|
||||||
|
BufferedImage overlay = loadImage(TROLL_IMAGE);
|
||||||
|
|
||||||
|
Graphics2D g = detectedImage.createGraphics();
|
||||||
|
for (int i = 0; i < faces.length; i++) {
|
||||||
|
Rect rect = faces[i];
|
||||||
|
g.drawImage(overlay, rect.x, rect.y, rect.x + rect.width,
|
||||||
|
rect.y + rect.height, 0, 0, overlay.getWidth(),
|
||||||
|
overlay.getHeight(), null);
|
||||||
|
}
|
||||||
|
g.dispose();
|
||||||
|
|
||||||
|
|
||||||
|
return detectedImage;
|
||||||
|
// ImageIO.write(detectedImage, "JPEG", new File("/tmp/test.jpg"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static BufferedImage loadImage(String file) {
|
||||||
|
try {
|
||||||
|
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(file);
|
||||||
|
return ImageIO.read(in);
|
||||||
|
// return ImageIO.read(file);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Rect[] faceDetect(Mat image) {
|
||||||
|
|
||||||
|
// Create a face detector from the cascade file in the resources
|
||||||
|
// directory.
|
||||||
|
CascadeClassifier faceDetector = new CascadeClassifier(OPENCV_HAARCASCADES_HOME
|
||||||
|
+ "haarcascade_frontalface_default.xml");
|
||||||
|
|
||||||
|
// Detect faces in the image.
|
||||||
|
// MatOfRect is a special container class for Rect.
|
||||||
|
MatOfRect faceDetections = new MatOfRect();
|
||||||
|
faceDetector.detectMultiScale(image, faceDetections, 1.2, 4, 0,
|
||||||
|
new org.opencv.core.Size(10, 10), new org.opencv.core.Size(
|
||||||
|
1000, 1000));
|
||||||
|
|
||||||
|
System.out.println(String.format("Detected %s faces",
|
||||||
|
faceDetections.toArray().length));
|
||||||
|
|
||||||
|
return faceDetections.toArray();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufferedImage toBufferedImage(Mat mat) {
|
||||||
|
MatOfByte mb = new MatOfByte();
|
||||||
|
Imgcodecs.imencode(".jpg", mat, mb);
|
||||||
|
BufferedImage bufferedImage = null;
|
||||||
|
try {
|
||||||
|
bufferedImage = ImageIO
|
||||||
|
.read(new ByteArrayInputStream(mb.toArray()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return bufferedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
10
src/main/java/servlet/HelloWorldApplication.java
Normal file
10
src/main/java/servlet/HelloWorldApplication.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package servlet;
|
||||||
|
|
||||||
|
import org.glassfish.jersey.server.ResourceConfig;
|
||||||
|
|
||||||
|
public class HelloWorldApplication extends ResourceConfig {
|
||||||
|
public HelloWorldApplication() {
|
||||||
|
// Define the package which contains the service classes.
|
||||||
|
packages("fr.esir.mdi.rest");
|
||||||
|
}
|
||||||
|
}
|
||||||
66
src/main/resources/META-INF/persistence.xml
Normal file
66
src/main/resources/META-INF/persistence.xml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
||||||
|
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
|
||||||
|
|
||||||
|
|
||||||
|
<persistence-unit name="dev" transaction-type="RESOURCE_LOCAL">
|
||||||
|
<!-- <class>org.hibernate.ejb.test.Cat</class> -->
|
||||||
|
<!-- <class>org.hibernate.ejb.test.Distributor</class> -->
|
||||||
|
<!-- <class>org.hibernate.ejb.test.Item</class> -->
|
||||||
|
<properties>
|
||||||
|
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||||
|
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
|
||||||
|
<property name="hibernate.connection.username" value="sa" />
|
||||||
|
<property name="hibernate.connection.password" value="" />
|
||||||
|
<property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost/" />
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
<persistence-unit name="prod" transaction-type="RESOURCE_LOCAL">
|
||||||
|
<!-- <class>org.hibernate.ejb.test.Cat</class> -->
|
||||||
|
<!-- <class>org.hibernate.ejb.test.Distributor</class> -->
|
||||||
|
<!-- <class>org.hibernate.ejb.test.Item</class> -->
|
||||||
|
<properties>
|
||||||
|
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="create" />
|
||||||
|
<property name="hibernate.show_sql" value="true" />
|
||||||
|
<property name="toplink.target-database" value="HSQL" />
|
||||||
|
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
|
||||||
|
<property name="hibernate.connection.username" value="sa" />
|
||||||
|
<property name="hibernate.connection.password" value="" />
|
||||||
|
<property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost/" />
|
||||||
|
<property name="hibernate.max_fetch_depth" value="3" />
|
||||||
|
<!-- cache configuration -->
|
||||||
|
<!-- <property name="hibernate.ejb.classcache.org.hibernate.ejb.test.Item"
|
||||||
|
value="read-write"/> -->
|
||||||
|
<!-- <property name="hibernate.ejb.collectioncache.org.hibernate.ejb.test.Item.distributors"
|
||||||
|
value="read-write, RegionName"/> -->
|
||||||
|
|
||||||
|
<!-- alternatively to <class> and <property> declarations, you can use
|
||||||
|
a regular hibernate.cfg.xml file -->
|
||||||
|
<!-- property name="hibernate.ejb.cfgfile" value="/org/hibernate/ejb/test/hibernate.cfg.xml"/ -->
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
|
||||||
|
<persistence-unit name="mysql">
|
||||||
|
<properties>
|
||||||
|
<!-- <property name="hibernate.ejb.cfgfile" value="/hibernate.cfg.xml"/>
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="create"/> -->
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||||
|
<property name="hibernate.archive.autodetection" value="class, hbm" />
|
||||||
|
<property name="hibernate.show_sql" value="true" />
|
||||||
|
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
|
||||||
|
<property name="hibernate.connection.password" value="root" />
|
||||||
|
<property name="hibernate.connection.url" value="jdbc:mysql://localhost/projetWE" />
|
||||||
|
<property name="hibernate.connection.username" value="root" />
|
||||||
|
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
|
||||||
|
<property name="hibernate.c3p0.min_size" value="5" />
|
||||||
|
<property name="hibernate.c3p0.max_size" value="20" />
|
||||||
|
<property name="hibernate.c3p0.timeout" value="300" />
|
||||||
|
<property name="hibernate.c3p0.max_statements" value="50" />
|
||||||
|
<property name="hibernate.c3p0.idle_test_period" value="3000" />
|
||||||
|
</properties>
|
||||||
|
</persistence-unit>
|
||||||
|
|
||||||
|
</persistence>
|
||||||
BIN
src/main/resources/trollface.jpg
Normal file
BIN
src/main/resources/trollface.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
24
src/main/webapp/WEB-INF/web.xml
Normal file
24
src/main/webapp/WEB-INF/web.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||||
|
id="WebApp_ID" version="3.0">
|
||||||
|
<display-name>MyWebProject</display-name>
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>Jersey Web Application</servlet-name>
|
||||||
|
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>javax.ws.rs.Application</param-name>
|
||||||
|
<param-value>servlet.HelloWorldApplication</param-value>
|
||||||
|
</init-param>
|
||||||
|
<init-param>
|
||||||
|
<param-name>jersey.config.server.provider.classnames</param-name>
|
||||||
|
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
|
||||||
|
</init-param>
|
||||||
|
<load-on-startup>1</load-on-startup>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>Jersey Web Application</servlet-name>
|
||||||
|
<url-pattern>/rest/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
</web-app>
|
||||||
137
src/main/webapp/capture.js
Normal file
137
src/main/webapp/capture.js
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
(function() {
|
||||||
|
// The width and height of the captured photo. We will set the
|
||||||
|
// width to the value defined here, but the height will be
|
||||||
|
// calculated based on the aspect ratio of the input stream.
|
||||||
|
|
||||||
|
var width = 320; // We will scale the photo width to this
|
||||||
|
var height = 0; // This will be computed based on the input stream
|
||||||
|
|
||||||
|
// |streaming| indicates whether or not we're currently streaming
|
||||||
|
// video from the camera. Obviously, we start at false.
|
||||||
|
|
||||||
|
var streaming = false;
|
||||||
|
|
||||||
|
// The various HTML elements we need to configure or control. These
|
||||||
|
// will be set by the startup() function.
|
||||||
|
|
||||||
|
var video = null;
|
||||||
|
var canvas = null;
|
||||||
|
var photo = null;
|
||||||
|
var startbutton = null;
|
||||||
|
|
||||||
|
function startup() {
|
||||||
|
video = document.getElementById('video');
|
||||||
|
canvas = document.getElementById('canvas');
|
||||||
|
photo = document.getElementById('photo');
|
||||||
|
startbutton = document.getElementById('startbutton');
|
||||||
|
sendbutton = document.getElementById('sendbutton');
|
||||||
|
navigator.getMedia = ( navigator.getUserMedia ||
|
||||||
|
navigator.webkitGetUserMedia ||
|
||||||
|
navigator.mozGetUserMedia ||
|
||||||
|
navigator.msGetUserMedia);
|
||||||
|
|
||||||
|
navigator.getMedia(
|
||||||
|
{
|
||||||
|
video: true,
|
||||||
|
audio: false
|
||||||
|
},
|
||||||
|
function(stream) {
|
||||||
|
video.srcObject = stream;
|
||||||
|
video.play();
|
||||||
|
},
|
||||||
|
function(err) {
|
||||||
|
console.log("An error occured! " + err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
video.addEventListener('canplay', function(ev){
|
||||||
|
if (!streaming) {
|
||||||
|
height = video.videoHeight / (video.videoWidth/width);
|
||||||
|
|
||||||
|
// Firefox currently has a bug where the height can't be read from
|
||||||
|
// the video, so we will make assumptions if this happens.
|
||||||
|
|
||||||
|
if (isNaN(height)) {
|
||||||
|
height = width / (4/3);
|
||||||
|
}
|
||||||
|
|
||||||
|
video.setAttribute('width', width);
|
||||||
|
video.setAttribute('height', height);
|
||||||
|
canvas.setAttribute('width', width);
|
||||||
|
canvas.setAttribute('height', height);
|
||||||
|
streaming = true;
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
startbutton.addEventListener('click', function(ev){
|
||||||
|
takepicture();
|
||||||
|
ev.preventDefault();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
sendbutton.addEventListener('click', function(ev){
|
||||||
|
console.log('toto');
|
||||||
|
sendpicture();
|
||||||
|
ev.preventDefault();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
clearphoto();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the photo with an indication that none has been
|
||||||
|
// captured.
|
||||||
|
|
||||||
|
function clearphoto() {
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
context.fillStyle = "#AAA";
|
||||||
|
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
var data = canvas.toDataURL('image/png');
|
||||||
|
photo.setAttribute('src', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Capture a photo by fetching the current contents of the video
|
||||||
|
// and drawing it into a canvas, then converting that to a PNG
|
||||||
|
// format data URL. By drawing it on an offscreen canvas and then
|
||||||
|
// drawing that to the screen, we can change its size and/or apply
|
||||||
|
// other changes before drawing it.
|
||||||
|
|
||||||
|
function takepicture() {
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
if (width && height) {
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
context.drawImage(video, 0, 0, width, height);
|
||||||
|
|
||||||
|
var data = canvas.toDataURL('image/png');
|
||||||
|
photo.setAttribute('src', data);
|
||||||
|
} else {
|
||||||
|
clearphoto();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendpicture() {
|
||||||
|
var formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('imageData', photo.getAttribute('src'));
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: '/rest/hello/photo/',
|
||||||
|
data: formData,
|
||||||
|
contentType: false,
|
||||||
|
processData: false,
|
||||||
|
success: function (data) {
|
||||||
|
photo.setAttribute('src', data);
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
alert('There was an error uploading your file!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Set up our event listener to run the startup process
|
||||||
|
// once loading is complete.
|
||||||
|
window.addEventListener('load', startup, false);
|
||||||
|
})();
|
||||||
138
src/main/webapp/capture.js~
Normal file
138
src/main/webapp/capture.js~
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
(function() {
|
||||||
|
// The width and height of the captured photo. We will set the
|
||||||
|
// width to the value defined here, but the height will be
|
||||||
|
// calculated based on the aspect ratio of the input stream.
|
||||||
|
|
||||||
|
var width = 320; // We will scale the photo width to this
|
||||||
|
var height = 0; // This will be computed based on the input stream
|
||||||
|
|
||||||
|
// |streaming| indicates whether or not we're currently streaming
|
||||||
|
// video from the camera. Obviously, we start at false.
|
||||||
|
|
||||||
|
var streaming = false;
|
||||||
|
|
||||||
|
// The various HTML elements we need to configure or control. These
|
||||||
|
// will be set by the startup() function.
|
||||||
|
|
||||||
|
var video = null;
|
||||||
|
var canvas = null;
|
||||||
|
var photo = null;
|
||||||
|
var startbutton = null;
|
||||||
|
|
||||||
|
function startup() {
|
||||||
|
video = document.getElementById('video');
|
||||||
|
canvas = document.getElementById('canvas');
|
||||||
|
photo = document.getElementById('photo');
|
||||||
|
startbutton = document.getElementById('startbutton');
|
||||||
|
sendbutton = document.getElementById('sendbutton');
|
||||||
|
navigator.getMedia = ( navigator.getUserMedia ||
|
||||||
|
navigator.webkitGetUserMedia ||
|
||||||
|
navigator.mozGetUserMedia ||
|
||||||
|
navigator.msGetUserMedia);
|
||||||
|
|
||||||
|
navigator.getMedia(
|
||||||
|
{
|
||||||
|
video: true,
|
||||||
|
audio: false
|
||||||
|
},
|
||||||
|
function(stream) {
|
||||||
|
video.srcObject = stream;
|
||||||
|
video.play();
|
||||||
|
},
|
||||||
|
function(err) {
|
||||||
|
console.log("An error occured! " + err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
video.addEventListener('canplay', function(ev){
|
||||||
|
if (!streaming) {
|
||||||
|
height = video.videoHeight / (video.videoWidth/width);
|
||||||
|
|
||||||
|
// Firefox currently has a bug where the height can't be read from
|
||||||
|
// the video, so we will make assumptions if this happens.
|
||||||
|
|
||||||
|
if (isNaN(height)) {
|
||||||
|
height = width / (4/3);
|
||||||
|
}
|
||||||
|
|
||||||
|
video.setAttribute('width', width);
|
||||||
|
video.setAttribute('height', height);
|
||||||
|
canvas.setAttribute('width', width);
|
||||||
|
canvas.setAttribute('height', height);
|
||||||
|
streaming = true;
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
startbutton.addEventListener('click', function(ev){
|
||||||
|
takepicture();
|
||||||
|
ev.preventDefault();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
sendbutton.addEventListener('click', function(ev){
|
||||||
|
console.log('toto');
|
||||||
|
sendpicture();
|
||||||
|
ev.preventDefault();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
clearphoto();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the photo with an indication that none has been
|
||||||
|
// captured.
|
||||||
|
|
||||||
|
function clearphoto() {
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
context.fillStyle = "#AAA";
|
||||||
|
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
var data = canvas.toDataURL('image/png');
|
||||||
|
photo.setAttribute('src', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Capture a photo by fetching the current contents of the video
|
||||||
|
// and drawing it into a canvas, then converting that to a PNG
|
||||||
|
// format data URL. By drawing it on an offscreen canvas and then
|
||||||
|
// drawing that to the screen, we can change its size and/or apply
|
||||||
|
// other changes before drawing it.
|
||||||
|
|
||||||
|
function takepicture() {
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
if (width && height) {
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
context.drawImage(video, 0, 0, width, height);
|
||||||
|
|
||||||
|
var data = canvas.toDataURL('image/png');
|
||||||
|
photo.setAttribute('src', data);
|
||||||
|
} else {
|
||||||
|
clearphoto();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendpicture() {
|
||||||
|
var formData = new FormData();
|
||||||
|
|
||||||
|
formData.append('imageData', photo.getAttribute('src'));
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: '/photo/',
|
||||||
|
data: formData,
|
||||||
|
contentType: false,
|
||||||
|
processData: false,
|
||||||
|
success: function (data) {
|
||||||
|
alert('Your file was successfully uploaded!');
|
||||||
|
window.location='/photo'
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
alert('There was an error uploading your file!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Set up our event listener to run the startup process
|
||||||
|
// once loading is complete.
|
||||||
|
window.addEventListener('load', startup, false);
|
||||||
|
})();
|
||||||
35
src/main/webapp/index.html
Normal file
35
src/main/webapp/index.html
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Trombi ISTIC</title>
|
||||||
|
<meta charset='utf-8'>
|
||||||
|
<link rel="stylesheet" href="main.css" type="text/css" media="all">
|
||||||
|
<script
|
||||||
|
src="https://code.jquery.com/jquery-2.2.4.min.js"
|
||||||
|
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="capture.js">
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="contentarea">
|
||||||
|
<h1>
|
||||||
|
Demo docker
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="camera">
|
||||||
|
<video id="video">Video stream not available.</video>
|
||||||
|
<button id="startbutton">Take photo</button>
|
||||||
|
</div>
|
||||||
|
<canvas id="canvas">
|
||||||
|
</canvas>
|
||||||
|
<div class="output">
|
||||||
|
<img id="photo" alt="The screen capture will appear in this box.">
|
||||||
|
<button id="sendbutton">Send photo</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
61
src/main/webapp/main.css
Normal file
61
src/main/webapp/main.css
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#video {
|
||||||
|
border: 1px solid black;
|
||||||
|
box-shadow: 2px 2px 3px black;
|
||||||
|
width:320px;
|
||||||
|
height:240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#photo {
|
||||||
|
border: 1px solid black;
|
||||||
|
box-shadow: 2px 2px 3px black;
|
||||||
|
width:320px;
|
||||||
|
height:240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#canvas {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.camera {
|
||||||
|
width: 340px;
|
||||||
|
display:inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output {
|
||||||
|
width: 340px;
|
||||||
|
display:inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#startbutton {
|
||||||
|
display:block;
|
||||||
|
position:relative;
|
||||||
|
margin-left:auto;
|
||||||
|
margin-right:auto;
|
||||||
|
bottom:32px;
|
||||||
|
background-color: rgba(0, 150, 0, 0.5);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.7);
|
||||||
|
box-shadow: 0px 0px 1px 2px rgba(0, 0, 0, 0.2);
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: "Lucida Grande", "Arial", sans-serif;
|
||||||
|
color: rgba(255, 255, 255, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sendbutton {
|
||||||
|
display:block;
|
||||||
|
position:relative;
|
||||||
|
margin-left:auto;
|
||||||
|
margin-right:auto;
|
||||||
|
bottom:36px;
|
||||||
|
background-color: rgba(0, 150, 0, 0.5);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.7);
|
||||||
|
box-shadow: 0px 0px 1px 2px rgba(0, 0, 0, 0.2);
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: "Lucida Grande", "Arial", sans-serif;
|
||||||
|
color: rgba(255, 255, 255, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contentarea {
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: "Lucida Grande", "Arial", sans-serif;
|
||||||
|
width: 760px;
|
||||||
|
}
|
||||||
59
src/main/webapp/main1.css
Normal file
59
src/main/webapp/main1.css
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
.Portfolio {
|
||||||
|
position: relative;
|
||||||
|
margin: 5px;
|
||||||
|
border: 2px solid black;
|
||||||
|
float: left;
|
||||||
|
width: 180px;
|
||||||
|
transition-duration: 0.4s;
|
||||||
|
border-radius: 5px;
|
||||||
|
animation: winanim 0.5s ;
|
||||||
|
-webkit-backface-visibility:visible;
|
||||||
|
backface-visibility:visible;
|
||||||
|
box-shadow:0 3px 5px -1px rgba(0,0,0,.2),0 5px 8px 0 rgba(0,0,0,.14),0 1px 14px 0 rgba(0,0,0,.12)
|
||||||
|
}
|
||||||
|
|
||||||
|
.Portfolio:hover {
|
||||||
|
box-shadow: 0 12px 16px 0 rgba(0,0,0,.24),0 17px 50px 0 rgba(0,0,0,.19);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Portfolio img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 5px
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
padding: 5px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 90%;
|
||||||
|
background:black;
|
||||||
|
color: white
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav {
|
||||||
|
padding:20px;
|
||||||
|
margin-left:340px;
|
||||||
|
margin-top:-30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav li a {
|
||||||
|
margin:5px;
|
||||||
|
padding: 15px 50px;
|
||||||
|
font-size:16px;
|
||||||
|
color:gray;
|
||||||
|
background: #000;
|
||||||
|
transition-duration: 0.4s;
|
||||||
|
}
|
||||||
|
.nav a:hover {
|
||||||
|
background:#333;
|
||||||
|
}
|
||||||
|
.nav .active {
|
||||||
|
background-color:blue !important;
|
||||||
|
color:#fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes winanim {
|
||||||
|
0%{opacity:0;transform:scale3d(.3,.3,.3)}
|
||||||
|
50%{opacity:1}
|
||||||
|
|
||||||
|
}
|
||||||
BIN
src/main/webapp/swagger/favicon-16x16.png
Normal file
BIN
src/main/webapp/swagger/favicon-16x16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 738 B |
BIN
src/main/webapp/swagger/favicon-32x32.png
Normal file
BIN
src/main/webapp/swagger/favicon-32x32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
60
src/main/webapp/swagger/index.html
Normal file
60
src/main/webapp/swagger/index.html
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<!-- HTML for static distribution bundle build -->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Swagger UI</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" >
|
||||||
|
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
|
||||||
|
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
|
||||||
|
<style>
|
||||||
|
html
|
||||||
|
{
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: -moz-scrollbars-vertical;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after
|
||||||
|
{
|
||||||
|
box-sizing: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
body
|
||||||
|
{
|
||||||
|
margin:0;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="swagger-ui"></div>
|
||||||
|
|
||||||
|
<script src="./swagger-ui-bundle.js"> </script>
|
||||||
|
<script src="./swagger-ui-standalone-preset.js"> </script>
|
||||||
|
<script>
|
||||||
|
window.onload = function() {
|
||||||
|
// Begin Swagger UI call region
|
||||||
|
const ui = SwaggerUIBundle({
|
||||||
|
url: "http://localhost:8080/openapi.json",
|
||||||
|
dom_id: '#swagger-ui',
|
||||||
|
deepLinking: true,
|
||||||
|
presets: [
|
||||||
|
SwaggerUIBundle.presets.apis,
|
||||||
|
SwaggerUIStandalonePreset
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
SwaggerUIBundle.plugins.DownloadUrl
|
||||||
|
],
|
||||||
|
layout: "StandaloneLayout"
|
||||||
|
})
|
||||||
|
// End Swagger UI call region
|
||||||
|
|
||||||
|
window.ui = ui
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
67
src/main/webapp/swagger/oauth2-redirect.html
Normal file
67
src/main/webapp/swagger/oauth2-redirect.html
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en-US">
|
||||||
|
<body onload="run()">
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
function run () {
|
||||||
|
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||||
|
var sentState = oauth2.state;
|
||||||
|
var redirectUrl = oauth2.redirectUrl;
|
||||||
|
var isValid, qp, arr;
|
||||||
|
|
||||||
|
if (/code|token|error/.test(window.location.hash)) {
|
||||||
|
qp = window.location.hash.substring(1);
|
||||||
|
} else {
|
||||||
|
qp = location.search.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
arr = qp.split("&")
|
||||||
|
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
|
||||||
|
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||||
|
function (key, value) {
|
||||||
|
return key === "" ? value : decodeURIComponent(value)
|
||||||
|
}
|
||||||
|
) : {}
|
||||||
|
|
||||||
|
isValid = qp.state === sentState
|
||||||
|
|
||||||
|
if ((
|
||||||
|
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||||
|
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||||
|
) && !oauth2.auth.code) {
|
||||||
|
if (!isValid) {
|
||||||
|
oauth2.errCb({
|
||||||
|
authId: oauth2.auth.name,
|
||||||
|
source: "auth",
|
||||||
|
level: "warning",
|
||||||
|
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qp.code) {
|
||||||
|
delete oauth2.state;
|
||||||
|
oauth2.auth.code = qp.code;
|
||||||
|
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||||
|
} else {
|
||||||
|
let oauthErrorMsg
|
||||||
|
if (qp.error) {
|
||||||
|
oauthErrorMsg = "["+qp.error+"]: " +
|
||||||
|
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||||
|
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
oauth2.errCb({
|
||||||
|
authId: oauth2.auth.name,
|
||||||
|
source: "auth",
|
||||||
|
level: "error",
|
||||||
|
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||||
|
}
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
93
src/main/webapp/swagger/swagger-ui-bundle.js
Normal file
93
src/main/webapp/swagger/swagger-ui-bundle.js
Normal file
File diff suppressed because one or more lines are too long
1
src/main/webapp/swagger/swagger-ui-bundle.js.map
Normal file
1
src/main/webapp/swagger/swagger-ui-bundle.js.map
Normal file
File diff suppressed because one or more lines are too long
14
src/main/webapp/swagger/swagger-ui-standalone-preset.js
Normal file
14
src/main/webapp/swagger/swagger-ui-standalone-preset.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
src/main/webapp/swagger/swagger-ui.css
Normal file
3
src/main/webapp/swagger/swagger-ui.css
Normal file
File diff suppressed because one or more lines are too long
1
src/main/webapp/swagger/swagger-ui.css.map
Normal file
1
src/main/webapp/swagger/swagger-ui.css.map
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}
|
||||||
9
src/main/webapp/swagger/swagger-ui.js
Normal file
9
src/main/webapp/swagger/swagger-ui.js
Normal file
File diff suppressed because one or more lines are too long
1
src/main/webapp/swagger/swagger-ui.js.map
Normal file
1
src/main/webapp/swagger/swagger-ui.js.map
Normal file
File diff suppressed because one or more lines are too long
38
src/test/java/fr/ensai/projetWE/AppTest.java
Normal file
38
src/test/java/fr/ensai/projetWE/AppTest.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package fr.ensai.projetWE;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for simple App.
|
||||||
|
*/
|
||||||
|
public class AppTest
|
||||||
|
extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the test case
|
||||||
|
*
|
||||||
|
* @param testName name of the test case
|
||||||
|
*/
|
||||||
|
public AppTest( String testName )
|
||||||
|
{
|
||||||
|
super( testName );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the suite of tests being tested
|
||||||
|
*/
|
||||||
|
public static Test suite()
|
||||||
|
{
|
||||||
|
return new TestSuite( AppTest.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rigourous Test :-)
|
||||||
|
*/
|
||||||
|
public void testApp()
|
||||||
|
{
|
||||||
|
assertTrue( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user