Skip to content
Snippets Groups Projects
Commit 003b045a authored by Lucas Bertrand-Christen's avatar Lucas Bertrand-Christen
Browse files

feat:td2-td3-wildflytxt

parent dad4494a
No related branches found
No related tags found
No related merge requests found
Showing
with 803 additions and 0 deletions
target/
.idea
target
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
\ No newline at end of file
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fr.ul.miage</groupId>
<artifactId>td2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.report.sourceEncoding>UTF-8</project.report.sourceEncoding>
<jakartaee-api.version>10.0.0</jakartaee-api.version>
<wildfly.version>29.0.1.Final</wildfly.version>
<compiler-plugin.version>3.11.0</compiler-plugin.version>
<war-plugin.version>3.3.2</war-plugin.version>
<wildfly-plugin.version>4.2.0.Final</wildfly-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>${jakartaee-api.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>filestore</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>${war-plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<!-- Execute 'mvn clean package wildfly:dev' to run the application. -->
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${wildfly-plugin.version}</version>
<configuration>
<version>${wildfly.version}</version>
<server-config>standalone-full.xml</server-config>
<jbossHome>C:\Users\LB-C\Bureau\Logiciels\wildfly-29.0.1.Final</jbossHome>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package fr.ul.miage.td2;
import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;
@ApplicationPath("api")
public class FilestoreAPI extends Application {
}
package fr.ul.miage.td2;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("hello") // "localhost:8080/filestore/api/hello"
public class HelloWorldResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello World (resource)";
}
}
package fr.ul.miage.td2;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name="HelloWorld", urlPatterns = "/hello")
public class HelloWorldServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("Hello World (servlet)");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">
<!--
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>fr.ul.miage.td2.HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping> -->
</web-app>
# Filestore Miage.23 Project
You can run the application by executing the following command from the directory where this file resides.
Please ensure you have installed a [Java SE 17+ implementation](https://adoptium.net/?variant=openjdk17) appropriate for your Jakarta EE version
and runtime choice. You also need to have a working maven installation.
```
./mvn clean package wildfly:dev
```
Once the runtime starts, you can access the project at http://localhost:8080/filestore
# http://localhost:8080/filestore/api/nodes _Quel code d'erreur renvoi cet appel ? _
Le code renvoie l'erreur : 404
En effet on a besoin d'un id
# _Quelle URL faut-il appeler à la place ? Vous allez alors avoir une nouvelle erreur.
On appelle http://localhost:8080/filestore/api/nodes/root
On obtient l'erreur : Could not find MessageBodyWriter for response object of type: fr.miage23.filestore.files.entity.Node of media type: text/html;charset=UTF-8
On doit traduire le Node en HTML
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fr.miage23.filestore</groupId>
<artifactId>jayblanc</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>The FileStore Application</name>
<organization>
<name>Miage Nancy</name>
<url>http://www.miage-nancy.fr</url>
</organization>
<developers>
<developer>
<id>jayblanc</id>
<name>Jerome Blanchard</name>
<email>jayblanc@gmail.com</email>
<url>http://wiki.jayblanc.fr</url>
<organization>Equasens</organization>
<organizationUrl>http://www.equasens.fr</organizationUrl>
<roles>
<role>developer</role>
</roles>
<timezone>Europe/Paris</timezone>
</developer>
</developers>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.report.sourceEncoding>UTF-8</project.report.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>
<jakartaee-api.version>10.0.0</jakartaee-api.version>
<wildfly.version>29.0.1.Final</wildfly.version>
<compiler-plugin.version>3.11.0</compiler-plugin.version>
<war-plugin.version>3.4.0</war-plugin.version>
<wildfly-plugin.version>4.2.0.Final</wildfly-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>${jakartaee-api.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>filestore</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${war-plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<!-- Execute 'mvn clean package wildfly:dev' to run the application. -->
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${wildfly-plugin.version}</version>
<configuration>
<version>${wildfly.version}</version>
<server-config>standalone-full.xml</server-config>
<jbossHome>C:\Users\LB-C\Bureau\Logiciels\wildfly-29.0.1.Final</jbossHome>
</configuration>
</plugin>
</plugins>
</build>
</project>
package fr.miage23.filestore.api;
import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;
@ApplicationPath("api")
public class FilestoreApplication extends Application {
}
package fr.miage23.filestore.api.dto;
public class Hello {
private String name;
public Hello(String name) {
this.name = name;
}
public String getHello(){
return name;
}
}
\ No newline at end of file
package fr.miage23.filestore.api.exceptions;
import fr.miage23.filestore.files.exceptions.NodeNotFoundException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class NodeNotFoundExceptionMapper implements ExceptionMapper<NodeNotFoundException> {
@Override
public Response toResponse(NodeNotFoundException e) {
return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build();
}
}
package fr.miage23.filestore.api.mapper;
import fr.miage23.filestore.files.entity.Node;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.ext.MessageBodyWriter;
import jakarta.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
@Provider
@Produces(MediaType.TEXT_HTML)
public class NodeHtmlMapper implements MessageBodyWriter<Node> {
@Override
public boolean isWriteable(Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public void writeTo(Node node, Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> multivaluedMap, OutputStream outputStream) throws IOException, WebApplicationException {
Writer writer = new PrintWriter(outputStream);
writer.write("<html><head><title>Filestore</title></head>");
writer.write("<body><h2>" + node.getName() + "</h2>");
writer.write("<ul><li>id: " + node.getId() + "</li>");
writer.write("<li>type: " + node.getType() + "</li>");
writer.write("<li>size: " + node.getSize() + "</li>");
writer.write("<li>creation: " + node.getCreation() + "</li>");
writer.write("<li>modification: " + node.getModification() + "</li>");
writer.write("</ul></body>");
writer.flush();
writer.close();
}
}
package fr.miage23.filestore.api.resources;
import fr.miage23.filestore.files.FileService;
import fr.miage23.filestore.files.entity.Node;
import fr.miage23.filestore.files.InMemoryFileServiceBean;
import fr.miage23.filestore.files.exceptions.NodeAlreadyExistsException;
import fr.miage23.filestore.files.exceptions.NodeNotFoundException;
import fr.miage23.filestore.files.exceptions.NodeTypeException;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriInfo;
import java.net.URI;
import java.util.logging.Level;
import java.util.logging.Logger;
@Path("nodes")
public class NodesResource {
private FileService service = InMemoryFileServiceBean.getInstance();
private static final Logger LOGGER = Logger.getLogger(NodesResource.class.getName());
@Context
UriInfo uriInfo; // Injectez l'objet UriInfo pour accéder aux informations d'URI.
@GET
public Response redirectToDefaultNode() {
String defaultNodeUrl = uriInfo.getBaseUriBuilder().path("nodes/root").build().toString();
return Response.seeOther(URI.create(defaultNodeUrl)).build();
}
@GET
@Path("{id}")
@Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_JSON})
public Node getNode(@PathParam("id") String id) throws NodeNotFoundException {
LOGGER.log(Level.INFO, "GET /api/nodes/" + id);
return service.get(id);
}
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response createNode(@FormParam("id") String id, @FormParam("name") String name, @Context UriInfo uriInfo) throws NodeNotFoundException, NodeTypeException, NodeAlreadyExistsException {
LOGGER.log(Level.INFO, "POST /api/nodes/" + id);
String newid = service.add(id, name);
return Response.created(uriInfo.getBaseUriBuilder().path(NodesResource.class).path(newid).build()).entity(newid).build();
}
@POST
@Path("{id}")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response createNodeWithPath(@PathParam("id") String id, @FormParam("name") String name, @Context UriInfo uriInfo) throws NodeNotFoundException, NodeTypeException, NodeAlreadyExistsException {
LOGGER.log(Level.INFO, "POST /api/nodes/" + id);
String newid = service.add(id, name);
return Response.created(uriInfo.getBaseUriBuilder().path(NodesResource.class).path(newid).build()).entity(newid).build();
}
}
package fr.miage23.filestore.files;
import fr.miage23.filestore.files.entity.Node;
import fr.miage23.filestore.files.exceptions.*;
import java.io.InputStream;
import java.util.List;
public interface FileService {
String ROOT_NODE_ID = "root";
String TREE_NODE_MIMETYPE = "application/fs-folder";
List<Node> list(String id) throws NodeNotFoundException;
Node get(String id) throws NodeNotFoundException;
InputStream getContent(String id) throws NodeNotFoundException, NodeTypeException, ContentException;
String add(String parent, String name) throws NodeNotFoundException, NodeAlreadyExistsException, NodeTypeException;
String add(String parent, String name, InputStream content) throws NodeNotFoundException, NodeAlreadyExistsException, NodeTypeException, ContentException;
void remove(String parent, String name) throws NodeNotFoundException, NodeNotEmptyException, NodeTypeException;
}
package fr.miage23.filestore.files;
import fr.miage23.filestore.files.entity.Node;
import fr.miage23.filestore.files.exceptions.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class InMemoryFileServiceBean implements FileService {
private static final Logger LOGGER = Logger.getLogger(InMemoryFileServiceBean.class.getName());
private static Map<String, Node> nodes;
private static Map<String, byte[]> contents;
private static final class InstanceHolder {
private static final FileService instance = new InMemoryFileServiceBean();
}
public static FileService getInstance(){
return InstanceHolder.instance;
}
private InMemoryFileServiceBean() {
LOGGER.log(Level.INFO, "Instantiating file service bean");
contents = new HashMap<>();
nodes = new ConcurrentHashMap<>();
Node root = new Node(Node.Type.TREE, "", ROOT_NODE_ID, "root");
nodes.put(root.getId(), root);
}
@Override
public List<Node> list(String parent) throws NodeNotFoundException {
String pid = (parent == null || parent.isEmpty())? ROOT_NODE_ID:parent;
LOGGER.log(Level.INFO, "Listing nodes for parent: " + pid);
if (!nodes.containsKey(pid)) {
throw new NodeNotFoundException("unable to find a node with id " + pid + " in the storage");
}
return nodes.values().stream().filter(n -> n.getParent().equals(pid)).collect(Collectors.toList());
}
@Override
public Node get(String id) throws NodeNotFoundException {
LOGGER.log(Level.INFO, "Getting node with id: " + id);
if (!nodes.containsKey(id)) {
throw new NodeNotFoundException("unable to find a node with id " + id + " in the storage");
}
return nodes.get(id);
}
@Override
public InputStream getContent(String id) throws NodeNotFoundException, NodeTypeException, ContentException {
LOGGER.log(Level.INFO, "Getting content for node with id: " + id);
if (!nodes.containsKey(id)) {
throw new NodeNotFoundException("unable to find a node with id " + id + " in the storage");
}
Node node = nodes.get(id);
if (!node.getType().equals(Node.Type.BLOB)) {
throw new NodeTypeException("only node of type BLOB have content");
}
if (!contents.containsKey(node.getContent())) {
throw new ContentException("unable to find node content with id: " + node.getContent() + " in storage");
}
return new ByteArrayInputStream(contents.get(node.getContent()));
}
@Override
public String add(String parent, String name) throws NodeNotFoundException, NodeAlreadyExistsException, NodeTypeException {
String pid = (parent == null || parent.isEmpty())? ROOT_NODE_ID:parent;
LOGGER.log(Level.INFO, "Adding TREE node with name: " + name + " for parent with id: " + pid);
if (!nodes.containsKey(pid)) {
throw new NodeNotFoundException("Unable to find a node with id: " + pid);
}
Node pnode = nodes.get(pid);
if (!pnode.getType().equals(Node.Type.TREE)) {
throw new NodeTypeException("Parent must be a node of type TREE");
}
if (nodes.values().stream().filter(n -> n.getParent().equals(pid)).anyMatch(n -> n.getName().equals(name))) {
throw new NodeAlreadyExistsException("A node with name: " + name + " already exists in tree with id: " + pid);
}
Node node = new Node(Node.Type.TREE, pid, UUID.randomUUID().toString(), name);
nodes.put(node.getId(), node);
pnode.setSize(pnode.getSize()+1);
return node.getId();
}
@Override
public String add(String parent, String name, InputStream content) throws NodeNotFoundException, NodeAlreadyExistsException, NodeTypeException, ContentException {
String pid = (parent == null || parent.isEmpty())? ROOT_NODE_ID:parent;
LOGGER.log(Level.INFO, "Adding BLOB node with name: " + name + " for parent with id: " + pid);
if (!nodes.containsKey(pid)) {
throw new NodeNotFoundException("Unable to find a parent node with id: " + pid);
}
Node pnode = nodes.get(pid);
if (!pnode.getType().equals(Node.Type.TREE)) {
throw new NodeTypeException("Parent must be a node of type TREE");
}
if (nodes.values().stream().filter(n -> n.getParent().equals(pid)).anyMatch(n -> n.getName().equals(name))) {
throw new NodeAlreadyExistsException("A node with name: " + name + " already exists in tree with id: " + pid);
}
String cid = UUID.randomUUID().toString();
try {
contents.put(cid, content.readAllBytes());
Node node = new Node(Node.Type.BLOB, pid, UUID.randomUUID().toString(), name);
node.setContent(cid);
node.setSize(contents.get(cid).length);
node.setMimetype("application/octet-stream");
nodes.put(node.getId(), node);
pnode.setSize(pnode.getSize()+1);
return node.getId();
} catch (IOException e) {
throw new ContentException("unable to read file content", e);
}
}
@Override
public void remove(String parent, String name) throws NodeNotFoundException, NodeNotEmptyException, NodeTypeException {
String pid = (parent == null || parent.isEmpty())? ROOT_NODE_ID:parent;
LOGGER.log(Level.FINE, "Remove node with name: " + name + " and parent: " + pid);
if (!nodes.containsKey(pid)) {
throw new NodeNotFoundException("Unable to find a parent node with id: " + pid);
}
Node pnode = nodes.get(pid);
if (!pnode.getType().equals(Node.Type.TREE)) {
throw new NodeTypeException("Parent must be a node of type TREE");
}
Optional<Node> node = nodes.values().stream().filter(n -> n.getParent().equals(pid)).filter(n -> n.getName().equals(name)).findAny();
if (node.isEmpty()) {
throw new NodeNotFoundException("A node with name: " + name + " does not exists in tree with id: " + pid);
}
if (node.get().getType().equals(Node.Type.TREE) && nodes.values().stream().anyMatch(n -> n.getParent().equals(node.get().getId()))) {
throw new NodeNotEmptyException("The node with name: " + name + " is not empty");
}
if (node.get().getType().equals(Node.Type.BLOB)) {
contents.remove(node.get().getContent());
}
nodes.remove(node.get().getId());
pnode.setSize(pnode.getSize()-1);
}
}
package fr.miage23.filestore.files.entity;
import fr.miage23.filestore.files.FileService;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Objects;
import java.util.UUID;
public class Node implements Comparable<Node>, Serializable {
private Type type;
private String id;
private long version;
private String parent;
private String name;
private String mimetype;
private long size;
private long creation;
private long modification;
private String content;
public Node() {
this.creation = this.modification = System.currentTimeMillis();
this.size = 0;
}
public Node(Type type, String parent, String id, String name) {
this();
this.parent = parent;
this.type = type;
this.id = id;
this.name = name;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
public String getParent() {
return parent;
}
public void setParent(String parent) {
this.parent = parent;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getMimetype() {
return mimetype;
}
public void setMimetype(String mimetype) {
this.mimetype = mimetype;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public long getCreation() {
return creation;
}
public void setCreation(long creation) {
this.creation = creation;
}
public long getModification() {
return modification;
}
public void setModification(long modification) {
this.modification = modification;
}
public boolean isRoot() {
return this.id.equals(FileService.ROOT_NODE_ID);
}
public boolean isFolder() {
return this.type.equals(Type.TREE);
}
public enum Type {
TREE,
BLOB
}
@Override
public int compareTo(Node o) {
if (this.getType().equals(o.getType())) {
return this.getName().compareTo(o.getName());
} else if (this.getType().equals(Type.TREE)){
return 1;
} else {
return -1;
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return creation == node.creation && modification == node.modification && type == node.type && Objects.equals(id, node.id) && Objects.equals(name, node.name) && Objects.equals(content, node.content) && Objects.equals(mimetype, node.mimetype);
}
@Override
public int hashCode() {
return Objects.hash(type, id, name, content, mimetype, creation, modification);
}
@Override
public String toString() {
return "Node{" +
"type=" + type +
", id='" + id + '\'' +
", version=" + version +
", parent='" + parent + '\'' +
", name='" + name + '\'' +
", mimetype='" + mimetype + '\'' +
", size=" + size +
", creation=" + creation +
", modification=" + modification +
", content='" + content + '\'' +
'}';
}
public static class NameComparatorAsc implements Comparator<Node> {
@Override
public int compare(Node o1, Node o2) {
if ( o1.isFolder() && !o2.isFolder() ) {
return -1;
}
if ( !o1.isFolder() && o2.isFolder() ) {
return 1;
}
return o1.getName().compareTo(o2.getName());
}
}
public static class NameComparatorDesc implements Comparator<Node> {
@Override
public int compare(Node o1, Node o2) {
if ( o1.isFolder() && !o2.isFolder() ) {
return -1;
}
if ( !o1.isFolder() && o2.isFolder() ) {
return 1;
}
return o2.getName().compareTo(o1.getName());
}
}
}
\ No newline at end of file
package fr.miage23.filestore.files.exceptions;
public class ContentException extends Exception {
public ContentException(String message) {
super(message);
}
public ContentException(String message, Throwable e) {
super(message, e);
}
}
package fr.miage23.filestore.files.exceptions;
public class NodeAlreadyExistsException extends Exception {
public NodeAlreadyExistsException(String message) {
super(message);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment