From 1f44e8a119ac9db862d422a6d85946a0a0bab75d Mon Sep 17 00:00:00 2001
From: Thomas <gltron3000@gmail.com>
Date: Fri, 22 May 2020 13:51:40 +0200
Subject: [PATCH] Refactored project structure

---
 .../src/main/java/mozen/MozenApplication.java |  48 +++++++-
 .../java/mozen/business/ILayerManager.java    |  13 +++
 .../java/mozen/business/IModelManager.java    |  17 +--
 .../main/java/mozen/business/ITagManager.java |  17 +++
 .../java/mozen/business/LayerManager.java     |  71 ++++++++++++
 .../java/mozen/business/ModelManager.java     | 107 ++----------------
 .../mozen/business/SpringBusinessConfig.java  |  53 ---------
 .../main/java/mozen/business/TagManager.java  |  57 ++++++++++
 .../main/java/mozen/business/UserManager.java |   1 +
 .../CustomLayerRepository.java                |   2 +-
 .../{business => repos}/ModelRepository.java  |   2 +-
 .../TagCategoryRepository.java                |   3 +-
 .../{business => repos}/TagRepository.java    |   2 +-
 .../{business => repos}/UserRepository.java   |   2 +-
 .../main/java/mozen/utils/DatabaseFiller.java |   4 +-
 .../java/mozen/web/CustomLayerController.java |  89 +++++++++++++++
 .../main/java/mozen/web/ModelController.java  |  75 ------------
 .../main/java/mozen/web/TagController.java    |  59 ++++++++++
 18 files changed, 373 insertions(+), 249 deletions(-)
 create mode 100644 mozen/src/main/java/mozen/business/ILayerManager.java
 create mode 100644 mozen/src/main/java/mozen/business/ITagManager.java
 create mode 100644 mozen/src/main/java/mozen/business/LayerManager.java
 delete mode 100644 mozen/src/main/java/mozen/business/SpringBusinessConfig.java
 create mode 100644 mozen/src/main/java/mozen/business/TagManager.java
 rename mozen/src/main/java/mozen/{business => repos}/CustomLayerRepository.java (88%)
 rename mozen/src/main/java/mozen/{business => repos}/ModelRepository.java (97%)
 rename mozen/src/main/java/mozen/{business => repos}/TagCategoryRepository.java (78%)
 rename mozen/src/main/java/mozen/{business => repos}/TagRepository.java (92%)
 rename mozen/src/main/java/mozen/{business => repos}/UserRepository.java (91%)
 create mode 100644 mozen/src/main/java/mozen/web/CustomLayerController.java
 create mode 100644 mozen/src/main/java/mozen/web/TagController.java

diff --git a/mozen/src/main/java/mozen/MozenApplication.java b/mozen/src/main/java/mozen/MozenApplication.java
index 68b4c2a..fa1e655 100644
--- a/mozen/src/main/java/mozen/MozenApplication.java
+++ b/mozen/src/main/java/mozen/MozenApplication.java
@@ -1,15 +1,31 @@
 package mozen;
 
+import javax.persistence.EntityManagerFactory;
+import javax.sql.DataSource;
+
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.domain.EntityScan;
 import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.PropertySource;
 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 @SpringBootApplication
 @EnableJpaRepositories(basePackageClasses = MozenApplication.class)
-@EntityScan(basePackageClasses = MozenApplication.class)
+@EntityScan(basePackages = "mozen.model")
+@ComponentScan(basePackages = "mozen")
+@EnableTransactionManagement
+@PropertySource("classpath:application.properties")
 public class MozenApplication {
 
 	@Bean
@@ -17,6 +33,36 @@ public class MozenApplication {
 		return new BCryptPasswordEncoder();
 	}
 
+	@Bean
+  public DataSource dataSource() {
+    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
+    return builder.setType(EmbeddedDatabaseType.HSQL).build();
+  }
+
+  @Bean
+  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
+    vendorAdapter.setGenerateDdl(true);
+
+    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
+    factory.setJpaVendorAdapter(vendorAdapter);
+    factory.setPackagesToScan("mozen.model");
+    factory.setDataSource(dataSource());
+    return factory;
+  }
+
+  @Bean
+  public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
+    JpaTransactionManager transactionManager = new JpaTransactionManager();
+    transactionManager.setEntityManagerFactory(emf);
+    return transactionManager;
+  }
+
+  @Bean
+  public PersistenceAnnotationBeanPostProcessor annotationProcessor() {
+    return new PersistenceAnnotationBeanPostProcessor();
+  }
+
 	public static void main(String[] args) {
 		SpringApplication.run(MozenApplication.class, args);
 	}
diff --git a/mozen/src/main/java/mozen/business/ILayerManager.java b/mozen/src/main/java/mozen/business/ILayerManager.java
new file mode 100644
index 0000000..d6c6718
--- /dev/null
+++ b/mozen/src/main/java/mozen/business/ILayerManager.java
@@ -0,0 +1,13 @@
+package mozen.business;
+
+import org.springframework.web.multipart.MultipartFile;
+
+import mozen.model.CustomLayer;
+import mozen.model.User;
+
+public interface ILayerManager {
+  void addLayerFile(MultipartFile file, long modelId, String name, User user) throws Exception;
+  void removeLayer(long id, User user) throws Exception;
+  
+  CustomLayer getLayer(long id);
+}
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/business/IModelManager.java b/mozen/src/main/java/mozen/business/IModelManager.java
index 348eeb6..57bda0d 100644
--- a/mozen/src/main/java/mozen/business/IModelManager.java
+++ b/mozen/src/main/java/mozen/business/IModelManager.java
@@ -5,33 +5,18 @@ import java.util.Collection;
 import org.springframework.web.multipart.MultipartFile;
 
 import mozen.messages.ModelMessage;
-import mozen.messages.TagMessage;
-import mozen.model.CustomLayer;
 import mozen.model.Model;
 import mozen.messages.SearchResult;
-import mozen.messages.TagCategoryMessage;
-import mozen.model.TagCategory;
 import mozen.model.User;
 
 public interface IModelManager {
   Long addModel(ModelMessage message, User user) throws Exception;
   void addModelFile(MultipartFile file, long id, User user) throws Exception;
   void updateModel(Model model, long id, User user) throws Exception;
-  void removeModel(long id, User user) throws Exception;
-
-  void addLayerFile(MultipartFile file, long modelId, String name, User user) throws Exception;
-  void removeLayer(long id, User user) throws Exception;
-
-  void addTag(TagMessage message);
-  void removeTag(long id);
-
-  void addCategory(TagCategoryMessage message);
-  void removeCategory(long id);
+  void removeModel(long id, User user) throws Exception;  
 
   Model getModel(long id);
   Collection<Model> getModels();
-  Collection<TagCategory> getTags();
-  CustomLayer getLayer(long id);
 
   SearchResult findModel(String name, int page, int size, String sort);
   SearchResult findModelWithTags(String name, int page, int size, String sort, Collection<String> tags);
diff --git a/mozen/src/main/java/mozen/business/ITagManager.java b/mozen/src/main/java/mozen/business/ITagManager.java
new file mode 100644
index 0000000..23613b2
--- /dev/null
+++ b/mozen/src/main/java/mozen/business/ITagManager.java
@@ -0,0 +1,17 @@
+package mozen.business;
+
+import java.util.Collection;
+
+import mozen.messages.TagCategoryMessage;
+import mozen.messages.TagMessage;
+import mozen.model.TagCategory;
+
+public interface ITagManager {
+  void addTag(TagMessage message);
+  void removeTag(long id);
+
+  void addCategory(TagCategoryMessage message);
+  void removeCategory(long id);
+
+  Collection<TagCategory> getTags();
+}
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/business/LayerManager.java b/mozen/src/main/java/mozen/business/LayerManager.java
new file mode 100644
index 0000000..b31a66e
--- /dev/null
+++ b/mozen/src/main/java/mozen/business/LayerManager.java
@@ -0,0 +1,71 @@
+package mozen.business;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import mozen.model.CustomLayer;
+import mozen.model.Model;
+import mozen.model.Role;
+import mozen.model.User;
+import mozen.repos.CustomLayerRepository;
+import mozen.repos.ModelRepository;
+
+@Service
+public class LayerManager implements ILayerManager{
+  @Autowired
+  private ModelRepository modelRepo;
+
+  @Autowired
+  private CustomLayerRepository layerRepo;
+
+  @Override
+  public CustomLayer getLayer(long id) {
+    return layerRepo.findById(id).get();
+  }
+
+  @Override
+  public void addLayerFile(MultipartFile file, long modelId, String name, User user) throws Exception {
+    Model model = modelRepo.findById(modelId).get();
+
+    if (model == null)
+      throw new Exception("Unknown model");
+    if (!isModelAuthor(model, user))
+      throw new Exception("Not the author");
+
+    CustomLayer layer = new CustomLayer();
+    layer.setName(name);
+    layer.setFile(file.getBytes());
+    layer.setFileType(file.getContentType());
+    layer.setModel(model);
+
+    model.getCustomLayers().add(layer);
+
+    modelRepo.save(model);
+  }
+
+  @Override
+  public void removeLayer(long id, User user) throws Exception {
+    CustomLayer layer = layerRepo.findById(id).get();
+
+    if (layer == null)
+      throw new Exception("Unknown layer");
+    if (!isLayerAuthor(layer, user))
+      throw new Exception("Not the author");
+
+    layerRepo.deleteById(id);
+  }
+
+  private boolean isLayerAuthor(CustomLayer layer, User user) {
+    if (user.getRole() == Role.ROLE_ADMIN)
+      return true;
+    return layer.getModel().getAuthor() == user;
+  }
+
+  private boolean isModelAuthor(Model model, User user) {
+    if (user.getRole() == Role.ROLE_ADMIN)
+      return true;
+    return model.getAuthor() == user;
+  }
+
+}
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/business/ModelManager.java b/mozen/src/main/java/mozen/business/ModelManager.java
index 251404c..dec9495 100644
--- a/mozen/src/main/java/mozen/business/ModelManager.java
+++ b/mozen/src/main/java/mozen/business/ModelManager.java
@@ -14,15 +14,13 @@ import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
 import mozen.messages.ModelMessage;
-import mozen.messages.TagMessage;
-import mozen.model.CustomLayer;
 import mozen.model.Model;
 import mozen.model.Role;
 import mozen.messages.SearchResult;
-import mozen.messages.TagCategoryMessage;
 import mozen.model.Tag;
-import mozen.model.TagCategory;
 import mozen.model.User;
+import mozen.repos.ModelRepository;
+import mozen.repos.TagRepository;
 
 @Service
 public class ModelManager implements IModelManager {
@@ -33,12 +31,6 @@ public class ModelManager implements IModelManager {
   @Autowired
   private TagRepository tagRepo;
 
-  @Autowired
-  private TagCategoryRepository tagCategoryRepo;
-
-  @Autowired
-  private CustomLayerRepository layerRepo;
-
   @Override
   public Long addModel(ModelMessage message, User user) throws Exception {
     Model model = new Model();
@@ -114,11 +106,6 @@ public class ModelManager implements IModelManager {
     modelRepo.deleteById(id);
   }
 
-  @Override
-  public Model getModel(long id) {
-    return modelRepo.findById(id).get();
-  }
-
   @Override
   public SearchResult findModel(String name, int page, int size, String sort) {
     System.err.println("[MODEL MANAGER] search n:" + name + " p:" + page + " si:" + size + " so:" + sort);
@@ -141,68 +128,6 @@ public class ModelManager implements IModelManager {
     return result;
   }
 
-  @Override
-  public void addLayerFile(MultipartFile file, long modelId, String name, User user) throws Exception {
-    Model model = modelRepo.findById(modelId).get();
-
-    if (model == null)
-      throw new Exception("Unknown model");
-    if (!isModelAuthor(model, user))
-      throw new Exception("Not the author");
-
-    CustomLayer layer = new CustomLayer();
-    layer.setName(name);
-    layer.setFile(file.getBytes());
-    layer.setFileType(file.getContentType());
-    layer.setModel(model);
-
-    model.getCustomLayers().add(layer);
-
-    modelRepo.save(model);
-  }
-
-  @Override
-  public void removeLayer(long id, User user) throws Exception {
-    CustomLayer layer = layerRepo.findById(id).get();
-
-    if (layer == null)
-      throw new Exception("Unknown layer");
-    if (!isLayerAuthor(layer, user))
-      throw new Exception("Not the author");
-
-    layerRepo.deleteById(id);
-  }
-
-  @Override
-  public void addTag(TagMessage message) {
-    System.err.println("[MODEL MANAGER] add tag n:" + message.getName() + " c:" + message.getCategoryId());
-    Long categoryId = message.getCategoryId();
-    TagCategory category = tagCategoryRepo.findById(categoryId).get();
-
-    Tag tag = new Tag();
-    tag.setName(message.getName());
-    tag.setCategory(category);
-
-    tagRepo.save(tag);
-  }
-
-  @Override
-  public Collection<TagCategory> getTags() {
-    return tagCategoryRepo.findAll();
-  }
-
-  private boolean isLayerAuthor(CustomLayer layer, User user) {
-    if (user.getRole() == Role.ROLE_ADMIN)
-      return true;
-    return layer.getModel().getAuthor() == user;
-  }
-
-  private boolean isModelAuthor(Model model, User user) {
-    if (user.getRole() == Role.ROLE_ADMIN)
-      return true;
-    return model.getAuthor() == user;
-  }
-
   @Override
   public SearchResult findModelWithTags(String name, int page, int size, String sort, Collection<String> tagsName) {
     System.err.println(
@@ -228,30 +153,18 @@ public class ModelManager implements IModelManager {
   }
 
   @Override
-  public Collection<Model> getModels() {
-    return modelRepo.findAll();
-  }
-
-  @Override
-  public CustomLayer getLayer(long id) {
-    return layerRepo.findById(id).get();
-  }
-
-  @Override
-  public void removeTag(long id) {
-    tagRepo.deleteById(id);
+  public Model getModel(long id) {
+    return modelRepo.findById(id).get();
   }
 
   @Override
-  public void removeCategory(long id) {
-    tagCategoryRepo.deleteById(id);
+  public Collection<Model> getModels() {
+    return modelRepo.findAll();
   }
 
-  @Override
-  public void addCategory(TagCategoryMessage message) {
-    TagCategory category = new TagCategory();
-    category.setName(message.getName());
-    tagCategoryRepo.save(category);
+  private boolean isModelAuthor(Model model, User user) {
+    if (user.getRole() == Role.ROLE_ADMIN)
+      return true;
+    return model.getAuthor() == user;
   }
-
 }
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/business/SpringBusinessConfig.java b/mozen/src/main/java/mozen/business/SpringBusinessConfig.java
deleted file mode 100644
index c2f1382..0000000
--- a/mozen/src/main/java/mozen/business/SpringBusinessConfig.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package mozen.business;
-
-import javax.persistence.EntityManagerFactory;
-import javax.sql.DataSource;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.PropertySource;
-import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
-import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
-import org.springframework.orm.jpa.JpaTransactionManager;
-import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
-import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor;
-import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.annotation.EnableTransactionManagement;
-
-@Configuration
-@ComponentScan(basePackageClasses = SpringBusinessConfig.class)
-@EnableTransactionManagement
-@PropertySource("classpath:application.properties")
-public class SpringBusinessConfig {
-  @Bean
-  public DataSource dataSource() {
-    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
-    return builder.setType(EmbeddedDatabaseType.HSQL).build();
-  }
-
-  @Bean
-  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
-    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
-    vendorAdapter.setGenerateDdl(true);
-
-    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
-    factory.setJpaVendorAdapter(vendorAdapter);
-    factory.setPackagesToScan("mozen.model");
-    factory.setDataSource(dataSource());
-    return factory;
-  }
-
-  @Bean
-  public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
-    JpaTransactionManager transactionManager = new JpaTransactionManager();
-    transactionManager.setEntityManagerFactory(emf);
-    return transactionManager;
-  }
-
-  @Bean
-  public PersistenceAnnotationBeanPostProcessor annotationProcessor() {
-    return new PersistenceAnnotationBeanPostProcessor();
-  }
-}
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/business/TagManager.java b/mozen/src/main/java/mozen/business/TagManager.java
new file mode 100644
index 0000000..60ada10
--- /dev/null
+++ b/mozen/src/main/java/mozen/business/TagManager.java
@@ -0,0 +1,57 @@
+package mozen.business;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import mozen.messages.TagCategoryMessage;
+import mozen.messages.TagMessage;
+import mozen.model.Tag;
+import mozen.model.TagCategory;
+import mozen.repos.TagCategoryRepository;
+import mozen.repos.TagRepository;
+
+@Service
+public class TagManager implements ITagManager {
+  @Autowired
+  private TagRepository tagRepo;
+
+  @Autowired
+  private TagCategoryRepository tagCategoryRepo;
+  
+  @Override
+  public void addTag(TagMessage message) {
+    System.err.println("[MODEL MANAGER] add tag n:" + message.getName() + " c:" + message.getCategoryId());
+    Long categoryId = message.getCategoryId();
+    TagCategory category = tagCategoryRepo.findById(categoryId).get();
+
+    Tag tag = new Tag();
+    tag.setName(message.getName());
+    tag.setCategory(category);
+
+    tagRepo.save(tag);
+  }
+
+  @Override
+  public void removeTag(long id) {
+    tagRepo.deleteById(id);
+  }
+
+  @Override
+  public void addCategory(TagCategoryMessage message) {
+    TagCategory category = new TagCategory();
+    category.setName(message.getName());
+    tagCategoryRepo.save(category);
+  }
+
+  @Override
+  public void removeCategory(long id) {
+    tagCategoryRepo.deleteById(id);
+  }
+
+  @Override
+  public Collection<TagCategory> getTags() {
+    return tagCategoryRepo.findAll();
+  }
+}
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/business/UserManager.java b/mozen/src/main/java/mozen/business/UserManager.java
index fb71d8e..84cb6c3 100644
--- a/mozen/src/main/java/mozen/business/UserManager.java
+++ b/mozen/src/main/java/mozen/business/UserManager.java
@@ -9,6 +9,7 @@ import org.springframework.stereotype.Service;
 import mozen.model.Role;
 import mozen.messages.SignupMessage;
 import mozen.model.User;
+import mozen.repos.UserRepository;
 
 @Service
 public class UserManager implements IUserManager {
diff --git a/mozen/src/main/java/mozen/business/CustomLayerRepository.java b/mozen/src/main/java/mozen/repos/CustomLayerRepository.java
similarity index 88%
rename from mozen/src/main/java/mozen/business/CustomLayerRepository.java
rename to mozen/src/main/java/mozen/repos/CustomLayerRepository.java
index 039a660..05f39aa 100644
--- a/mozen/src/main/java/mozen/business/CustomLayerRepository.java
+++ b/mozen/src/main/java/mozen/repos/CustomLayerRepository.java
@@ -1,4 +1,4 @@
-package mozen.business;
+package mozen.repos;
 
 import org.springframework.data.repository.CrudRepository;
 
diff --git a/mozen/src/main/java/mozen/business/ModelRepository.java b/mozen/src/main/java/mozen/repos/ModelRepository.java
similarity index 97%
rename from mozen/src/main/java/mozen/business/ModelRepository.java
rename to mozen/src/main/java/mozen/repos/ModelRepository.java
index d8bff04..f61700e 100644
--- a/mozen/src/main/java/mozen/business/ModelRepository.java
+++ b/mozen/src/main/java/mozen/repos/ModelRepository.java
@@ -1,4 +1,4 @@
-package mozen.business;
+package mozen.repos;
 
 import java.util.Collection;
 
diff --git a/mozen/src/main/java/mozen/business/TagCategoryRepository.java b/mozen/src/main/java/mozen/repos/TagCategoryRepository.java
similarity index 78%
rename from mozen/src/main/java/mozen/business/TagCategoryRepository.java
rename to mozen/src/main/java/mozen/repos/TagCategoryRepository.java
index dcf49ea..04bee96 100644
--- a/mozen/src/main/java/mozen/business/TagCategoryRepository.java
+++ b/mozen/src/main/java/mozen/repos/TagCategoryRepository.java
@@ -1,4 +1,4 @@
-package mozen.business;
+package mozen.repos;
 
 import java.util.List;
 
@@ -8,4 +8,5 @@ import mozen.model.TagCategory;
 
 public interface TagCategoryRepository extends CrudRepository<TagCategory, Long>{
   List<TagCategory> findAll();
+  List<TagCategory> findByOrderByNameAsc();
 }
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/business/TagRepository.java b/mozen/src/main/java/mozen/repos/TagRepository.java
similarity index 92%
rename from mozen/src/main/java/mozen/business/TagRepository.java
rename to mozen/src/main/java/mozen/repos/TagRepository.java
index 5e1038f..7ac968c 100644
--- a/mozen/src/main/java/mozen/business/TagRepository.java
+++ b/mozen/src/main/java/mozen/repos/TagRepository.java
@@ -1,4 +1,4 @@
-package mozen.business;
+package mozen.repos;
 
 import java.util.Collection;
 import java.util.List;
diff --git a/mozen/src/main/java/mozen/business/UserRepository.java b/mozen/src/main/java/mozen/repos/UserRepository.java
similarity index 91%
rename from mozen/src/main/java/mozen/business/UserRepository.java
rename to mozen/src/main/java/mozen/repos/UserRepository.java
index dbbe318..df7a286 100644
--- a/mozen/src/main/java/mozen/business/UserRepository.java
+++ b/mozen/src/main/java/mozen/repos/UserRepository.java
@@ -1,4 +1,4 @@
-package mozen.business;
+package mozen.repos;
 
 import java.util.List;
 
diff --git a/mozen/src/main/java/mozen/utils/DatabaseFiller.java b/mozen/src/main/java/mozen/utils/DatabaseFiller.java
index e556a23..ac405fa 100644
--- a/mozen/src/main/java/mozen/utils/DatabaseFiller.java
+++ b/mozen/src/main/java/mozen/utils/DatabaseFiller.java
@@ -16,14 +16,14 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import mozen.business.ModelRepository;
-import mozen.business.UserRepository;
 import mozen.model.CustomLayer;
 import mozen.model.Model;
 import mozen.model.Role;
 import mozen.model.Tag;
 import mozen.model.TagCategory;
 import mozen.model.User;
+import mozen.repos.ModelRepository;
+import mozen.repos.UserRepository;
 
 @Service
 public class DatabaseFiller {
diff --git a/mozen/src/main/java/mozen/web/CustomLayerController.java b/mozen/src/main/java/mozen/web/CustomLayerController.java
new file mode 100644
index 0000000..85678a6
--- /dev/null
+++ b/mozen/src/main/java/mozen/web/CustomLayerController.java
@@ -0,0 +1,89 @@
+package mozen.web;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import mozen.business.ILayerManager;
+import mozen.business.IUserManager;
+import mozen.model.CustomLayer;
+import mozen.messages.ResponseMessage;
+import mozen.model.User;
+
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@RestController
+@RequestMapping("/layers")
+@CrossOrigin
+public class CustomLayerController {
+  @Autowired
+  ILayerManager layerManager;
+
+  @Autowired
+  IUserManager userManager;
+
+  @GetMapping("/download")
+  public ResponseEntity<?> downloadLayerFile(@RequestParam(value = "id", required = true) Long id) {
+    ResponseMessage response = new ResponseMessage(false, "");
+  
+    try {
+      CustomLayer layer = layerManager.getLayer(id);
+      return ResponseEntity.ok()
+        .contentType(MediaType.parseMediaType(layer.getFileType()))
+        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + layer.getName() + "\"")
+        .body(new ByteArrayResource(layer.getFile()));
+    } catch (Exception e) {
+      response.setError(true);
+      response.setMessage(e.getMessage());
+    }
+
+    return ResponseEntity.ok(response);
+  }
+
+  @PostMapping("/upload")
+  public ResponseEntity<ResponseMessage> uploadLayerFile(
+    @RequestParam("file") MultipartFile file, 
+    @RequestParam(value = "id", required = true) Long id,
+    @RequestParam(value = "name", required = true) String name) {
+    ResponseMessage response = new ResponseMessage(false, "");
+    User user = getCurrentUser();
+    if(user == null) {
+      response.setError(true);
+      response.setMessage("User unknown");
+      return ResponseEntity.ok(response);
+    }
+  
+    try {
+      System.err.println("[MODEL CONTROLLER] layer file upload f:"+file.getName()+" n:"+name);
+      layerManager.addLayerFile(file, id, name, user);
+    } catch (Exception e) {
+      response.setError(true);
+      response.setMessage(e.getMessage());
+    }
+
+    return ResponseEntity.ok(response);
+  }
+
+  private User getCurrentUser() {
+    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+
+    if (!(auth instanceof AnonymousAuthenticationToken)) {
+      if (auth.getPrincipal() instanceof org.springframework.security.core.userdetails.User) return null;
+      String username = (String) auth.getPrincipal();
+      return userManager.getUserByUsername(username);
+    } else {
+      return null;
+    }
+  }
+}
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/web/ModelController.java b/mozen/src/main/java/mozen/web/ModelController.java
index a3817d1..2603aa5 100644
--- a/mozen/src/main/java/mozen/web/ModelController.java
+++ b/mozen/src/main/java/mozen/web/ModelController.java
@@ -21,13 +21,9 @@ import org.springframework.web.multipart.MultipartFile;
 
 import mozen.business.IModelManager;
 import mozen.business.IUserManager;
-import mozen.model.CustomLayer;
 import mozen.model.Model;
 import mozen.messages.ModelMessage;
 import mozen.messages.ResponseMessage;
-import mozen.messages.TagCategoryMessage;
-import mozen.messages.TagMessage;
-import mozen.model.TagCategory;
 import mozen.model.User;
 
 import org.springframework.web.bind.annotation.PostMapping;
@@ -122,35 +118,6 @@ public class ModelController {
     return modelManager.getModels();
   }
 
-  @GetMapping("/tags")
-  public Collection<TagCategory> getTags() {
-    return modelManager.getTags();
-  }
-
-  @PostMapping("/tags")
-  public ResponseEntity<ResponseMessage> addTag(@RequestBody @Valid TagMessage message) {
-    modelManager.addTag(message);
-    return ResponseEntity.ok().build();
-  }
-
-  @DeleteMapping("/tags")
-  public ResponseEntity<ResponseMessage> deleteTag(@RequestParam(value = "id", required = true) Long id) {
-    modelManager.removeTag(id);
-    return ResponseEntity.ok().build();
-  }
-
-  @PostMapping("/category")
-  public ResponseEntity<ResponseMessage> addCategory(@RequestBody @Valid TagCategoryMessage message) {
-    modelManager.addCategory(message);
-    return ResponseEntity.ok().build();
-  }
-
-  @DeleteMapping("/category")
-  public ResponseEntity<ResponseMessage> deleteCategory(@RequestParam(value = "id", required = true) Long id) {
-    modelManager.removeCategory(id);
-    return ResponseEntity.ok().build();
-  }
-
   @PostMapping("/upload")
   public ResponseEntity<ResponseMessage> uploadModelFile(@RequestParam("file") MultipartFile file, @RequestParam(value = "id", required = true) Long id) {
     ResponseMessage response = new ResponseMessage(false, "");
@@ -190,48 +157,6 @@ public class ModelController {
     return ResponseEntity.ok(response);
   }
 
-  @GetMapping("/downloadLayer")
-  public ResponseEntity<?> downloadLayerFile(@RequestParam(value = "id", required = true) Long id) {
-    ResponseMessage response = new ResponseMessage(false, "");
-  
-    try {
-      CustomLayer layer = modelManager.getLayer(id);
-      return ResponseEntity.ok()
-        .contentType(MediaType.parseMediaType(layer.getFileType()))
-        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + layer.getName() + "\"")
-        .body(new ByteArrayResource(layer.getFile()));
-    } catch (Exception e) {
-      response.setError(true);
-      response.setMessage(e.getMessage());
-    }
-
-    return ResponseEntity.ok(response);
-  }
-
-  @PostMapping("/uploadLayer")
-  public ResponseEntity<ResponseMessage> uploadLayerFile(
-    @RequestParam("file") MultipartFile file, 
-    @RequestParam(value = "id", required = true) Long id,
-    @RequestParam(value = "name", required = true) String name) {
-    ResponseMessage response = new ResponseMessage(false, "");
-    User user = getCurrentUser();
-    if(user == null) {
-      response.setError(true);
-      response.setMessage("User unknown");
-      return ResponseEntity.ok(response);
-    }
-  
-    try {
-      System.err.println("[MODEL CONTROLLER] layer file upload f:"+file.getName()+" n:"+name);
-      modelManager.addLayerFile(file, id, name, user);
-    } catch (Exception e) {
-      response.setError(true);
-      response.setMessage(e.getMessage());
-    }
-
-    return ResponseEntity.ok(response);
-  }
-
   private User getCurrentUser() {
     Authentication auth = SecurityContextHolder.getContext().getAuthentication();
 
diff --git a/mozen/src/main/java/mozen/web/TagController.java b/mozen/src/main/java/mozen/web/TagController.java
new file mode 100644
index 0000000..66f4721
--- /dev/null
+++ b/mozen/src/main/java/mozen/web/TagController.java
@@ -0,0 +1,59 @@
+package mozen.web;
+
+import java.util.Collection;
+
+import javax.validation.Valid;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import mozen.business.ITagManager;
+import mozen.messages.ResponseMessage;
+import mozen.messages.TagCategoryMessage;
+import mozen.messages.TagMessage;
+import mozen.model.TagCategory;
+
+@RestController
+@RequestMapping("/tags")
+@CrossOrigin
+public class TagController {
+  @Autowired
+  ITagManager tagManager;
+
+  @GetMapping("/")
+  public Collection<TagCategory> getTags() {
+    return tagManager.getTags();
+  }
+
+  @PostMapping("/")
+  public ResponseEntity<ResponseMessage> addTag(@RequestBody @Valid TagMessage message) {
+    tagManager.addTag(message);
+    return ResponseEntity.ok().build();
+  }
+
+  @DeleteMapping("/")
+  public ResponseEntity<ResponseMessage> deleteTag(@RequestParam(value = "id", required = true) Long id) {
+    tagManager.removeTag(id);
+    return ResponseEntity.ok().build();
+  }
+
+  @PostMapping("/category")
+  public ResponseEntity<ResponseMessage> addCategory(@RequestBody @Valid TagCategoryMessage message) {
+    tagManager.addCategory(message);
+    return ResponseEntity.ok().build();
+  }
+
+  @DeleteMapping("/category")
+  public ResponseEntity<ResponseMessage> deleteCategory(@RequestParam(value = "id", required = true) Long id) {
+    tagManager.removeCategory(id);
+    return ResponseEntity.ok().build();
+  }
+}
\ No newline at end of file
-- 
GitLab