added dnet-orgs-database-application
This commit is contained in:
parent
f0e850f3db
commit
99bae13b31
|
@ -0,0 +1,5 @@
|
|||
1) Completare operazioni di insert/update sul db
|
||||
2) Migliorare ricerca (utilizzare fulltext search di postgres)
|
||||
3) Primo caricamento di organizzazioni da openaire (con prefisso openorgs____) con simrels
|
||||
4) Caricamenti successivi di nuove oganizazzioni
|
||||
5) Caricamenti successivi di nuove simrels
|
|
@ -0,0 +1,3 @@
|
|||
{"type_source": "SVN", "goal": "package -U source:jar",
|
||||
"url": "http://svn-public.driver.research-infrastructures.eu/driver/dnet45/modules/dnet-orgs-database-application/trunk/", "deploy_repository": "dnet45-snapshots", "version": "4", "mail": "sandro.labruzzo@isti.cnr.it,michele.artini@isti.cnr.it, claudio.atzori@isti.cnr.it, alessia.bardi@isti.cnr.it",
|
||||
"deploy_repository_url": "http://maven.research-infrastructures.eu/nexus/content/repositories/dnet45-snapshots", "name": "dnet-orgs-database-application"}
|
|
@ -0,0 +1,72 @@
|
|||
<?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">
|
||||
|
||||
<parent>
|
||||
<groupId>eu.dnetlib</groupId>
|
||||
<artifactId>apps</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>dnet-orgs-database-application</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-json</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
<version>3.0.4.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.vladmihalcea</groupId>
|
||||
<artifactId>hibernate-types-52</artifactId>
|
||||
<version>2.3.5</version>
|
||||
</dependency>
|
||||
|
||||
<!-- hot swapping, disable cache for template, enable live reload -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Swagger -->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>2.9.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>2.9.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
|
@ -0,0 +1,46 @@
|
|||
package eu.dnetlib.organizations;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableSwagger2
|
||||
@EnableCaching
|
||||
public class MainApplication {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MainApplication.class);
|
||||
|
||||
public static void main(final String[] args) {
|
||||
SpringApplication.run(MainApplication.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public static Docket newSwaggerDocket() {
|
||||
log.info("Initializing SWAGGER...");
|
||||
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.any())
|
||||
.paths(p -> p.startsWith("/api/"))
|
||||
.build().apiInfo(new ApiInfoBuilder()
|
||||
.title("D-Net Organizations Service APIs")
|
||||
.description("APIs documentation")
|
||||
.version("1.1")
|
||||
.contact(ApiInfo.DEFAULT_CONTACT)
|
||||
.license("Apache 2.0")
|
||||
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
|
||||
.build());
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package eu.dnetlib.organizations;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import eu.dnetlib.organizations.controller.UserInfo;
|
||||
|
||||
@Component
|
||||
public class MyAccessDeniedHandler implements AccessDeniedHandler {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(MyAccessDeniedHandler.class);
|
||||
|
||||
@Override
|
||||
public void handle(final HttpServletRequest req, final HttpServletResponse res, final AccessDeniedException e)
|
||||
throws IOException, ServletException {
|
||||
|
||||
final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
if (auth != null) {
|
||||
logger.warn(String.format("User '%s' attempted to access the protected URL: %s", auth.getName(), req.getRequestURI()));
|
||||
}
|
||||
|
||||
if (UserInfo.isNotAuthorized(auth)) {
|
||||
res.sendRedirect(req.getContextPath() + "/authorizationRequest");
|
||||
} else {
|
||||
res.sendRedirect(req.getContextPath() + "/alreadyRegistered");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package eu.dnetlib.organizations;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
|
||||
import eu.dnetlib.organizations.controller.UserRole;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Autowired
|
||||
private AccessDeniedHandler accessDeniedHandler;
|
||||
|
||||
@Override
|
||||
protected void configure(final HttpSecurity http) throws Exception {
|
||||
|
||||
http.csrf()
|
||||
.disable()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/", "/api/**")
|
||||
.hasAnyRole(UserRole.ADMIN.name(), UserRole.NATIONAL_ADMIN.name(), UserRole.USER.name())
|
||||
.antMatchers("/registration_api/**")
|
||||
.hasRole(UserRole.NOT_AUTHORIZED.name())
|
||||
.antMatchers("/resources/**", "/webjars/**")
|
||||
.permitAll()
|
||||
.anyRequest()
|
||||
.authenticated()
|
||||
.and()
|
||||
.formLogin()
|
||||
.loginPage("/login")
|
||||
.permitAll()
|
||||
.and()
|
||||
.logout()
|
||||
.permitAll()
|
||||
.and()
|
||||
.exceptionHandling()
|
||||
.accessDeniedHandler(accessDeniedHandler);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.jdbcAuthentication()
|
||||
.dataSource(dataSource)
|
||||
.usersByUsernameQuery("select ?, '{MD5}60c4a0eb167dd41e915a885f582414df', true") // TODO: this is a MOCK, the user should
|
||||
// be authenticated using the openaire
|
||||
// credentials
|
||||
.authoritiesByUsernameQuery("with const as (SELECT ? as email) "
|
||||
+ "select c.email, 'ROLE_'||coalesce(u.role, '"
|
||||
+ UserRole.NOT_AUTHORIZED
|
||||
+ "') from const c left outer join users u on (u.email = c.email)");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package eu.dnetlib.organizations.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
@Controller
|
||||
public class HomeController {
|
||||
|
||||
@GetMapping("/")
|
||||
public String home() {
|
||||
return "home";
|
||||
}
|
||||
|
||||
@GetMapping("/login")
|
||||
public String login() {
|
||||
return "login";
|
||||
}
|
||||
|
||||
@GetMapping("/authorizationRequest")
|
||||
public String authorizationRequest() {
|
||||
return "authorizationRequest";
|
||||
}
|
||||
|
||||
@GetMapping("/alreadyRegistered")
|
||||
public String alreadyRegistered() {
|
||||
return "alreadyRegistered";
|
||||
}
|
||||
|
||||
@RequestMapping(value = { "/doc", "/swagger" }, method = RequestMethod.GET)
|
||||
public String apiDoc() {
|
||||
return "redirect:swagger-ui.html";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,270 @@
|
|||
package eu.dnetlib.organizations.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import eu.dnetlib.organizations.model.OpenaireDuplicate;
|
||||
import eu.dnetlib.organizations.model.Relationship;
|
||||
import eu.dnetlib.organizations.model.utils.BrowseEntry;
|
||||
import eu.dnetlib.organizations.model.utils.OrganizationConflict;
|
||||
import eu.dnetlib.organizations.model.utils.OrganizationConflictImpl;
|
||||
import eu.dnetlib.organizations.model.view.ConflictGroupView;
|
||||
import eu.dnetlib.organizations.model.view.DuplicateGroupView;
|
||||
import eu.dnetlib.organizations.model.view.OrganizationInfoView;
|
||||
import eu.dnetlib.organizations.model.view.OrganizationSimpleView;
|
||||
import eu.dnetlib.organizations.model.view.OrganizationView;
|
||||
import eu.dnetlib.organizations.repository.OpenaireConflictRepository;
|
||||
import eu.dnetlib.organizations.repository.OpenaireDuplicateRepository;
|
||||
import eu.dnetlib.organizations.repository.UserCountryRepository;
|
||||
import eu.dnetlib.organizations.repository.readonly.ConflictGroupViewRepository;
|
||||
import eu.dnetlib.organizations.repository.readonly.DuplicateGroupViewRepository;
|
||||
import eu.dnetlib.organizations.repository.readonly.OrganizationInfoViewRepository;
|
||||
import eu.dnetlib.organizations.repository.readonly.OrganizationSimpleViewRepository;
|
||||
import eu.dnetlib.organizations.repository.readonly.OrganizationViewRepository;
|
||||
import eu.dnetlib.organizations.repository.readonly.SuggestionInfoViewByCountryRepository;
|
||||
import eu.dnetlib.organizations.utils.DatabaseUtils;
|
||||
import eu.dnetlib.organizations.utils.RelationType;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/organizations")
|
||||
public class OrganizationController {
|
||||
|
||||
@Autowired
|
||||
private OrganizationViewRepository organizationViewRepository;
|
||||
@Autowired
|
||||
private OrganizationInfoViewRepository organizationInfoViewRepository;
|
||||
@Autowired
|
||||
private OrganizationSimpleViewRepository organizationSimpleViewRepository;
|
||||
@Autowired
|
||||
private OpenaireDuplicateRepository openaireDuplicateRepository;
|
||||
@Autowired
|
||||
private OpenaireConflictRepository openaireConflictRepository;
|
||||
@Autowired
|
||||
private ConflictGroupViewRepository conflictGroupViewRepository;
|
||||
@Autowired
|
||||
private SuggestionInfoViewByCountryRepository suggestionInfoViewByCountryRepository;
|
||||
@Autowired
|
||||
private UserCountryRepository userCountryRepository;
|
||||
@Autowired
|
||||
private DuplicateGroupViewRepository duplicateGroupViewRepository;
|
||||
@Autowired
|
||||
private DatabaseUtils databaseUtils;
|
||||
|
||||
@RequestMapping(value = "/save", method = RequestMethod.POST)
|
||||
public List<String> save(@RequestBody final OrganizationView org, final Authentication authentication) {
|
||||
if (StringUtils.isBlank(org.getName())) {
|
||||
throw new RuntimeException("Missing field: name");
|
||||
} else if (StringUtils.isBlank(org.getCountry())) {
|
||||
throw new RuntimeException("Missing field: country");
|
||||
} else if (StringUtils.isBlank(org.getType())) {
|
||||
throw new RuntimeException("Missing field: type");
|
||||
} else if (UserInfo.isSuperAdmin(authentication) || userCountryRepository.verifyAuthorizationForCountry(org.getCountry(), authentication.getName())) {
|
||||
final String orgId = databaseUtils.insertOrUpdateOrganization(org, authentication.getName(), StringUtils.isNotBlank(org.getId()));
|
||||
return Arrays.asList(orgId);
|
||||
} else {
|
||||
throw new RuntimeException("User not authorized");
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/info", method = RequestMethod.GET)
|
||||
public OrganizationInfoView infoById(@RequestParam final String id, final Authentication authentication) {
|
||||
return organizationInfoViewRepository.findById(id).get();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/suggestionsInfo", method = RequestMethod.GET)
|
||||
public SuggestionInfo suggestionsInfo(final Authentication authentication) {
|
||||
final SuggestionInfo info = new SuggestionInfo();
|
||||
|
||||
if (UserInfo.isSuperAdmin(authentication)) {
|
||||
suggestionInfoViewByCountryRepository.findAll().forEach(info::add);
|
||||
} else if (UserInfo.isSimpleUser(authentication) || UserInfo.isNationalAdmin(authentication)) {
|
||||
userCountryRepository.getCountriesForUser(authentication.getName())
|
||||
.stream()
|
||||
.map(suggestionInfoViewByCountryRepository::findById)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.forEach(info::add);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/get", method = RequestMethod.GET)
|
||||
public OrganizationView findById(@RequestParam final String id, final Authentication authentication) {
|
||||
final OrganizationView org = organizationViewRepository.findById(id).get();
|
||||
|
||||
if (UserInfo.isSuperAdmin(authentication) || userCountryRepository.verifyAuthorizationForCountry(org.getCountry(), authentication.getName())) {
|
||||
return org;
|
||||
} else {
|
||||
throw new RuntimeException("User not authorized");
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/conflicts", method = RequestMethod.GET)
|
||||
public List<OrganizationConflict> conflicts(@RequestParam final String id, final Authentication authentication) {
|
||||
if (UserInfo.isSuperAdmin(authentication) || userCountryRepository.verifyAuthorizationForId(id, authentication.getName())) {
|
||||
return openaireConflictRepository.getConflictsForId(id);
|
||||
} else {
|
||||
throw new RuntimeException("User not authorized");
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/duplicates", method = RequestMethod.GET)
|
||||
public List<OpenaireDuplicate> duplicates(@RequestParam final String id, final Authentication authentication) {
|
||||
if (UserInfo.isSuperAdmin(authentication) || userCountryRepository.verifyAuthorizationForId(id, authentication.getName())) {
|
||||
return openaireDuplicateRepository.findByLocalId(id);
|
||||
} else {
|
||||
throw new RuntimeException("User not authorized");
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/conflicts/byCountry/{country}", method = RequestMethod.GET)
|
||||
public Collection<Set<OrganizationConflictImpl>> findConflictsByCountry(@PathVariable final String country, final Authentication authentication) {
|
||||
|
||||
databaseUtils.verifyConflictGroups(false);
|
||||
|
||||
if (UserInfo.isSuperAdmin(authentication)) {
|
||||
return groupConflicts(conflictGroupViewRepository.findByCountry1OrCountry2(country, country).stream());
|
||||
} else if (UserInfo.isSimpleUser(authentication) || UserInfo.isNationalAdmin(authentication)) {
|
||||
final Stream<ConflictGroupView> list = userCountryRepository.getCountriesForUser(authentication.getName())
|
||||
.stream()
|
||||
.filter(country::equalsIgnoreCase)
|
||||
.map(c -> conflictGroupViewRepository.findByCountry1OrCountry2(c, c).stream())
|
||||
.findFirst()
|
||||
.orElse(Stream.empty());
|
||||
return groupConflicts(list);
|
||||
} else {
|
||||
throw new RuntimeException("User not authorized");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/duplicates/byCountry/{country}", method = RequestMethod.GET)
|
||||
public Iterable<DuplicateGroupView> findDuplicatesByCountry(@PathVariable final String country, final Authentication authentication) {
|
||||
|
||||
if (UserInfo.isSuperAdmin(authentication)) {
|
||||
return duplicateGroupViewRepository.findByCountry(country);
|
||||
} else if (UserInfo.isSimpleUser(authentication) || UserInfo.isNationalAdmin(authentication)) {
|
||||
return userCountryRepository.getCountriesForUser(authentication.getName())
|
||||
.stream()
|
||||
.filter(country::equalsIgnoreCase)
|
||||
.map(duplicateGroupViewRepository::findByCountry)
|
||||
.findFirst()
|
||||
.orElse(new ArrayList<DuplicateGroupView>());
|
||||
} else {
|
||||
throw new RuntimeException("User not authorized");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Collection<Set<OrganizationConflictImpl>> groupConflicts(final Stream<ConflictGroupView> stream) {
|
||||
final Map<String, Set<OrganizationConflictImpl>> map = new TreeMap<>();
|
||||
stream.forEach(c -> {
|
||||
if (!map.containsKey(c.getGroup())) {
|
||||
map.put(c.getGroup(), new TreeSet<>());
|
||||
}
|
||||
map.get(c.getGroup()).add(new OrganizationConflictImpl(c.getId1(), c.getName1(), c.getType1(), c.getCity1(), c.getCountry1()));
|
||||
map.get(c.getGroup()).add(new OrganizationConflictImpl(c.getId2(), c.getName2(), c.getType2(), c.getCity2(), c.getCountry2()));
|
||||
});
|
||||
return map.values();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/duplicates", method = RequestMethod.POST)
|
||||
public List<OpenaireDuplicate> duplicates(@RequestBody final List<OpenaireDuplicate> simrels, final Authentication authentication) {
|
||||
|
||||
final boolean b = UserInfo.isSuperAdmin(authentication)
|
||||
|| simrels.stream()
|
||||
.map(OpenaireDuplicate::getLocalId)
|
||||
.distinct()
|
||||
.allMatch(id -> userCountryRepository.verifyAuthorizationForId(id, authentication.getName()));
|
||||
|
||||
if (b) {
|
||||
return openaireDuplicateRepository.saveAll(simrels);
|
||||
} else {
|
||||
throw new RuntimeException("User not authorized");
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/search/{page}/{size}", method = RequestMethod.GET)
|
||||
public Page<OrganizationSimpleView> search(@PathVariable final int page,
|
||||
@PathVariable final int size,
|
||||
@RequestParam final String q,
|
||||
final Authentication authentication) {
|
||||
return UserInfo.isSuperAdmin(authentication)
|
||||
? organizationSimpleViewRepository.findByNameContainingIgnoreCase(q, PageRequest.of(page, size))
|
||||
: organizationSimpleViewRepository.findByNameForUser(q, authentication.getName(), PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/byCountry/{code}/{page}/{size}", method = RequestMethod.GET)
|
||||
public Page<OrganizationSimpleView> findByCountry(@PathVariable final String code,
|
||||
@PathVariable final int page,
|
||||
@PathVariable final int size,
|
||||
final Authentication authentication) {
|
||||
if (UserInfo.isSuperAdmin(authentication) || userCountryRepository.verifyAuthorizationForCountry(code, authentication.getName())) {
|
||||
return organizationSimpleViewRepository.findByCountry(code, PageRequest.of(page, size));
|
||||
} else {
|
||||
throw new RuntimeException("User not authorized");
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/byType/{type}/{page}/{size}", method = RequestMethod.GET)
|
||||
public Page<OrganizationSimpleView> findByType(@PathVariable final String type,
|
||||
@PathVariable final int page,
|
||||
@PathVariable final int size,
|
||||
final Authentication authentication) {
|
||||
return UserInfo.isSuperAdmin(authentication)
|
||||
? organizationSimpleViewRepository.findByType(type, PageRequest.of(page, size))
|
||||
: organizationSimpleViewRepository.findByTypeForUser(type, authentication.getName(), PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/browse/countries", method = RequestMethod.GET)
|
||||
public List<BrowseEntry> browseCountries(final Authentication authentication) {
|
||||
return UserInfo.isSuperAdmin(authentication)
|
||||
? organizationSimpleViewRepository.browseCountries()
|
||||
: organizationSimpleViewRepository.browseCountriesForUser(authentication.getName());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/browse/types", method = RequestMethod.GET)
|
||||
public List<BrowseEntry> browseOrganizationTypes(final Authentication authentication) {
|
||||
return UserInfo.isSuperAdmin(authentication)
|
||||
? organizationSimpleViewRepository.browseTypes()
|
||||
: organizationSimpleViewRepository.browseTypesForUser(authentication.getName());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/conflicts/fix/{masterId}", method = RequestMethod.POST)
|
||||
public List<Relationship> fixConflicts(final Authentication authentication, @PathVariable final String masterId, @RequestBody final List<String> otherIds) {
|
||||
if (UserInfo.isSuperAdmin(authentication) || userCountryRepository.verifyAuthorizationForId(masterId, authentication.getName())) {
|
||||
|
||||
return otherIds.stream()
|
||||
.filter(id -> UserInfo.isSuperAdmin(authentication) || userCountryRepository.verifyAuthorizationForId(id, authentication.getName()))
|
||||
.map(id -> databaseUtils.makeRelation(masterId, id, RelationType.Merges))
|
||||
.flatMap(List::stream)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package eu.dnetlib.organizations.controller;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import eu.dnetlib.organizations.model.view.SuggestionInfoViewByCountry;
|
||||
|
||||
public class SuggestionInfo {
|
||||
|
||||
public class SuggestionCounter {
|
||||
|
||||
private long nDuplicates = 0;
|
||||
|
||||
private long nConflicts = 0;
|
||||
|
||||
public long getnDuplicates() {
|
||||
return nDuplicates;
|
||||
}
|
||||
|
||||
public void setnDuplicates(final long nDuplicates) {
|
||||
this.nDuplicates = nDuplicates;
|
||||
}
|
||||
|
||||
public long getnConflicts() {
|
||||
return nConflicts;
|
||||
}
|
||||
|
||||
public void setnConflicts(final long nConflicts) {
|
||||
this.nConflicts = nConflicts;
|
||||
}
|
||||
|
||||
public void add(final SuggestionInfoViewByCountry infoCountry) {
|
||||
nDuplicates += infoCountry.getnDuplicates();
|
||||
nConflicts += infoCountry.getnConflicts();
|
||||
}
|
||||
}
|
||||
|
||||
public SuggestionCounter total = new SuggestionCounter();;
|
||||
|
||||
public Map<String, SuggestionCounter> byCountry = new LinkedHashMap<>();
|
||||
|
||||
public void add(final SuggestionInfoViewByCountry infoCountry) {
|
||||
final String country = infoCountry.getCountry();
|
||||
|
||||
if (!byCountry.containsKey(country)) {
|
||||
byCountry.put(country, new SuggestionCounter());
|
||||
|
||||
}
|
||||
byCountry.get(country).add(infoCountry);
|
||||
total.add(infoCountry);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package eu.dnetlib.organizations.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.Authentication;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import eu.dnetlib.organizations.model.view.UserView;
|
||||
import eu.dnetlib.organizations.repository.UserRepository;
|
||||
import eu.dnetlib.organizations.repository.readonly.UserViewRepository;
|
||||
import eu.dnetlib.organizations.utils.DatabaseUtils;
|
||||
|
||||
@RestController
|
||||
public class UserController {
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Autowired
|
||||
private UserViewRepository userViewRepository;
|
||||
@Autowired
|
||||
private DatabaseUtils dbUtils;
|
||||
|
||||
@PostMapping(value = "/registration_api/newUser")
|
||||
public Map<String, Integer> newUser(final @RequestBody List<String> countries, final Authentication authentication) {
|
||||
|
||||
final String email = authentication.getName();
|
||||
|
||||
final Map<String, Integer> res = new HashMap<>();
|
||||
|
||||
if (!UserInfo.isNotAuthorized(authentication) || userRepository.existsById(email)) {
|
||||
res.put("status", 2);
|
||||
} else {
|
||||
dbUtils.newUser(email, countries);
|
||||
res.put("status", 1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@GetMapping("/api/users")
|
||||
public Iterable<UserView> users(final Authentication authentication) {
|
||||
if (UserInfo.isSuperAdmin(authentication)) {
|
||||
return userViewRepository.findAll();
|
||||
} else if (UserInfo.isNationalAdmin(authentication)) {
|
||||
|
||||
// IMPORTANT: a national admin can manage ONLY the users where ALL the countries are under his control
|
||||
final List<UserView> res = new ArrayList<>();
|
||||
final List<String> myCountries = dbUtils.listCountriesForUser(authentication.getName());
|
||||
|
||||
for (final UserView uw : userViewRepository.findAll()) {
|
||||
if (uw.getCountries() != null && uw.getCountries().length > 0 && myCountries.containsAll(Arrays.asList(uw.getCountries()))) {
|
||||
res.add(uw);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/api/users")
|
||||
public Iterable<UserView> save(@RequestBody final UserView userView, final Authentication authentication) {
|
||||
if (authentication.getName().equals(userView.getEmail())) { throw new RuntimeException("You can't edit your own user"); }
|
||||
dbUtils.saveUser(userView);
|
||||
return users(authentication);
|
||||
}
|
||||
|
||||
@DeleteMapping("/api/users")
|
||||
public Iterable<UserView> delete(final @RequestParam String email, final Authentication authentication) {
|
||||
if (authentication.getName().equals(email)) { throw new RuntimeException("You can't delete your own user"); }
|
||||
dbUtils.deleteUser(email);
|
||||
return users(authentication);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package eu.dnetlib.organizations.controller;
|
||||
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
||||
public class UserInfo {
|
||||
|
||||
private String name;
|
||||
private UserRole role;
|
||||
|
||||
public UserInfo() {
|
||||
this.name = "anonymous";
|
||||
this.role = UserRole.NOT_AUTHORIZED;
|
||||
}
|
||||
|
||||
public UserInfo(final String name, final UserRole role) {
|
||||
this.name = name;
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public UserRole getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(final UserRole role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public static UserInfo generate(final Authentication authentication) {
|
||||
return new UserInfo(authentication.getName(), findRole(authentication));
|
||||
}
|
||||
|
||||
public static UserRole findRole(final Authentication authentication) {
|
||||
return authentication.getAuthorities()
|
||||
.stream()
|
||||
.map(GrantedAuthority::getAuthority)
|
||||
.map(s -> StringUtils.substringAfter(s, "ROLE_"))
|
||||
.filter(s -> EnumUtils.isValidEnum(UserRole.class, s))
|
||||
.map(UserRole::valueOf)
|
||||
.findFirst()
|
||||
.orElseGet(() -> UserRole.NOT_AUTHORIZED);
|
||||
}
|
||||
|
||||
public static boolean isSuperAdmin(final Authentication authentication) {
|
||||
for (final GrantedAuthority aut : authentication.getAuthorities()) {
|
||||
if (aut.getAuthority().equals("ROLE_" + UserRole.ADMIN)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isNationalAdmin(final Authentication authentication) {
|
||||
for (final GrantedAuthority aut : authentication.getAuthorities()) {
|
||||
if (aut.getAuthority().equals("ROLE_" + UserRole.NATIONAL_ADMIN)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isSimpleUser(final Authentication authentication) {
|
||||
for (final GrantedAuthority aut : authentication.getAuthorities()) {
|
||||
if (aut.getAuthority().equals("ROLE_" + UserRole.USER)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isPending(final Authentication authentication) {
|
||||
for (final GrantedAuthority aut : authentication.getAuthorities()) {
|
||||
if (aut.getAuthority().equals("ROLE_" + UserRole.PENDING)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isNotAuthorized(final Authentication authentication) {
|
||||
for (final GrantedAuthority aut : authentication.getAuthorities()) {
|
||||
if (aut.getAuthority().equals("ROLE_" + UserRole.NOT_AUTHORIZED)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package eu.dnetlib.organizations.controller;
|
||||
|
||||
public enum UserRole {
|
||||
USER, ADMIN, NATIONAL_ADMIN, PENDING, NOT_AUTHORIZED
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package eu.dnetlib.organizations.controller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import eu.dnetlib.organizations.utils.DatabaseUtils;
|
||||
import eu.dnetlib.organizations.utils.DatabaseUtils.VocabularyTable;
|
||||
import eu.dnetlib.organizations.utils.RelationType;
|
||||
import eu.dnetlib.organizations.utils.SimilarityType;
|
||||
|
||||
@RestController
|
||||
public class VocabulariesController {
|
||||
|
||||
@Autowired
|
||||
private DatabaseUtils databaseUtils;
|
||||
|
||||
@GetMapping("/api/vocabularies")
|
||||
public Map<String, List<String>> ListVocabularies(final Authentication authentication) {
|
||||
final Map<String, List<String>> vocs = new HashMap<>();
|
||||
vocs.put("orgTypes", databaseUtils.listValuesOfVocabularyTable(VocabularyTable.org_types));
|
||||
vocs.put("idTypes", databaseUtils.listValuesOfVocabularyTable(VocabularyTable.id_types));
|
||||
vocs.put("languages", databaseUtils.listValuesOfVocabularyTable(VocabularyTable.languages));
|
||||
|
||||
vocs.put("relTypes", Arrays.stream(RelationType.values()).map(Object::toString).collect(Collectors.toList()));
|
||||
vocs.put("similaritiesType", Arrays.stream(SimilarityType.values()).map(Object::toString).collect(Collectors.toList()));
|
||||
|
||||
if (UserInfo.isSimpleUser(authentication) || UserInfo.isNationalAdmin(authentication)) {
|
||||
vocs.put("countries", databaseUtils.listCountriesForUser(authentication.getName()));
|
||||
} else if (UserInfo.isSuperAdmin(authentication)) {
|
||||
vocs.put("countries", databaseUtils.listValuesOfVocabularyTable(VocabularyTable.countries));
|
||||
} else {
|
||||
vocs.put("countries", new ArrayList<String>());
|
||||
}
|
||||
|
||||
return vocs;
|
||||
}
|
||||
|
||||
@GetMapping({ "/api/voc/allCountries", "/registration_api/voc/allCountries" })
|
||||
public List<String> allCountries() {
|
||||
return databaseUtils.listValuesOfVocabularyTable(VocabularyTable.countries);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "acronyms")
|
||||
@IdClass(AcronymPK.class)
|
||||
public class Acronym implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1521008848879976517L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private String orgId;
|
||||
|
||||
@Id
|
||||
@Column(name = "acronym")
|
||||
private String acronym;
|
||||
|
||||
public Acronym() {}
|
||||
|
||||
public Acronym(final String orgId, final String acronym) {
|
||||
this.orgId = orgId;
|
||||
this.acronym = acronym;
|
||||
}
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(final String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getAcronym() {
|
||||
return acronym;
|
||||
}
|
||||
|
||||
public void setAcronym(final String acronym) {
|
||||
this.acronym = acronym;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class AcronymPK implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -7771532658881429064L;
|
||||
|
||||
private String orgId;
|
||||
|
||||
private String acronym;
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(final String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getAcronym() {
|
||||
return acronym;
|
||||
}
|
||||
|
||||
public void setAcronym(final String acronym) {
|
||||
this.acronym = acronym;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(acronym, orgId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof AcronymPK)) { return false; }
|
||||
final AcronymPK other = (AcronymPK) obj;
|
||||
return Objects.equals(acronym, other.acronym) && Objects.equals(orgId, other.orgId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("AcronymPK [orgId=%s, acronym=%s]", orgId, acronym);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "oa_conflicts")
|
||||
@IdClass(OpenaireConflictPK.class)
|
||||
public class OpenaireConflict implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -5143344657695218270L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id1")
|
||||
private String id1;
|
||||
|
||||
@Id
|
||||
@Column(name = "id2")
|
||||
private String id2;
|
||||
|
||||
@Column(name = "reltype")
|
||||
private String relType;
|
||||
|
||||
@Column(name = "idgroup")
|
||||
private String group;
|
||||
|
||||
public OpenaireConflict() {}
|
||||
|
||||
public OpenaireConflict(final String id1, final String id2, final String relType, final String group) {
|
||||
this.id1 = id1;
|
||||
this.id2 = id2;
|
||||
this.relType = relType;
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public String getId1() {
|
||||
return id1;
|
||||
}
|
||||
|
||||
public void setId1(final String id1) {
|
||||
this.id1 = id1;
|
||||
}
|
||||
|
||||
public String getId2() {
|
||||
return id2;
|
||||
}
|
||||
|
||||
public void setId2(final String id2) {
|
||||
this.id2 = id2;
|
||||
}
|
||||
|
||||
public String getRelType() {
|
||||
return relType;
|
||||
}
|
||||
|
||||
public void setRelType(final String relType) {
|
||||
this.relType = relType;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setGroup(final String group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class OpenaireConflictPK implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 6752695921988906962L;
|
||||
|
||||
private String id1;
|
||||
|
||||
private String id2;
|
||||
|
||||
public OpenaireConflictPK() {}
|
||||
|
||||
public OpenaireConflictPK(final String id1, final String id2) {
|
||||
this.id1 = id1;
|
||||
this.id2 = id2;
|
||||
}
|
||||
|
||||
public String getId1() {
|
||||
return id1;
|
||||
}
|
||||
|
||||
public void setId1(final String id1) {
|
||||
this.id1 = id1;
|
||||
}
|
||||
|
||||
public String getId2() {
|
||||
return id2;
|
||||
}
|
||||
|
||||
public void setId2(final String id2) {
|
||||
this.id2 = id2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id1, id2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof OpenaireConflictPK)) { return false; }
|
||||
final OpenaireConflictPK other = (OpenaireConflictPK) obj;
|
||||
return Objects.equals(id1, other.id1) && Objects.equals(id2, other.id2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("OpenaireConflictPK [id1=%s, id2=%s]", id1, id2);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "oa_duplicates")
|
||||
@IdClass(OpenaireDuplicatePK.class)
|
||||
public class OpenaireDuplicate implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -5656204073481770618L;
|
||||
|
||||
@Id
|
||||
@Column(name = "local_id")
|
||||
private String localId;
|
||||
|
||||
@Id
|
||||
@Column(name = "oa_original_id")
|
||||
private String oaOriginalId;
|
||||
|
||||
@Column(name = "oa_name")
|
||||
private String oaName;
|
||||
|
||||
@Column(name = "oa_acronym")
|
||||
private String oaAcronym;
|
||||
|
||||
@Column(name = "oa_country")
|
||||
private String oaCountry;
|
||||
|
||||
@Column(name = "oa_url")
|
||||
private String oaUrl;
|
||||
|
||||
@Column(name = "oa_collectedfrom")
|
||||
private String oaCollectedFrom;
|
||||
|
||||
@Column(name = "reltype")
|
||||
private String relType;
|
||||
|
||||
public String getLocalId() {
|
||||
return localId;
|
||||
}
|
||||
|
||||
public void setLocalId(final String localId) {
|
||||
this.localId = localId;
|
||||
}
|
||||
|
||||
public String getOaOriginalId() {
|
||||
return oaOriginalId;
|
||||
}
|
||||
|
||||
public void setOaOriginalId(final String oaOriginalId) {
|
||||
this.oaOriginalId = oaOriginalId;
|
||||
}
|
||||
|
||||
public String getOaName() {
|
||||
return oaName;
|
||||
}
|
||||
|
||||
public void setOaName(final String oaName) {
|
||||
this.oaName = oaName;
|
||||
}
|
||||
|
||||
public String getOaAcronym() {
|
||||
return oaAcronym;
|
||||
}
|
||||
|
||||
public void setOaAcronym(final String oaAcronym) {
|
||||
this.oaAcronym = oaAcronym;
|
||||
}
|
||||
|
||||
public String getOaCountry() {
|
||||
return oaCountry;
|
||||
}
|
||||
|
||||
public void setOaCountry(final String oaCountry) {
|
||||
this.oaCountry = oaCountry;
|
||||
}
|
||||
|
||||
public String getOaUrl() {
|
||||
return oaUrl;
|
||||
}
|
||||
|
||||
public void setOaUrl(final String oaUrl) {
|
||||
this.oaUrl = oaUrl;
|
||||
}
|
||||
|
||||
public String getOaCollectedFrom() {
|
||||
return oaCollectedFrom;
|
||||
}
|
||||
|
||||
public void setOaCollectedFrom(final String oaCollectedFrom) {
|
||||
this.oaCollectedFrom = oaCollectedFrom;
|
||||
}
|
||||
|
||||
public String getRelType() {
|
||||
return relType;
|
||||
}
|
||||
|
||||
public void setRelType(final String relType) {
|
||||
this.relType = relType;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class OpenaireDuplicatePK implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 2546257975404466712L;
|
||||
|
||||
private String localId;
|
||||
private String oaOriginalId;
|
||||
|
||||
public String getLocalId() {
|
||||
return localId;
|
||||
}
|
||||
|
||||
public void setLocalId(final String localId) {
|
||||
this.localId = localId;
|
||||
}
|
||||
|
||||
public String getOaOriginalId() {
|
||||
return oaOriginalId;
|
||||
}
|
||||
|
||||
public void setOaOriginalId(final String oaOriginalId) {
|
||||
this.oaOriginalId = oaOriginalId;
|
||||
};
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(localId, oaOriginalId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof OpenaireDuplicatePK)) { return false; }
|
||||
final OpenaireDuplicatePK other = (OpenaireDuplicatePK) obj;
|
||||
return Objects.equals(localId, other.localId) && Objects.equals(oaOriginalId, other.oaOriginalId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("OpenaireDuplicatePK [localId=%s, oaOriginalId=%s]", localId, oaOriginalId);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "organizations")
|
||||
public class Organization implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 5563256467964495301L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private String id;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "type")
|
||||
private String type;
|
||||
|
||||
@Column(name = "lat")
|
||||
private Double lat;
|
||||
|
||||
@Column(name = "lng")
|
||||
private Double lng;
|
||||
|
||||
@Column(name = "city")
|
||||
private String city;
|
||||
|
||||
@Column(name = "country")
|
||||
private String country;
|
||||
|
||||
public Organization() {}
|
||||
|
||||
public Organization(final String id, final String name, final String type, final Double lat, final Double lng, final String city, final String country) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.lat = lat;
|
||||
this.lng = lng;
|
||||
this.city = city;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Double getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public void setLat(final Double lat) {
|
||||
this.lat = lat;
|
||||
}
|
||||
|
||||
public Double getLng() {
|
||||
return lng;
|
||||
}
|
||||
|
||||
public void setLng(final Double lng) {
|
||||
this.lng = lng;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(final String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(final String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "other_ids")
|
||||
@IdClass(OtherIdentifierPK.class)
|
||||
public class OtherIdentifier implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -8290245353090885241L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private String orgId;
|
||||
|
||||
@Id
|
||||
@Column(name = "otherid")
|
||||
private String otherId;
|
||||
|
||||
@Id
|
||||
@Column(name = "type")
|
||||
private String type;
|
||||
|
||||
public OtherIdentifier() {}
|
||||
|
||||
public OtherIdentifier(final String orgId, final String otherId, final String type) {
|
||||
this.orgId = orgId;
|
||||
this.otherId = otherId;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(final String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getOtherId() {
|
||||
return otherId;
|
||||
}
|
||||
|
||||
public void setOtherId(final String otherId) {
|
||||
this.otherId = otherId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class OtherIdentifierPK implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -3525128185006173748L;
|
||||
|
||||
private String orgId;
|
||||
private String otherId;
|
||||
private String type;
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(final String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getOtherId() {
|
||||
return otherId;
|
||||
}
|
||||
|
||||
public void setOtherId(final String otherId) {
|
||||
this.otherId = otherId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orgId, otherId, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof OtherIdentifierPK)) { return false; }
|
||||
final OtherIdentifierPK other = (OtherIdentifierPK) obj;
|
||||
return Objects.equals(orgId, other.orgId) && Objects.equals(otherId, other.otherId) && Objects.equals(type, other.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("OtherIdentifierPK [orgId=%s, otherId=%s, type=%s]", orgId, otherId, type);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "other_names")
|
||||
@IdClass(OtherNamePK.class)
|
||||
public class OtherName implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -5212012138309835912L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private String orgId;
|
||||
|
||||
@Id
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Id
|
||||
@Column(name = "lang")
|
||||
private String lang;
|
||||
|
||||
public OtherName() {}
|
||||
|
||||
public OtherName(final String orgId, final String name, final String lang) {
|
||||
this.orgId = orgId;
|
||||
this.name = name;
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(final String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getLang() {
|
||||
return lang;
|
||||
}
|
||||
|
||||
public void setLang(final String lang) {
|
||||
this.lang = lang;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class OtherNamePK implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1225063182881256637L;
|
||||
|
||||
private String orgId;
|
||||
|
||||
private String name;
|
||||
|
||||
private String lang;
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(final String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getLang() {
|
||||
return lang;
|
||||
}
|
||||
|
||||
public void setLang(final String lang) {
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orgId, lang, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof OtherNamePK)) { return false; }
|
||||
final OtherNamePK other = (OtherNamePK) obj;
|
||||
return Objects.equals(orgId, other.orgId) && Objects.equals(lang, other.lang) && Objects.equals(name, other.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("OtherNamePK [orgId=%s, name=%s, lang=%s]", orgId, name, lang);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "relationships")
|
||||
@IdClass(RelationshipPK.class)
|
||||
public class Relationship implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -5700143694178113214L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id1")
|
||||
private String id1;
|
||||
|
||||
@Id
|
||||
@Column(name = "id2")
|
||||
private String id2;
|
||||
|
||||
@Id
|
||||
@Column(name = "reltype")
|
||||
private String relType;
|
||||
|
||||
public Relationship() {}
|
||||
|
||||
public Relationship(final String id1, final String id2, final String relType) {
|
||||
this.id1 = id1;
|
||||
this.id2 = id2;
|
||||
this.relType = relType;
|
||||
}
|
||||
|
||||
public String getId1() {
|
||||
return id1;
|
||||
}
|
||||
|
||||
public void setId1(final String id1) {
|
||||
this.id1 = id1;
|
||||
}
|
||||
|
||||
public String getId2() {
|
||||
return id2;
|
||||
}
|
||||
|
||||
public void setId2(final String id2) {
|
||||
this.id2 = id2;
|
||||
}
|
||||
|
||||
public String getRelType() {
|
||||
return relType;
|
||||
}
|
||||
|
||||
public void setRelType(final String relType) {
|
||||
this.relType = relType;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class RelationshipPK implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 6090016904833186505L;
|
||||
|
||||
private String id1;
|
||||
|
||||
private String id2;
|
||||
|
||||
private String relType;
|
||||
|
||||
public String getId1() {
|
||||
return id1;
|
||||
}
|
||||
|
||||
public void setId1(final String id1) {
|
||||
this.id1 = id1;
|
||||
}
|
||||
|
||||
public String getId2() {
|
||||
return id2;
|
||||
}
|
||||
|
||||
public void setId2(final String id2) {
|
||||
this.id2 = id2;
|
||||
}
|
||||
|
||||
public String getRelType() {
|
||||
return relType;
|
||||
}
|
||||
|
||||
public void setRelType(final String relType) {
|
||||
this.relType = relType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id1, id2, relType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof RelationshipPK)) { return false; }
|
||||
final RelationshipPK other = (RelationshipPK) obj;
|
||||
return Objects.equals(id1, other.id1) && Objects.equals(id2, other.id2) && Objects.equals(relType, other.relType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("RelationshipPK [id1=%s, id2=%s, relType=%s]", id1, id2, relType);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "urls")
|
||||
@IdClass(UrlPK.class)
|
||||
public class Url implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -5889020711423271565L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private String orgId;
|
||||
|
||||
@Id
|
||||
@Column(name = "url")
|
||||
private String url;
|
||||
|
||||
public Url() {}
|
||||
|
||||
public Url(final String orgId, final String url) {
|
||||
this.orgId = orgId;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(final String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(final String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class UrlPK implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 6459755341474103359L;
|
||||
|
||||
private String orgId;
|
||||
|
||||
private String url;
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(final String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(final String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orgId, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof UrlPK)) { return false; }
|
||||
final UrlPK other = (UrlPK) obj;
|
||||
return Objects.equals(orgId, other.orgId) && Objects.equals(url, other.url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("UrlPK [orgId=%s, urls=%s]", orgId, url);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
public class User implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -9062674086098391604L;
|
||||
|
||||
@Id
|
||||
@Column(name = "email")
|
||||
private String email;
|
||||
|
||||
@Column(name = "valid")
|
||||
private boolean valid;
|
||||
|
||||
@Column(name = "role")
|
||||
private String role;
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(final String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
public void setValid(final boolean valid) {
|
||||
this.valid = valid;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(final String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "user_countries")
|
||||
@IdClass(UserCountryPK.class)
|
||||
public class UserCountry implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 3493897777214583701L;
|
||||
|
||||
@Id
|
||||
@Column(name = "email")
|
||||
private String email;
|
||||
|
||||
@Id
|
||||
@Column(name = "country")
|
||||
private String country;
|
||||
|
||||
public UserCountry() {}
|
||||
|
||||
public UserCountry(final String email, final String country) {
|
||||
this.email = email;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(final String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(final String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package eu.dnetlib.organizations.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class UserCountryPK implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 2003686130380208901L;
|
||||
|
||||
private String email;
|
||||
|
||||
private String country;
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(final String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(final String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(country, email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof UserCountryPK)) { return false; }
|
||||
final UserCountryPK other = (UserCountryPK) obj;
|
||||
return Objects.equals(country, other.country) && Objects.equals(email, other.email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("UserCountryPK [email=%s, country=%s]", email, country);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package eu.dnetlib.organizations.model.utils;
|
||||
|
||||
public interface BrowseEntry {
|
||||
|
||||
String getValue();
|
||||
|
||||
int getCount();
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package eu.dnetlib.organizations.model.utils;
|
||||
|
||||
public interface OrganizationConflict {
|
||||
|
||||
String getId();
|
||||
|
||||
String getName();
|
||||
|
||||
String getType();
|
||||
|
||||
String getCity();
|
||||
|
||||
String getCountry();
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package eu.dnetlib.organizations.model.utils;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class OrganizationConflictImpl implements OrganizationConflict, Comparable<OrganizationConflict> {
|
||||
|
||||
private String id;
|
||||
private String name;
|
||||
private String type;
|
||||
private String city;
|
||||
private String country;
|
||||
|
||||
public OrganizationConflictImpl() {}
|
||||
|
||||
public OrganizationConflictImpl(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public OrganizationConflictImpl(final String id, final String name, final String type, final String city, final String country) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.city = city;
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(final String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(final String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final OrganizationConflict o) {
|
||||
return getId().compareTo(o.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof OrganizationConflictImpl)) { return false; }
|
||||
final OrganizationConflictImpl other = (OrganizationConflictImpl) obj;
|
||||
return Objects.equals(id, other.id);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
package eu.dnetlib.organizations.model.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "conflict_groups_view")
|
||||
@IdClass(ConflictGroupViewPK.class)
|
||||
public class ConflictGroupView implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -6621501199394187765L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id_1")
|
||||
private String id1;
|
||||
|
||||
@Id
|
||||
@Column(name = "id_2")
|
||||
private String id2;
|
||||
|
||||
@Column(name = "name_1")
|
||||
private String name1;
|
||||
|
||||
@Column(name = "name_2")
|
||||
private String name2;
|
||||
|
||||
@Column(name = "type_1")
|
||||
private String type1;
|
||||
|
||||
@Column(name = "type_2")
|
||||
private String type2;
|
||||
|
||||
@Column(name = "city_1")
|
||||
private String city1;
|
||||
|
||||
@Column(name = "city_2")
|
||||
private String city2;
|
||||
|
||||
@Column(name = "country_1")
|
||||
private String country1;
|
||||
|
||||
@Column(name = "country_2")
|
||||
private String country2;
|
||||
|
||||
@Column(name = "idgroup")
|
||||
private String group;
|
||||
|
||||
public String getId1() {
|
||||
return id1;
|
||||
}
|
||||
|
||||
public void setId1(final String id1) {
|
||||
this.id1 = id1;
|
||||
}
|
||||
|
||||
public String getId2() {
|
||||
return id2;
|
||||
}
|
||||
|
||||
public void setId2(final String id2) {
|
||||
this.id2 = id2;
|
||||
}
|
||||
|
||||
public String getName1() {
|
||||
return name1;
|
||||
}
|
||||
|
||||
public void setName1(final String name1) {
|
||||
this.name1 = name1;
|
||||
}
|
||||
|
||||
public String getName2() {
|
||||
return name2;
|
||||
}
|
||||
|
||||
public void setName2(final String name2) {
|
||||
this.name2 = name2;
|
||||
}
|
||||
|
||||
public String getType1() {
|
||||
return type1;
|
||||
}
|
||||
|
||||
public void setType1(final String type1) {
|
||||
this.type1 = type1;
|
||||
}
|
||||
|
||||
public String getType2() {
|
||||
return type2;
|
||||
}
|
||||
|
||||
public void setType2(final String type2) {
|
||||
this.type2 = type2;
|
||||
}
|
||||
|
||||
public String getCity1() {
|
||||
return city1;
|
||||
}
|
||||
|
||||
public void setCity1(final String city1) {
|
||||
this.city1 = city1;
|
||||
}
|
||||
|
||||
public String getCity2() {
|
||||
return city2;
|
||||
}
|
||||
|
||||
public void setCity2(final String city2) {
|
||||
this.city2 = city2;
|
||||
}
|
||||
|
||||
public String getCountry1() {
|
||||
return country1;
|
||||
}
|
||||
|
||||
public void setCountry1(final String country1) {
|
||||
this.country1 = country1;
|
||||
}
|
||||
|
||||
public String getCountry2() {
|
||||
return country2;
|
||||
}
|
||||
|
||||
public void setCountry2(final String country2) {
|
||||
this.country2 = country2;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setGroup(final String group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package eu.dnetlib.organizations.model.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ConflictGroupViewPK implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -4702103726315884367L;
|
||||
|
||||
private String id1;
|
||||
|
||||
private String id2;
|
||||
|
||||
public String getId1() {
|
||||
return id1;
|
||||
}
|
||||
|
||||
public void setId1(final String id1) {
|
||||
this.id1 = id1;
|
||||
}
|
||||
|
||||
public String getId2() {
|
||||
return id2;
|
||||
}
|
||||
|
||||
public void setId2(final String id2) {
|
||||
this.id2 = id2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id1, id2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof ConflictGroupViewPK)) { return false; }
|
||||
final ConflictGroupViewPK other = (ConflictGroupViewPK) obj;
|
||||
return Objects.equals(id1, other.id1) && Objects.equals(id2, other.id2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("ConflictGroupViewPK [id1=%s, id2=%s]", id1, id2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package eu.dnetlib.organizations.model.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "duplicate_groups_view")
|
||||
public class DuplicateGroupView implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 8387253981112795514L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private String id;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "city")
|
||||
private String city;
|
||||
|
||||
@Column(name = "country")
|
||||
private String country;
|
||||
|
||||
@Column(name = "n_duplicates")
|
||||
private long numberOfDuplicates;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(final String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(final String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public long getNumberOfDuplicates() {
|
||||
return numberOfDuplicates;
|
||||
}
|
||||
|
||||
public void setNumberOfDuplicates(final long numberOfDuplicates) {
|
||||
this.numberOfDuplicates = numberOfDuplicates;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package eu.dnetlib.organizations.model.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "organizations_info_view")
|
||||
public class OrganizationInfoView implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -6077637367923773598L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private String id;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "created_by")
|
||||
private String createdBy;
|
||||
|
||||
@Column(name = "creation_date")
|
||||
private OffsetDateTime creationDate;
|
||||
|
||||
@Column(name = "modified_by")
|
||||
private String modifiedBy;
|
||||
|
||||
@Column(name = "modification_date")
|
||||
private OffsetDateTime modificationDate;
|
||||
|
||||
@Column(name = "n_duplicates")
|
||||
private long nDuplicates;
|
||||
|
||||
@Column(name = "n_conflicts")
|
||||
private long nConflicts;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
||||
public void setCreatedBy(final String createdBy) {
|
||||
this.createdBy = createdBy;
|
||||
}
|
||||
|
||||
public OffsetDateTime getCreationDate() {
|
||||
return creationDate;
|
||||
}
|
||||
|
||||
public void setCreationDate(final OffsetDateTime creationDate) {
|
||||
this.creationDate = creationDate;
|
||||
}
|
||||
|
||||
public String getModifiedBy() {
|
||||
return modifiedBy;
|
||||
}
|
||||
|
||||
public void setModifiedBy(final String modifiedBy) {
|
||||
this.modifiedBy = modifiedBy;
|
||||
}
|
||||
|
||||
public OffsetDateTime getModificationDate() {
|
||||
return modificationDate;
|
||||
}
|
||||
|
||||
public void setModificationDate(final OffsetDateTime modificationDate) {
|
||||
this.modificationDate = modificationDate;
|
||||
}
|
||||
|
||||
public long getnDuplicates() {
|
||||
return nDuplicates;
|
||||
}
|
||||
|
||||
public void setnDuplicates(final long nDuplicates) {
|
||||
this.nDuplicates = nDuplicates;
|
||||
}
|
||||
|
||||
public long getnConflicts() {
|
||||
return nConflicts;
|
||||
}
|
||||
|
||||
public void setnConflicts(final long nConflicts) {
|
||||
this.nConflicts = nConflicts;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package eu.dnetlib.organizations.model.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.hibernate.annotations.TypeDef;
|
||||
import org.hibernate.annotations.TypeDefs;
|
||||
|
||||
import com.vladmihalcea.hibernate.type.array.StringArrayType;
|
||||
|
||||
@Entity
|
||||
@Table(name = "organizations_simple_view")
|
||||
@TypeDefs({
|
||||
@TypeDef(name = "string-array", typeClass = StringArrayType.class)
|
||||
})
|
||||
public class OrganizationSimpleView implements Serializable, Comparable<OrganizationSimpleView> {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 417248897119259446L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private String id;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "type")
|
||||
private String type;
|
||||
|
||||
@Column(name = "city")
|
||||
private String city;
|
||||
|
||||
@Column(name = "country")
|
||||
private String country;
|
||||
|
||||
@Type(type = "string-array")
|
||||
@Column(name = "acronyms", columnDefinition = "text[]")
|
||||
private String[] acronyms;
|
||||
|
||||
public OrganizationSimpleView() {}
|
||||
|
||||
public OrganizationSimpleView(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public OrganizationSimpleView(final String id, final String name, final String type, final String city, final String country, final String[] acronyms) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.city = city;
|
||||
this.country = country;
|
||||
this.acronyms = acronyms;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(final String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(final String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String[] getAcronyms() {
|
||||
return acronyms;
|
||||
}
|
||||
|
||||
public void setAcronyms(final String[] acronyms) {
|
||||
this.acronyms = acronyms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof OrganizationSimpleView)) { return false; }
|
||||
final OrganizationSimpleView other = (OrganizationSimpleView) obj;
|
||||
return Objects.equals(id, other.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final OrganizationSimpleView o) {
|
||||
return id.compareTo(o.getId());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
package eu.dnetlib.organizations.model.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.hibernate.annotations.TypeDef;
|
||||
import org.hibernate.annotations.TypeDefs;
|
||||
|
||||
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
|
||||
import com.vladmihalcea.hibernate.type.json.JsonStringType;
|
||||
|
||||
@Entity
|
||||
@Table(name = "organizations_view")
|
||||
@TypeDefs({
|
||||
@TypeDef(name = "json", typeClass = JsonStringType.class),
|
||||
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
|
||||
})
|
||||
public class OrganizationView implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -7864607073631041868L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private String id;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "type")
|
||||
private String type;
|
||||
|
||||
@Column(name = "lat")
|
||||
private Double lat;
|
||||
|
||||
@Column(name = "lng")
|
||||
private Double lng;
|
||||
|
||||
@Column(name = "city")
|
||||
private String city;
|
||||
|
||||
@Column(name = "country")
|
||||
private String country;
|
||||
|
||||
@Type(type = "jsonb")
|
||||
@Column(name = "other_ids", columnDefinition = "jsonb")
|
||||
private Set<OtherIdentifier> otherIdentifiers;
|
||||
|
||||
@Type(type = "jsonb")
|
||||
@Column(name = "other_names", columnDefinition = "jsonb")
|
||||
private Set<OtherName> otherNames;
|
||||
|
||||
@Type(type = "jsonb")
|
||||
@Column(name = "acronyms", columnDefinition = "jsonb")
|
||||
private Set<String> acronyms;
|
||||
|
||||
@Type(type = "jsonb")
|
||||
@Column(name = "urls", columnDefinition = "jsonb")
|
||||
private Set<String> urls;
|
||||
|
||||
@Type(type = "jsonb")
|
||||
@Column(name = "relations", columnDefinition = "jsonb")
|
||||
private Set<RelationByOrg> relations;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Double getLat() {
|
||||
return lat;
|
||||
}
|
||||
|
||||
public void setLat(final Double lat) {
|
||||
this.lat = lat;
|
||||
}
|
||||
|
||||
public Double getLng() {
|
||||
return lng;
|
||||
}
|
||||
|
||||
public void setLng(final Double lng) {
|
||||
this.lng = lng;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(final String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(final String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public Set<OtherIdentifier> getOtherIdentifiers() {
|
||||
return otherIdentifiers;
|
||||
}
|
||||
|
||||
public void setOtherIdentifiers(final Set<OtherIdentifier> otherIdentifiers) {
|
||||
this.otherIdentifiers = otherIdentifiers;
|
||||
}
|
||||
|
||||
public Set<OtherName> getOtherNames() {
|
||||
return otherNames;
|
||||
}
|
||||
|
||||
public void setOtherNames(final Set<OtherName> otherNames) {
|
||||
this.otherNames = otherNames;
|
||||
}
|
||||
|
||||
public Set<String> getAcronyms() {
|
||||
return acronyms;
|
||||
}
|
||||
|
||||
public void setAcronyms(final Set<String> acronyms) {
|
||||
this.acronyms = acronyms;
|
||||
}
|
||||
|
||||
public Set<String> getUrls() {
|
||||
return urls;
|
||||
}
|
||||
|
||||
public void setUrls(final Set<String> urls) {
|
||||
this.urls = urls;
|
||||
}
|
||||
|
||||
public Set<RelationByOrg> getRelations() {
|
||||
return relations;
|
||||
}
|
||||
|
||||
public void setRelations(final Set<RelationByOrg> relations) {
|
||||
this.relations = relations;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package eu.dnetlib.organizations.model.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class OtherIdentifier implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -8290245353090885241L;
|
||||
|
||||
private String id;
|
||||
private String type;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof OtherIdentifier)) { return false; }
|
||||
final OtherIdentifier other = (OtherIdentifier) obj;
|
||||
return Objects.equals(id, other.id) && Objects.equals(type, other.type);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package eu.dnetlib.organizations.model.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class OtherName implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -5212012138309835912L;
|
||||
|
||||
private String name;
|
||||
|
||||
private String lang;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getLang() {
|
||||
return lang;
|
||||
}
|
||||
|
||||
public void setLang(final String lang) {
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(lang, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof OtherName)) { return false; }
|
||||
final OtherName other = (OtherName) obj;
|
||||
return Objects.equals(lang, other.lang) && Objects.equals(name, other.name);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package eu.dnetlib.organizations.model.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class RelationByOrg implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -659747760287666406L;
|
||||
|
||||
private String relatedOrgId;
|
||||
private String relatedOrgName;
|
||||
private String type;
|
||||
|
||||
public String getRelatedOrgId() {
|
||||
return relatedOrgId;
|
||||
}
|
||||
|
||||
public void setRelatedOrgId(final String relatedOrgId) {
|
||||
this.relatedOrgId = relatedOrgId;
|
||||
}
|
||||
|
||||
public String getRelatedOrgName() {
|
||||
return relatedOrgName;
|
||||
}
|
||||
|
||||
public void setRelatedOrgName(final String relatedOrgName) {
|
||||
this.relatedOrgName = relatedOrgName;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(relatedOrgId, relatedOrgName, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) { return true; }
|
||||
if (obj == null) { return false; }
|
||||
if (!(obj instanceof RelationByOrg)) { return false; }
|
||||
final RelationByOrg other = (RelationByOrg) obj;
|
||||
return Objects.equals(relatedOrgId, other.relatedOrgId) && Objects.equals(relatedOrgName, other.relatedOrgName) && Objects.equals(type, other.type);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package eu.dnetlib.organizations.model.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "suggestions_info_by_country_view")
|
||||
public class SuggestionInfoViewByCountry implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -6814272980951063075L;
|
||||
|
||||
@Id
|
||||
@Column(name = "country")
|
||||
private String country;
|
||||
|
||||
@Column(name = "n_duplicates")
|
||||
private long nDuplicates;
|
||||
|
||||
@Column(name = "n_conflicts")
|
||||
private long nConflicts;
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(final String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public long getnDuplicates() {
|
||||
return nDuplicates;
|
||||
}
|
||||
|
||||
public void setnDuplicates(final long nDuplicates) {
|
||||
this.nDuplicates = nDuplicates;
|
||||
}
|
||||
|
||||
public long getnConflicts() {
|
||||
return nConflicts;
|
||||
}
|
||||
|
||||
public void setnConflicts(final long nConflicts) {
|
||||
this.nConflicts = nConflicts;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package eu.dnetlib.organizations.model.view;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.hibernate.annotations.TypeDef;
|
||||
import org.hibernate.annotations.TypeDefs;
|
||||
|
||||
import com.vladmihalcea.hibernate.type.array.StringArrayType;
|
||||
|
||||
@Entity
|
||||
@Table(name = "users_view")
|
||||
@TypeDefs({
|
||||
@TypeDef(name = "string-array", typeClass = StringArrayType.class)
|
||||
})
|
||||
public class UserView implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -3308680880727895075L;
|
||||
|
||||
@Id
|
||||
@Column(name = "email")
|
||||
private String email;
|
||||
|
||||
@Column(name = "valid")
|
||||
private boolean valid;
|
||||
|
||||
@Column(name = "role")
|
||||
private String role;
|
||||
|
||||
@Type(type = "string-array")
|
||||
@Column(name = "countries", columnDefinition = "text[]")
|
||||
private String[] countries;
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(final String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
public void setValid(final boolean valid) {
|
||||
this.valid = valid;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(final String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String[] getCountries() {
|
||||
return countries;
|
||||
}
|
||||
|
||||
public void setCountries(final String[] countries) {
|
||||
this.countries = countries;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import eu.dnetlib.organizations.model.Acronym;
|
||||
import eu.dnetlib.organizations.model.AcronymPK;
|
||||
|
||||
public interface AcronymRepository extends JpaRepository<Acronym, AcronymPK> {
|
||||
|
||||
void deleteByOrgId(String orgId);
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import eu.dnetlib.organizations.model.OpenaireConflict;
|
||||
import eu.dnetlib.organizations.model.OpenaireConflictPK;
|
||||
import eu.dnetlib.organizations.model.utils.OrganizationConflict;
|
||||
|
||||
@Repository
|
||||
public interface OpenaireConflictRepository extends JpaRepository<OpenaireConflict, OpenaireConflictPK> {
|
||||
|
||||
@Query(value = "select o.id, o.name, o.type, o.city, o.country from oa_conflicts c left outer join organizations o on (c.id2 = o.id) where o.id is not null and c.id1 = ?", nativeQuery = true)
|
||||
List<OrganizationConflict> getConflictsForId(String id);
|
||||
|
||||
Iterable<OpenaireConflict> findById1AndGroupIsNull(String id);
|
||||
|
||||
Iterable<OpenaireConflict> findById2AndGroupIsNull(String id);
|
||||
|
||||
@Modifying
|
||||
@Query(value = "update oa_conflicts set idgroup = null", nativeQuery = true)
|
||||
void resetGroupIds();
|
||||
|
||||
long countByGroupNull();
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import eu.dnetlib.organizations.model.OpenaireDuplicate;
|
||||
import eu.dnetlib.organizations.model.OpenaireDuplicatePK;
|
||||
|
||||
@Repository
|
||||
public interface OpenaireDuplicateRepository extends JpaRepository<OpenaireDuplicate, OpenaireDuplicatePK> {
|
||||
|
||||
List<OpenaireDuplicate> findByLocalId(String localId);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
import eu.dnetlib.organizations.model.Organization;
|
||||
|
||||
public interface OrganizationRepository extends JpaRepository<Organization, String> {
|
||||
|
||||
@Modifying
|
||||
@Query("update Organization set created_by = ?2, creation_date = ?3 where id = ?1")
|
||||
void updateCreationDate(String id, String user, OffsetDateTime now);
|
||||
|
||||
@Modifying
|
||||
@Query("update Organization set modified_by = ?2, modification_date = ?3 where id = ?1")
|
||||
void updateModificationDate(String id, String user, OffsetDateTime now);
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import eu.dnetlib.organizations.model.OtherIdentifier;
|
||||
import eu.dnetlib.organizations.model.OtherIdentifierPK;
|
||||
|
||||
public interface OtherIdentifierRepository extends JpaRepository<OtherIdentifier, OtherIdentifierPK> {
|
||||
|
||||
void deleteByOrgId(String orgId);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import eu.dnetlib.organizations.model.OtherName;
|
||||
import eu.dnetlib.organizations.model.OtherNamePK;
|
||||
|
||||
public interface OtherNameRepository extends JpaRepository<OtherName, OtherNamePK> {
|
||||
|
||||
void deleteByOrgId(String orgId);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import eu.dnetlib.organizations.model.Relationship;
|
||||
import eu.dnetlib.organizations.model.RelationshipPK;
|
||||
|
||||
public interface RelationshipRepository extends JpaRepository<Relationship, RelationshipPK> {
|
||||
|
||||
void deleteById1(String id1);
|
||||
|
||||
void deleteById2(String id2);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import eu.dnetlib.organizations.model.Url;
|
||||
import eu.dnetlib.organizations.model.UrlPK;
|
||||
|
||||
public interface UrlRepository extends JpaRepository<Url, UrlPK> {
|
||||
|
||||
void deleteByOrgId(String orgId);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
|
||||
import eu.dnetlib.organizations.model.UserCountry;
|
||||
import eu.dnetlib.organizations.model.UserCountryPK;
|
||||
|
||||
public interface UserCountryRepository extends JpaRepository<UserCountry, UserCountryPK> {
|
||||
|
||||
void deleteByEmail(String email);
|
||||
|
||||
@Query(value = "select country from user_countries where email = ?1", nativeQuery = true)
|
||||
List<String> getCountriesForUser(String email);
|
||||
|
||||
@Query(value = "select count(o.country) > 0 from organizations o left outer join user_countries uc on (o.country = uc.country) where o.id = ?1 and uc.email = ?2", nativeQuery = true)
|
||||
boolean verifyAuthorizationForId(String id, String user);
|
||||
|
||||
@Query(value = "select count(country) > 0 from user_countries where country = ?1 and email = ?2", nativeQuery = true)
|
||||
boolean verifyAuthorizationForCountry(String country, String user);
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package eu.dnetlib.organizations.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import eu.dnetlib.organizations.model.User;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, String> {
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package eu.dnetlib.organizations.repository.readonly;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import eu.dnetlib.organizations.model.view.ConflictGroupView;
|
||||
import eu.dnetlib.organizations.model.view.ConflictGroupViewPK;
|
||||
|
||||
@Repository
|
||||
public interface ConflictGroupViewRepository extends ReadOnlyRepository<ConflictGroupView, ConflictGroupViewPK> {
|
||||
|
||||
List<ConflictGroupView> findByCountry1OrCountry2(String country1, String country2);
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package eu.dnetlib.organizations.repository.readonly;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import eu.dnetlib.organizations.model.view.DuplicateGroupView;
|
||||
|
||||
@Repository
|
||||
public interface DuplicateGroupViewRepository extends ReadOnlyRepository<DuplicateGroupView, String> {
|
||||
|
||||
List<DuplicateGroupView> findByCountry(String country);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package eu.dnetlib.organizations.repository.readonly;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import eu.dnetlib.organizations.model.view.OrganizationInfoView;
|
||||
|
||||
@Repository
|
||||
public interface OrganizationInfoViewRepository extends ReadOnlyRepository<OrganizationInfoView, String> {
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package eu.dnetlib.organizations.repository.readonly;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import eu.dnetlib.organizations.model.utils.BrowseEntry;
|
||||
import eu.dnetlib.organizations.model.view.OrganizationSimpleView;
|
||||
|
||||
@Repository
|
||||
public interface OrganizationSimpleViewRepository extends ReadOnlyRepository<OrganizationSimpleView, String> {
|
||||
|
||||
// SEARCH
|
||||
Page<OrganizationSimpleView> findByNameContainingIgnoreCase(String name, Pageable pageable);
|
||||
|
||||
// SEARCH FOR USER
|
||||
@Query(value = "select o.* from organizations_simple_view o left outer join user_countries uc on (uc.country = o.country) where o.name ilike %:text% and uc.email = :email", nativeQuery = true)
|
||||
Page<OrganizationSimpleView> findByNameForUser(String text, String email, Pageable pageable);
|
||||
|
||||
// BROWSE BY COUNTRY
|
||||
@Query(value = "select country as value, count(*) as count from organizations group by country order by count desc", nativeQuery = true)
|
||||
List<BrowseEntry> browseCountries();
|
||||
|
||||
// BROWSE BY COUNTRY FOR USER
|
||||
@Query(value = "select o.country as value, count(o.country) as count from user_countries uc left outer join organizations o on (uc.country = o.country) where uc.email=?1 group by o.country order by count desc", nativeQuery = true)
|
||||
List<BrowseEntry> browseCountriesForUser(String email);
|
||||
|
||||
Page<OrganizationSimpleView> findByCountry(String country, Pageable pageable);
|
||||
|
||||
// BROWSE BY ORG TYPE
|
||||
@Query(value = "select type as value, count(*) as count from organizations group by type order by count desc", nativeQuery = true)
|
||||
List<BrowseEntry> browseTypes();
|
||||
|
||||
// BROWSE BY ORG TYPE FOR USER
|
||||
@Query(value = "select o.type as value, count(o.type) as count "
|
||||
+ "from organizations o "
|
||||
+ "left outer join user_countries uc on (uc.country = o.country) "
|
||||
+ "where uc.email=?1 "
|
||||
+ "group by o.type "
|
||||
+ "order by count desc;", nativeQuery = true)
|
||||
List<BrowseEntry> browseTypesForUser(String email);
|
||||
|
||||
Page<OrganizationSimpleView> findByType(String type, Pageable pageable);
|
||||
|
||||
@Query(value = "select o.* from organizations_simple_view o left outer join user_countries uc on (uc.country = o.country) where uc.email = ?2 and o.type = ?1", nativeQuery = true)
|
||||
Page<OrganizationSimpleView> findByTypeForUser(String type, String name, Pageable pageable);
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package eu.dnetlib.organizations.repository.readonly;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import eu.dnetlib.organizations.model.view.OrganizationView;
|
||||
|
||||
@Repository
|
||||
public interface OrganizationViewRepository extends ReadOnlyRepository<OrganizationView, String> {
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package eu.dnetlib.organizations.repository.readonly;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.NoRepositoryBean;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
@NoRepositoryBean
|
||||
public interface ReadOnlyRepository<T, ID> extends Repository<T, ID> {
|
||||
|
||||
Optional<T> findById(ID id);
|
||||
|
||||
boolean existsById(ID id);
|
||||
|
||||
Page<T> findAll(Pageable pageable);
|
||||
|
||||
Iterable<T> findAll();
|
||||
|
||||
long count();
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package eu.dnetlib.organizations.repository.readonly;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import eu.dnetlib.organizations.model.view.SuggestionInfoViewByCountry;
|
||||
|
||||
@Repository
|
||||
public interface SuggestionInfoViewByCountryRepository extends ReadOnlyRepository<SuggestionInfoViewByCountry, String> {
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package eu.dnetlib.organizations.repository.readonly;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import eu.dnetlib.organizations.model.view.UserView;
|
||||
|
||||
@Repository
|
||||
public interface UserViewRepository extends ReadOnlyRepository<UserView, String> {
|
||||
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
package eu.dnetlib.organizations.utils;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import eu.dnetlib.organizations.controller.UserRole;
|
||||
import eu.dnetlib.organizations.model.Acronym;
|
||||
import eu.dnetlib.organizations.model.OpenaireConflict;
|
||||
import eu.dnetlib.organizations.model.OpenaireConflictPK;
|
||||
import eu.dnetlib.organizations.model.Organization;
|
||||
import eu.dnetlib.organizations.model.OtherIdentifier;
|
||||
import eu.dnetlib.organizations.model.OtherName;
|
||||
import eu.dnetlib.organizations.model.Relationship;
|
||||
import eu.dnetlib.organizations.model.Url;
|
||||
import eu.dnetlib.organizations.model.User;
|
||||
import eu.dnetlib.organizations.model.UserCountry;
|
||||
import eu.dnetlib.organizations.model.view.OrganizationView;
|
||||
import eu.dnetlib.organizations.model.view.UserView;
|
||||
import eu.dnetlib.organizations.repository.AcronymRepository;
|
||||
import eu.dnetlib.organizations.repository.OpenaireConflictRepository;
|
||||
import eu.dnetlib.organizations.repository.OrganizationRepository;
|
||||
import eu.dnetlib.organizations.repository.OtherIdentifierRepository;
|
||||
import eu.dnetlib.organizations.repository.OtherNameRepository;
|
||||
import eu.dnetlib.organizations.repository.RelationshipRepository;
|
||||
import eu.dnetlib.organizations.repository.UrlRepository;
|
||||
import eu.dnetlib.organizations.repository.UserCountryRepository;
|
||||
import eu.dnetlib.organizations.repository.UserRepository;
|
||||
|
||||
@Component
|
||||
public class DatabaseUtils {
|
||||
|
||||
@Autowired
|
||||
private AcronymRepository acronymRepository;
|
||||
@Autowired
|
||||
private OrganizationRepository organizationRepository;
|
||||
@Autowired
|
||||
private OtherIdentifierRepository otherIdentifierRepository;
|
||||
@Autowired
|
||||
private OtherNameRepository otherNameRepository;
|
||||
@Autowired
|
||||
private UrlRepository urlRepository;
|
||||
@Autowired
|
||||
private RelationshipRepository relationshipRepository;
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
@Autowired
|
||||
private UserCountryRepository userCountryRepository;
|
||||
@Autowired
|
||||
private OpenaireConflictRepository openaireConflictRepository;
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
public enum VocabularyTable {
|
||||
languages, countries, org_types, id_types, rel_types, simrel_types
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public String insertOrUpdateOrganization(final OrganizationView orgView, final String user, final boolean update) {
|
||||
|
||||
if (update) {
|
||||
cleanOldRelations(orgView.getId());
|
||||
}
|
||||
|
||||
final Organization org = new Organization(update ? orgView.getId() : null,
|
||||
orgView.getName(),
|
||||
orgView.getType(),
|
||||
orgView.getLat(), orgView.getLng(),
|
||||
orgView.getCity(), orgView.getCountry());
|
||||
|
||||
final String orgId = organizationRepository.save(org).getId();
|
||||
|
||||
makeNewRelations(orgView, orgId);
|
||||
|
||||
updateHistoryFields(orgId, user, update);
|
||||
|
||||
return orgId;
|
||||
}
|
||||
|
||||
private void updateHistoryFields(final String id, final String user, final boolean update) {
|
||||
final OffsetDateTime now = OffsetDateTime.now();
|
||||
if (update) {
|
||||
organizationRepository.updateModificationDate(id, user, now);
|
||||
} else {
|
||||
organizationRepository.updateCreationDate(id, user, now);
|
||||
organizationRepository.updateModificationDate(id, user, now);
|
||||
}
|
||||
}
|
||||
|
||||
private void makeNewRelations(final OrganizationView orgView, final String orgId) {
|
||||
orgView.getAcronyms().forEach(s -> acronymRepository.save(new Acronym(orgId, s)));
|
||||
orgView.getOtherNames().forEach(n -> otherNameRepository.save(new OtherName(orgId, n.getName(), n.getLang())));
|
||||
orgView.getOtherIdentifiers().forEach(id -> otherIdentifierRepository.save(new OtherIdentifier(orgId, id.getId(), id.getType())));
|
||||
orgView.getUrls().forEach(u -> urlRepository.save(new Url(orgId, u)));
|
||||
orgView.getRelations().forEach(r -> makeRelation(orgId, r.getRelatedOrgId(), RelationType.valueOf(r.getType())));
|
||||
}
|
||||
|
||||
private void cleanOldRelations(final String id) {
|
||||
acronymRepository.deleteByOrgId(id);
|
||||
otherNameRepository.deleteByOrgId(id);
|
||||
otherIdentifierRepository.deleteByOrgId(id);
|
||||
urlRepository.deleteByOrgId(id);
|
||||
relationshipRepository.deleteById1(id);
|
||||
relationshipRepository.deleteById2(id);
|
||||
}
|
||||
|
||||
@Cacheable("vocs")
|
||||
public List<String> listValuesOfVocabularyTable(final VocabularyTable table) {
|
||||
return jdbcTemplate.queryForList("select val from " + table, String.class);
|
||||
}
|
||||
|
||||
@Cacheable("countries_for_user")
|
||||
public List<String> listCountriesForUser(final String name) {
|
||||
return jdbcTemplate.queryForList("select country from user_countries where email = ?", String.class, name);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void saveUser(@RequestBody final UserView userView) {
|
||||
final User user = userRepository.findById(userView.getEmail()).orElseThrow(() -> new RuntimeException("User not found"));
|
||||
user.setRole(userView.getRole());
|
||||
user.setValid(userView.isValid());
|
||||
userRepository.save(user);
|
||||
userCountryRepository.deleteByEmail(userView.getEmail());
|
||||
if (userView.getCountries() != null) {
|
||||
userCountryRepository
|
||||
.saveAll(Arrays.stream(userView.getCountries()).map(c -> new UserCountry(userView.getEmail(), c)).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteUser(final String email) {
|
||||
userCountryRepository.deleteByEmail(email);
|
||||
userRepository.deleteById(email);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void newUser(final String email, final List<String> countries) {
|
||||
final User user = new User();
|
||||
user.setEmail(email);
|
||||
user.setRole(UserRole.PENDING.name());
|
||||
user.setValid(false);
|
||||
userRepository.save(user);
|
||||
if (countries != null) {
|
||||
userCountryRepository.saveAll(countries.stream().map(c -> new UserCountry(email, c)).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void verifyConflictGroups(final boolean forceUpdate) {
|
||||
|
||||
if (forceUpdate || openaireConflictRepository.countByGroupNull() > 0) {
|
||||
|
||||
openaireConflictRepository.resetGroupIds();
|
||||
|
||||
final Map<String, Set<String>> groups = new HashMap<>();
|
||||
for (final OpenaireConflict w : openaireConflictRepository.findAll()) {
|
||||
final List<String> list = findExistingGroupsForRel(w, groups);
|
||||
if (list.isEmpty()) {
|
||||
final String idGroup = generateGroupId();
|
||||
groups.put(idGroup, new HashSet<>());
|
||||
addToGroup(groups, idGroup, w);
|
||||
} else if (list.size() == 1) {
|
||||
addToGroup(groups, list.get(0), w);
|
||||
} else {
|
||||
final String idGroup = generateGroupId();
|
||||
groups.put(idGroup, new TreeSet<>());
|
||||
list.forEach(id -> groups.get(idGroup).addAll(groups.get(id)));
|
||||
list.forEach(id -> groups.remove(id));
|
||||
addToGroup(groups, idGroup, w);
|
||||
}
|
||||
}
|
||||
|
||||
for (final Entry<String, Set<String>> e : groups.entrySet()) {
|
||||
final String gid = e.getKey();
|
||||
for (final String orgId : e.getValue()) {
|
||||
for (final OpenaireConflict oc : openaireConflictRepository.findById1AndGroupIsNull(orgId)) {
|
||||
oc.setGroup(gid);
|
||||
openaireConflictRepository.save(oc);
|
||||
}
|
||||
for (final OpenaireConflict oc : openaireConflictRepository.findById2AndGroupIsNull(orgId)) {
|
||||
oc.setGroup(gid);
|
||||
openaireConflictRepository.save(oc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String generateGroupId() {
|
||||
return "group::" + UUID.randomUUID();
|
||||
}
|
||||
|
||||
private List<String> findExistingGroupsForRel(final OpenaireConflict w, final Map<String, Set<String>> groups) {
|
||||
return groups.entrySet()
|
||||
.stream()
|
||||
.filter(e -> {
|
||||
return e.getValue().contains(w.getId1()) || e.getValue().contains(w.getId2());
|
||||
})
|
||||
.map(e -> e.getKey())
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void addToGroup(final Map<String, Set<String>> groups, final String gid, final OpenaireConflict w) {
|
||||
groups.get(gid).add(w.getId1());
|
||||
groups.get(gid).add(w.getId2());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<Relationship> makeRelation(final String id1, final String id2, final RelationType type) {
|
||||
final Relationship r1 = new Relationship(id1, id2, type.toString());
|
||||
final Relationship r2 = new Relationship(id2, id1, type.getInverse().toString());
|
||||
relationshipRepository.save(r1);
|
||||
relationshipRepository.save(r2);
|
||||
|
||||
if (type == RelationType.Merged_In || type == RelationType.Merges) {
|
||||
openaireConflictRepository.findById(new OpenaireConflictPK(id1, id2)).ifPresent(openaireConflictRepository::delete);
|
||||
openaireConflictRepository.findById(new OpenaireConflictPK(id2, id1)).ifPresent(openaireConflictRepository::delete);
|
||||
}
|
||||
|
||||
return Arrays.asList(r1, r2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package eu.dnetlib.organizations.utils;
|
||||
|
||||
public class OpenOrgsConstants {
|
||||
|
||||
public static final String OPENORGS_PREFIX = "openorgs____::";
|
||||
public static final String OPENORGS_MESH_PREFIX = "openorgsmesh::";
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package eu.dnetlib.organizations.utils;
|
||||
|
||||
public enum RelationType {
|
||||
|
||||
Child, Parent, Related, Other, Merged_In, Merges;
|
||||
|
||||
public RelationType getInverse() {
|
||||
switch (this) {
|
||||
case Child:
|
||||
return Parent;
|
||||
case Parent:
|
||||
return Child;
|
||||
case Related:
|
||||
return Related;
|
||||
case Merged_In:
|
||||
return Merges;
|
||||
case Merges:
|
||||
return Merged_In;
|
||||
default:
|
||||
return Other;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package eu.dnetlib.organizations.utils;
|
||||
|
||||
public enum SimilarityType {
|
||||
suggested, is_similar, is_different
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
spring.main.banner-mode = off
|
||||
logging.level.root = INFO
|
||||
|
||||
spring.datasource.url=jdbc:postgresql://localhost:5432/dnet_orgs
|
||||
spring.datasource.username=
|
||||
spring.datasource.password=
|
||||
|
||||
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
|
||||
|
||||
# Hibernate ddl auto (create, create-drop, validate, update)
|
||||
spring.jpa.hibernate.ddl-auto = validate
|
||||
spring.jpa.properties.hibernate.hbm2dll.extra_physical_table_types = MATERIALIZED VIEW
|
||||
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
|
||||
spring.jpa.open-in-view=true
|
||||
|
||||
spring.jpa.properties.hibernate.show_sql=true
|
||||
spring.jpa.properties.hibernate.use_sql_comments=true
|
||||
spring.jpa.properties.hibernate.format_sql=true
|
|
@ -0,0 +1,27 @@
|
|||
CREATE TEMPORARY TABLE tmp_simrels (
|
||||
local_id text NOT NULL,
|
||||
oa_original_id text NOT NULL,
|
||||
oa_name text NOT NULL,
|
||||
oa_acronym text,
|
||||
oa_country text,
|
||||
oa_url text,
|
||||
oa_collectedfrom text
|
||||
);
|
||||
|
||||
COPY tmp_simrels(local_id, oa_original_id, oa_name, oa_acronym, oa_country, oa_url, oa_collectedfrom) FROM '/Users/michele/Develop/dnet45/dnet-orgs-database-application/src/main/resources/tmp_data/rels.part-r-00000.tsv' DELIMITER E'\t';;
|
||||
|
||||
DELETE FROM oa_duplicates WHERE reltype = 'suggested';
|
||||
DELETE FROM oa_conflicts WHERE reltype = 'suggested';
|
||||
UPDATE oa_conflicts SET idgroup = NULL;
|
||||
|
||||
INSERT INTO oa_duplicates (local_id, oa_original_id, oa_name, oa_acronym, oa_country, oa_url, oa_collectedfrom)
|
||||
SELECT local_id, oa_original_id, oa_name, oa_acronym, oa_country, oa_url, oa_collectedfrom
|
||||
FROM tmp_simrels
|
||||
WHERE oa_original_id NOT LIKE 'openorgs____::%'
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
INSERT INTO oa_conflicts (id1, id2)
|
||||
SELECT local_id, oa_original_id
|
||||
FROM tmp_simrels
|
||||
WHERE oa_original_id LIKE 'openorgs____::%'
|
||||
ON CONFLICT DO NOTHING;
|
|
@ -0,0 +1,103 @@
|
|||
CREATE TEMP TABLE grid_institutes (
|
||||
grid_id text,
|
||||
name text,
|
||||
wikipedia_url text,
|
||||
email_address text,
|
||||
established int
|
||||
);
|
||||
|
||||
CREATE TEMP TABLE grid_geonames (
|
||||
geonames_city_id text,
|
||||
city text,
|
||||
nuts_level1_code text,
|
||||
nuts_level1_name text,
|
||||
nuts_level2_code text,
|
||||
nuts_level2_name text,
|
||||
nuts_level3_code text,
|
||||
nuts_level3_name text,
|
||||
geonames_admin1_code text,
|
||||
geonames_admin1_name text,
|
||||
geonames_admin1_ascii_name text,
|
||||
geonames_admin2_code text,
|
||||
geonames_admin2_name text,
|
||||
geonames_admin2_ascii_name text
|
||||
);
|
||||
|
||||
CREATE TEMP TABLE grid_addresses (
|
||||
grid_id text,
|
||||
line_1 text,
|
||||
line_2 text,
|
||||
line_3 text,
|
||||
lat double precision,
|
||||
lng double precision,
|
||||
postcode text,
|
||||
is_primary boolean,
|
||||
city text,
|
||||
state text,
|
||||
state_code text,
|
||||
country text,
|
||||
country_code text,
|
||||
geonames_city_id int
|
||||
);
|
||||
|
||||
CREATE TEMP TABLE grid_external_ids (
|
||||
grid_id text,
|
||||
external_id_type text,
|
||||
external_id text
|
||||
);
|
||||
|
||||
CREATE TEMP TABLE grid_labels (
|
||||
grid_id text,
|
||||
iso639 text,
|
||||
label text
|
||||
);
|
||||
|
||||
CREATE TEMP TABLE grid_relationships (
|
||||
grid_id text,
|
||||
relationship_type text,
|
||||
related_grid_id text
|
||||
);
|
||||
|
||||
CREATE TEMP TABLE grid_types (
|
||||
grid_id text,
|
||||
type text
|
||||
);
|
||||
|
||||
CREATE TEMP TABLE grid_links (
|
||||
grid_id text,
|
||||
link text
|
||||
);
|
||||
|
||||
CREATE TEMP TABLE grid_acronyms (
|
||||
grid_id text,
|
||||
acronym text
|
||||
);
|
||||
|
||||
CREATE TEMP TABLE grid_aliases (
|
||||
grid_id text,
|
||||
alias text
|
||||
);
|
||||
|
||||
COPY grid_institutes (grid_id,name,wikipedia_url,email_address,established) FROM '/Users/michele/Develop/dnet45/dnet-orgs-database-application/data/grid-2019-05-06/full_tables/institutes.csv' CSV HEADER;
|
||||
COPY grid_geonames (geonames_city_id,city,nuts_level1_code,nuts_level1_name,nuts_level2_code,nuts_level2_name,nuts_level3_code,nuts_level3_name,geonames_admin1_code,geonames_admin1_name,geonames_admin1_ascii_name,geonames_admin2_code,geonames_admin2_name,geonames_admin2_ascii_name) FROM '/Users/michele/Develop/dnet45/dnet-orgs-database-application/data/grid-2019-05-06/full_tables/geonames.csv' CSV HEADER;
|
||||
COPY grid_addresses (grid_id,line_1,line_2,line_3,lat,lng,postcode,is_primary,city,state,state_code,country,country_code,geonames_city_id) FROM '/Users/michele/Develop/dnet45/dnet-orgs-database-application/data/grid-2019-05-06/full_tables/addresses.csv' CSV HEADER;
|
||||
COPY grid_external_ids (grid_id,external_id_type,external_id) FROM '/Users/michele/Develop/dnet45/dnet-orgs-database-application/data/grid-2019-05-06/full_tables/external_ids.csv' CSV HEADER;
|
||||
COPY grid_labels (grid_id,iso639,label) FROM '/Users/michele/Develop/dnet45/dnet-orgs-database-application/data/grid-2019-05-06/full_tables/labels.csv' CSV HEADER;
|
||||
COPY grid_relationships (grid_id,relationship_type,related_grid_id) FROM '/Users/michele/Develop/dnet45/dnet-orgs-database-application/data/grid-2019-05-06/full_tables/relationships.csv' CSV HEADER;
|
||||
COPY grid_types (grid_id,type) FROM '/Users/michele/Develop/dnet45/dnet-orgs-database-application/data/grid-2019-05-06/full_tables/types.csv' CSV HEADER;
|
||||
COPY grid_links (grid_id,link) FROM '/Users/michele/Develop/dnet45/dnet-orgs-database-application/data/grid-2019-05-06/full_tables/links.csv' CSV HEADER;
|
||||
COPY grid_acronyms (grid_id,acronym) FROM '/Users/michele/Develop/dnet45/dnet-orgs-database-application/data/grid-2019-05-06/full_tables/acronyms.csv' CSV HEADER;
|
||||
COPY grid_aliases (grid_id,alias) FROM '/Users/michele/Develop/dnet45/dnet-orgs-database-application/data/grid-2019-05-06/full_tables/aliases.csv' CSV HEADER;
|
||||
|
||||
|
||||
INSERT INTO organizations(id, name, type, lat, lng, city, country, created_by, modified_by) (SELECT 'tmp::'||md5(o.grid_id), o.name, COALESCE(t.type, 'UNKNOWN'), a.lat, a.lng, a.city, a.country_code, 'import:grid.ac', 'import:grid.ac' FROM grid_institutes o LEFT OUTER JOIN grid_addresses a ON (o.grid_id=a.grid_id) LEFT OUTER JOIN grid_types t ON (o.grid_id=t.grid_id)) ON CONFLICT DO NOTHING;
|
||||
INSERT INTO other_ids (id, otherid, type) (SELECT 'tmp::'||md5(grid_id), grid_id, 'grid.ac' FROM grid_institutes ) ON CONFLICT DO NOTHING;
|
||||
INSERT INTO other_ids (id, otherid, type) (SELECT 'tmp::'||md5(grid_id), external_id, external_id_type FROM grid_external_ids ) ON CONFLICT DO NOTHING;
|
||||
INSERT INTO other_names (id, lang, name) (SELECT 'tmp::'||md5(grid_id), 'en', name FROM grid_institutes ) ON CONFLICT DO NOTHING;
|
||||
INSERT INTO other_names (id, lang, name) (SELECT 'tmp::'||md5(grid_id), iso639, label FROM grid_labels ) ON CONFLICT DO NOTHING;
|
||||
INSERT INTO other_names (id, lang, name) (SELECT 'tmp::'||md5(grid_id), 'UNKNOWN', alias FROM grid_aliases ) ON CONFLICT DO NOTHING;
|
||||
INSERT INTO acronyms (id, acronym) (SELECT 'tmp::'||md5(grid_id), acronym FROM grid_acronyms ) ON CONFLICT DO NOTHING;
|
||||
INSERT INTO relationships(id1, reltype, id2) (SELECT 'tmp::'||md5(grid_id), relationship_type, 'tmp::'||md5(related_grid_id) FROM grid_relationships) ON CONFLICT DO NOTHING;
|
||||
INSERT INTO urls (id, url) (SELECT 'tmp::'||md5(grid_id), link FROM grid_links ) ON CONFLICT DO NOTHING;
|
||||
|
||||
update organizations set id = DEFAULT;
|
|
@ -0,0 +1 @@
|
|||
INSERT INTO users(email, valid, role) VALUES ('michele.artini@isti.cnr.it', true, 'ADMIN');
|
|
@ -0,0 +1,262 @@
|
|||
DROP VIEW organizations_view;
|
||||
DROP VIEW organizations_info_view;
|
||||
DROP VIEW organizations_simple_view;
|
||||
DROP VIEW users_view;
|
||||
DROP VIEW conflict_groups_view;
|
||||
DROP VIEW suggestions_info_by_country_view;
|
||||
DROP VIEW duplicate_groups_view
|
||||
|
||||
DROP TABLE IF EXISTS other_ids;
|
||||
DROP TABLE IF EXISTS other_names;
|
||||
DROP TABLE IF EXISTS acronyms;
|
||||
DROP TABLE IF EXISTS relationships;
|
||||
DROP TABLE IF EXISTS urls;
|
||||
DROP TABLE IF EXISTS oa_duplicates;
|
||||
DROP TABLE IF EXISTS oa_conflicts;
|
||||
DROP TABLE IF EXISTS organizations;
|
||||
DROP TABLE IF EXISTS org_types;
|
||||
|
||||
DROP TABLE IF EXISTS user_countries;
|
||||
DROP TABLE IF EXISTS users;
|
||||
|
||||
DROP TABLE IF EXISTS user_roles;
|
||||
DROP TABLE IF EXISTS countries;
|
||||
DROP TABLE IF EXISTS id_types;
|
||||
DROP TABLE IF EXISTS languages;
|
||||
|
||||
DROP SEQUENCE IF EXISTS organizations_id_seq;
|
||||
|
||||
CREATE TABLE org_types (val text PRIMARY KEY);
|
||||
INSERT INTO org_types VALUES ('Archive'), ('Company'), ('Education'), ('Facility'), ('Government'), ('Healthcare'), ('Nonprofit'), ('Other'), ('UNKNOWN');
|
||||
|
||||
CREATE TABLE id_types (val text PRIMARY KEY);
|
||||
INSERT INTO id_types VALUES ('CNRS'), ('FundRef'), ('HESA'), ('ISNI'), ('OrgRef'), ('UCAS'), ('UKPRN'), ('Wikidata'), ('grid.ac');
|
||||
|
||||
CREATE TABLE languages (val text PRIMARY KEY);
|
||||
INSERT INTO languages VALUES ('UNKNOWN'), ('aa'), ('af'), ('am'), ('ar'), ('as'), ('az'), ('ba'), ('be'), ('bg'), ('bn'), ('br'), ('bs'), ('ca'), ('ch'), ('co'), ('cs'), ('cy'), ('da'),
|
||||
('de'), ('dv'), ('dz'), ('el'), ('en'), ('eo'), ('es'), ('et'), ('eu'), ('fa'), ('fi'), ('fr'), ('fy'), ('ga'), ('gd'), ('gl'), ('gu'), ('he'), ('hi'), ('hr'), ('hu'), ('hy'), ('id'), ('is'),
|
||||
('it'), ('iu'), ('ja'), ('jv'), ('ka'), ('kk'), ('kl'), ('km'), ('kn'), ('ko'), ('ku'), ('ky'), ('la'), ('lb'), ('lo'), ('lt'), ('lv'), ('mg'), ('mi'), ('mk'), ('ml'), ('mn'), ('mr'), ('ms'),
|
||||
('mt'), ('my'), ('nb'), ('ne'), ('nl'), ('nn'), ('no'), ('oc'), ('or'), ('pa'), ('pl'), ('ps'), ('pt'), ('rm'), ('ro'), ('ru'), ('rw'), ('sa'), ('sd'), ('si'), ('sk'), ('sl'), ('so'), ('sq'),
|
||||
('sr'), ('sv'), ('sw'), ('ta'), ('te'), ('tg'), ('th'), ('tk'), ('tl'), ('tr'), ('tt'), ('ug'), ('uk'), ('ur'), ('uz'), ('vi'), ('xh'), ('yo'), ('zh'), ('zu');
|
||||
|
||||
CREATE TABLE countries (val text PRIMARY KEY);
|
||||
INSERT INTO countries VALUES ('UNKNOWN'), ('AD'), ('AE'), ('AF'), ('AG'), ('AL'), ('AM'), ('AO'), ('AR'), ('AT'), ('AU'), ('AW'), ('AX'), ('AZ'), ('BA'), ('BB'), ('BD'), ('BE'), ('BF'), ('BG'), ('BH'), ('BI'),
|
||||
('BJ'), ('BM'), ('BN'), ('BO'), ('BQ'), ('BR'), ('BS'), ('BT'), ('BW'), ('BY'), ('BZ'), ('CA'), ('CD'), ('CF'), ('CG'), ('CH'), ('CI'), ('CL'), ('CM'), ('CN'), ('CO'), ('CR'),
|
||||
('CU'), ('CV'), ('CW'), ('CY'), ('CZ'), ('DE'), ('DJ'), ('DK'), ('DM'), ('DO'), ('DZ'), ('EC'), ('EE'), ('EG'), ('EH'), ('ER'), ('ES'), ('ET'), ('FI'), ('FJ'), ('FM'), ('FO'),
|
||||
('FR'), ('GA'), ('GB'), ('GD'), ('GE'), ('GF'), ('GH'), ('GI'), ('GL'), ('GM'), ('GN'), ('GP'), ('GQ'), ('GR'), ('GT'), ('GW'), ('GY'), ('HN'), ('HR'), ('HT'), ('HU'), ('ID'),
|
||||
('IE'), ('IL'), ('IM'), ('IN'), ('IQ'), ('IR'), ('IS'), ('IT'), ('JE'), ('JM'), ('JO'), ('JP'), ('KE'), ('KG'), ('KH'), ('KN'), ('KP'), ('KR'), ('KW'), ('KY'), ('KZ'), ('LA'),
|
||||
('LB'), ('LC'), ('LI'), ('LK'), ('LR'), ('LS'), ('LT'), ('LU'), ('LV'), ('LY'), ('MA'), ('MC'), ('MD'), ('ME'), ('MG'), ('MK'), ('ML'), ('MM'), ('MN'), ('MO'), ('MQ'), ('MR'),
|
||||
('MS'), ('MT'), ('MU'), ('MV'), ('MW'), ('MX'), ('MY'), ('MZ'), ('NA'), ('NC'), ('NE'), ('NG'), ('NI'), ('NL'), ('NO'), ('NP'), ('NU'), ('NZ'), ('OM'), ('PA'), ('PE'), ('PF'),
|
||||
('PG'), ('PH'), ('PK'), ('PL'), ('PS'), ('PT'), ('PW'), ('PY'), ('QA'), ('RE'), ('RO'), ('RS'), ('RU'), ('RW'), ('SA'), ('SB'), ('SC'), ('SD'), ('SE'), ('SG'), ('SI'), ('SJ'),
|
||||
('SK'), ('SL'), ('SM'), ('SN'), ('SO'), ('SR'), ('SS'), ('ST'), ('SV'), ('SX'), ('SY'), ('SZ'), ('TC'), ('TD'), ('TG'), ('TH'), ('TJ'), ('TL'), ('TM'), ('TN'), ('TO'), ('TR'),
|
||||
('TT'), ('TV'), ('TW'), ('TZ'), ('UA'), ('UG'), ('US'), ('UY'), ('UZ'), ('VA'), ('VC'), ('VE'), ('VG'), ('VN'), ('WS'), ('XK'), ('YE'), ('ZA'), ('ZM'), ('ZW');
|
||||
|
||||
CREATE TABLE user_roles(role text PRIMARY KEY);
|
||||
INSERT INTO user_roles VALUES ('ADMIN'), ('NATIONAL_ADMIN'), ('USER'), ('PENDING'), ('NOT_AUTHORIZED');
|
||||
|
||||
CREATE TABLE users (
|
||||
email text PRIMARY KEY,
|
||||
valid boolean DEFAULT true,
|
||||
role text NOT NULL default 'USER' REFERENCES user_roles(role)
|
||||
);
|
||||
|
||||
CREATE TABLE user_countries (
|
||||
email text REFERENCES users(email),
|
||||
country text REFERENCES countries(val),
|
||||
PRIMARY KEY(email, country)
|
||||
);
|
||||
|
||||
CREATE SEQUENCE organizations_id_seq;
|
||||
|
||||
CREATE TABLE organizations (
|
||||
id text PRIMARY KEY DEFAULT 'openorgs____::'||lpad(nextval('organizations_id_seq')::text,10,'0'),
|
||||
name text,
|
||||
type text NOT NULL DEFAULT 'UNKNOWN' REFERENCES org_types(val),
|
||||
lat double precision,
|
||||
lng double precision,
|
||||
city text,
|
||||
country text REFERENCES countries(val),
|
||||
created_by text,
|
||||
creation_date timestamp with time zone DEFAULT now(),
|
||||
modified_by text,
|
||||
modification_date timestamp with time zone DEFAULT now()
|
||||
);
|
||||
CREATE INDEX organizations_type_idx ON organizations(type);
|
||||
CREATE INDEX organizations_country_idx ON organizations(country);
|
||||
|
||||
CREATE TABLE other_ids (
|
||||
id text REFERENCES organizations(id) ON UPDATE CASCADE,
|
||||
otherid text,
|
||||
type text REFERENCES id_types(val),
|
||||
PRIMARY KEY (id, otherid, type)
|
||||
);
|
||||
CREATE INDEX other_ids_id_idx ON other_ids(id);
|
||||
|
||||
CREATE TABLE other_names (
|
||||
id text REFERENCES organizations(id) ON UPDATE CASCADE,
|
||||
name text,
|
||||
lang text REFERENCES languages(val),
|
||||
PRIMARY KEY (id, name, lang)
|
||||
);
|
||||
CREATE INDEX other_names_id_idx ON other_names(id);
|
||||
|
||||
CREATE TABLE acronyms (
|
||||
id text REFERENCES organizations(id) ON UPDATE CASCADE,
|
||||
acronym text,
|
||||
PRIMARY KEY (id, acronym)
|
||||
);
|
||||
CREATE INDEX acronyms_id_idx ON acronyms(id);
|
||||
|
||||
CREATE TABLE relationships (
|
||||
id1 text REFERENCES organizations(id) ON UPDATE CASCADE,
|
||||
reltype text,
|
||||
id2 text REFERENCES organizations(id) ON UPDATE CASCADE,
|
||||
PRIMARY KEY (id1, reltype, id2)
|
||||
);
|
||||
CREATE INDEX relationships_id1_idx ON relationships(id1);
|
||||
CREATE INDEX relationships_id2_idx ON relationships(id2);
|
||||
|
||||
CREATE TABLE urls (
|
||||
id text REFERENCES organizations(id) ON UPDATE CASCADE,
|
||||
url text,
|
||||
PRIMARY KEY (id, url)
|
||||
);
|
||||
CREATE INDEX urls_id_idx ON urls(id);
|
||||
|
||||
CREATE TABLE oa_duplicates (
|
||||
local_id text REFERENCES organizations(id) ON UPDATE CASCADE,
|
||||
oa_original_id text NOT NULL,
|
||||
oa_name text NOT NULL,
|
||||
oa_acronym text,
|
||||
oa_country text,
|
||||
oa_url text,
|
||||
oa_collectedfrom text,
|
||||
reltype text NOT NULL DEFAULT 'suggested',
|
||||
PRIMARY KEY (local_id, oa_original_id)
|
||||
);
|
||||
CREATE INDEX oa_duplicates_local_id_idx ON oa_duplicates(local_id);
|
||||
|
||||
|
||||
CREATE TABLE oa_conflicts (
|
||||
id1 text REFERENCES organizations(id) ON UPDATE CASCADE,
|
||||
id2 text REFERENCES organizations(id) ON UPDATE CASCADE,
|
||||
reltype text NOT NULL DEFAULT 'suggested',
|
||||
idgroup text,
|
||||
PRIMARY KEY (id1, id2)
|
||||
);
|
||||
CREATE INDEX oa_conflicts_id1_idx ON oa_conflicts(id1);
|
||||
CREATE INDEX oa_conflicts_id2_idx ON oa_conflicts(id2);
|
||||
CREATE INDEX oa_conflicts_idgroup_idx ON oa_conflicts(idgroup);
|
||||
|
||||
CREATE VIEW organizations_view AS SELECT
|
||||
org.id,
|
||||
org.name,
|
||||
org.type,
|
||||
org.lat,
|
||||
org.lng,
|
||||
org.city,
|
||||
org.country,
|
||||
COALESCE(jsonb_agg(DISTINCT jsonb_build_object('id', oid.otherid, 'type', oid.type)) FILTER (WHERE oid.otherid IS NOT NULL), '[]') AS other_ids,
|
||||
COALESCE(jsonb_agg(DISTINCT jsonb_build_object('name', n.name, 'lang', n.lang)) FILTER (WHERE n.name IS NOT NULL), '[]') AS other_names,
|
||||
COALESCE(jsonb_agg(DISTINCT a.acronym) FILTER (WHERE a.acronym IS NOT NULL), '[]') AS acronyms,
|
||||
COALESCE(jsonb_agg(DISTINCT u.url) FILTER (WHERE u.url IS NOT NULL), '[]') AS urls,
|
||||
COALESCE(jsonb_agg(DISTINCT jsonb_build_object('relatedOrgId', relorg.id, 'relatedOrgName', relorg.name, 'type', r.reltype)) FILTER (WHERE relorg.id IS NOT NULL), '[]') AS relations
|
||||
FROM
|
||||
organizations org
|
||||
LEFT OUTER JOIN other_ids oid ON (org.id = oid.id)
|
||||
LEFT OUTER JOIN other_names n ON (org.id = n.id)
|
||||
LEFT OUTER JOIN acronyms a ON (org.id = a.id)
|
||||
LEFT OUTER JOIN urls u ON (org.id = u.id)
|
||||
LEFT OUTER JOIN relationships r ON (org.id = r.id1)
|
||||
LEFT OUTER JOIN organizations relorg ON (relorg.id = r.id2)
|
||||
GROUP BY
|
||||
org.id,
|
||||
org.name,
|
||||
org.type,
|
||||
org.lat,
|
||||
org.lng,
|
||||
org.city,
|
||||
org.country;
|
||||
|
||||
CREATE VIEW organizations_info_view AS SELECT
|
||||
org.id,
|
||||
org.name,
|
||||
org.created_by,
|
||||
org.creation_date,
|
||||
org.modified_by,
|
||||
org.modification_date,
|
||||
count(DISTINCT d.oa_original_id) as n_duplicates,
|
||||
count(DISTINCT c.id2) as n_conflicts
|
||||
FROM organizations org
|
||||
LEFT OUTER JOIN oa_duplicates d ON (org.id = d.local_id AND d.reltype = 'suggested')
|
||||
LEFT OUTER JOIN oa_conflicts c ON (org.id = c.id1 AND c.reltype = 'suggested')
|
||||
GROUP BY org.id;
|
||||
|
||||
CREATE VIEW organizations_simple_view AS SELECT
|
||||
org.id,
|
||||
org.name,
|
||||
org.type,
|
||||
org.city,
|
||||
org.country,
|
||||
array_agg(DISTINCT a.acronym) FILTER (WHERE a.acronym IS NOT NULL) AS acronyms
|
||||
FROM
|
||||
organizations org
|
||||
LEFT OUTER JOIN acronyms a ON (org.id = a.id)
|
||||
GROUP BY
|
||||
org.id,
|
||||
org.name,
|
||||
org.type,
|
||||
org.city,
|
||||
org.country;
|
||||
|
||||
CREATE VIEW users_view AS SELECT
|
||||
u.email,
|
||||
u.valid,
|
||||
u.role,
|
||||
array_agg(uc.country) FILTER (WHERE uc.country IS NOT NULL) AS countries
|
||||
FROM
|
||||
users u
|
||||
LEFT OUTER JOIN user_countries uc ON (u.email = uc.email)
|
||||
GROUP BY u.email, u.valid, u.role
|
||||
ORDER BY u.email;
|
||||
|
||||
CREATE VIEW suggestions_info_by_country_view AS SELECT c.val AS country,
|
||||
coalesce(t1.n_duplicates, 0) AS n_duplicates,
|
||||
coalesce(t2.n_conflicts, 0) AS n_conflicts
|
||||
FROM countries c
|
||||
LEFT OUTER JOIN (SELECT o.country AS country, count(DISTINCT d.*) AS n_duplicates FROM oa_duplicates d LEFT OUTER JOIN organizations o ON (d.local_id = o.id) GROUP BY o.country) AS t1 ON (t1.country = c.val)
|
||||
LEFT OUTER JOIN (SELECT o.country AS country, count(DISTINCT c.idgroup) AS n_conflicts FROM oa_conflicts c LEFT OUTER JOIN organizations o ON (c.id1 = o.id) GROUP BY o.country) AS t2 ON (t2.country = c.val);
|
||||
|
||||
CREATE VIEW conflict_groups_view AS SELECT
|
||||
c.idgroup AS idgroup,
|
||||
o1.id AS id_1,
|
||||
o1.name AS name_1,
|
||||
o1.type AS type_1,
|
||||
o1.city AS city_1,
|
||||
o1.country AS country_1,
|
||||
o2.id AS id_2,
|
||||
o2.name AS name_2,
|
||||
o2.type AS type_2,
|
||||
o2.city AS city_2,
|
||||
o2.country AS country_2
|
||||
FROM
|
||||
oa_conflicts c
|
||||
LEFT OUTER JOIN organizations o1 ON (c.id1 = o1.id)
|
||||
LEFT OUTER JOIN organizations o2 ON (c.id2 = o2.id)
|
||||
WHERE
|
||||
o1.id IS NOT NULL AND O2.id IS NOT NULL AND c.idgroup IS NOT NULL;
|
||||
|
||||
CREATE VIEW duplicate_groups_view AS SELECT
|
||||
o.id,
|
||||
o.name,
|
||||
o.city,
|
||||
o.country,
|
||||
count(d.*) as n_duplicates
|
||||
FROM
|
||||
oa_duplicates d
|
||||
LEFT OUTER JOIN organizations o ON (o.id = d.local_id)
|
||||
WHERE
|
||||
d.reltype = 'suggested'
|
||||
GROUP BY o.id, o.name, o.city, o.country
|
||||
ORDER BY o.name;
|
||||
|
12
apps/dnet-orgs-database-application/src/main/resources/static/resources/css/bootstrap.min.css
vendored
Normal file
12
apps/dnet-orgs-database-application/src/main/resources/static/resources/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,14 @@
|
|||
<table class="table table-sm table-hover col-lg-3">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th>{{field}}</th>
|
||||
<th class="text-right">#</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="e in entries">
|
||||
<td><a href="#!{{resultsBasePath}}/0/50/{{e.value}}">{{e.value}}</a></td>
|
||||
<td class="text-right">{{e.count}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
|
@ -0,0 +1,14 @@
|
|||
<h4>{{info.name}}</h4>
|
||||
|
||||
<div class="alert alert-success" ng-if="message">{{message}}</div>
|
||||
|
||||
<p class="text-muted" ng-if="!message">
|
||||
<b>ID: </b>{{info.id}}<br /> <b>Created at</b> {{info.creationDate | date:'MMMM d, y HH:mm:ss'}} <b>by</b> {{info.createdBy}}<br /> <b>Modified at</b> {{info.modificationDate | date:'MMMM d, y HH:mm:ss'}} <b>by</b>
|
||||
{{info.modifiedBy}}
|
||||
</p>
|
||||
|
||||
<div class="card">
|
||||
<org-tabs-menu org-id="{{orgId}}" info="info" org="org" events="events" selected="currentTab"></org-tabs-menu>
|
||||
<org-form-metadata org-id="{{orgId}}" org="org" vocabularies="vocabularies" info-method="getInfo()" ng-if="currentTab == 1"></org-form-metadata>
|
||||
<org-dedup-events org-id="{{orgId}}" events="events" vocabularies="vocabularies" info-method="getInfo()" ng-if="currentTab == 2"></org-dedup-events>
|
||||
</div>
|
|
@ -0,0 +1,40 @@
|
|||
<div>
|
||||
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
<input type="text" class="form-control" ng-model="conflictFilter" placeholder="Filter...">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text text-outline-primary" id="inputGroup-sizing-sm">Country:</span>
|
||||
<button class="btn btn-outline-primary dropdown-toggle" data-toggle="dropdown">{{country}}</button>
|
||||
<div class="dropdown-menu">
|
||||
<small>
|
||||
<a class="dropdown-item" href="#!/suggestions/{{c}}/2"
|
||||
ng-repeat="(c, vals) in info.byCountry"
|
||||
ng-if="vals.nConflicts > 0">
|
||||
{{c}} <span class="badge badge-danger float-right">{{vals.nConflicts}}</span>
|
||||
</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card text-white mb-3" ng-repeat="w in conflicts | filter:conflictFilter" class="mb-2">
|
||||
<div class="card-header bg-primary text-white py-1">Group {{$index+1}}</div>
|
||||
<table class="table table-sm">
|
||||
<tr ng-repeat="o in w">
|
||||
<th style="width:40px" class="text-center">#{{$index+1}}</th>
|
||||
<td><a href="#!/edit/0/{{o.id}}" title="{{o.id}}">{{o.name}}</a></td>
|
||||
<td style="width:250px"><img ng-src="resources/images/flags/{{o.country}}.gif" /> {{o.city}}, {{o.country}}</td>
|
||||
<td style="width:80px" class="text-right">{{o.type}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="card-footer bg-secondary py-1">
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-primary"
|
||||
data-toggle="modal" data-target="#resolveConflictsModal"
|
||||
ng-click="prepareConflictsModal(w)">resolve</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<resolve-conflicts-modal modal-id="resolveConflictsModal" orgs="orgs" selected-orgs="selectedOrgs"></resolve-conflicts-modal>
|
|
@ -0,0 +1,59 @@
|
|||
<div>
|
||||
|
||||
<div class="input-group input-group-sm mb-3">
|
||||
<input type="text" class="form-control" ng-model="duplicateFilter" placeholder="Filter...">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text text-outline-primary" id="inputGroup-sizing-sm">Country:</span>
|
||||
<button class="btn btn-outline-primary dropdown-toggle" data-toggle="dropdown">{{country}}</button>
|
||||
<div class="dropdown-menu">
|
||||
<small>
|
||||
<a class="dropdown-item" href="#!/suggestions/{{c}}/1"
|
||||
ng-repeat="(c, vals) in info.byCountry"
|
||||
ng-if="vals.nDuplicates > 0">
|
||||
{{c}} <span class="badge badge-primary float-right">{{vals.nDuplicates}}</span>
|
||||
</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-sm table-hover">
|
||||
<thead class="thead-light">
|
||||
<tr class="d-flex">
|
||||
<th class="col-8">Organization</th>
|
||||
<th class="col-3">Place</th>
|
||||
<th class="col-1 text-right"># pending duplicates</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="d in duplicates | filter:duplicateFilter" class="d-flex">
|
||||
<td class="col-8">
|
||||
<a href="javascript:void(0)" title="{{d.id}}" ng-click="prepareDuplicatesModal(d)" data-toggle="modal" data-target="#duplicatesModal">{{d.name}}</a>
|
||||
<a href="#!/edit/0/{{d.id}}" title="edit"><i class="fa fa-edit"></i></a>
|
||||
</td>
|
||||
<td class="col-3"><img ng-src="resources/images/flags/{{d.country}}.gif" /> {{d.city}}, {{d.country}}</td>
|
||||
<td class="col-1 text-right">{{d.numberOfDuplicates}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="duplicatesModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">{{currentOrg.name}}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="text-muted" ng-if="currentDuplicates.length == 0">No duplicates</div>
|
||||
<org-details org="currentOrgDetails" org-title="Registered organization" show="default"></org-details>
|
||||
<org-form-duplicates duplicates="currentDuplicates"></org-form-duplicates>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary" data-dismiss="modal" ng-click="saveCurrentDuplicates()" ng-if="currentDuplicates.length > 0">Save changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,28 @@
|
|||
<div class="card mb-3">
|
||||
<div class="card-header bg-primary text-white py-1">Conflicts</div>
|
||||
|
||||
<div class="card-body text-muted" ng-if="conflicts.length == 0">No conflicts</div>
|
||||
|
||||
<table class="table table-sm mt-2" ng-if="conflicts.length > 0">
|
||||
<thead>
|
||||
<tr class="d-flex">
|
||||
<th class="col-6 pl-3" style="border-top: none;">Related organization</th>
|
||||
<th class="col-2 text-center" style="border-top: none;">Type</th>
|
||||
<th class="col-4 text-right" style="border-top: none;">Place</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="d-flex" ng-repeat="sr in conflicts">
|
||||
<td class="col-6 pl-3">{{sr.name}}<br /><a href="#!/edit/0/{{sr.id}}" class="small text-monospace">{{sr.id}}</a></td>
|
||||
<td class="col-2 text-center small">{{sr.type}}</td>
|
||||
<td class="col-4 text-right small"><img ng-src="resources/images/flags/{{sr.country}}.gif" /> {{sr.city}}, {{sr.country}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="card-footer text-right" ng-if="showSaveButton && conflicts.length > 0">
|
||||
<button class="btn btn-sm btn-primary" data-toggle="modal" data-target="#resolveConflictsModal" ng-click="prepareConflictsModal()">resolve conflicts</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<resolve-conflicts-modal modal-id="resolveConflictsModal" orgs="candidateConflicts" selected-orgs="selectedConflicts"></resolve-conflicts-modal>
|
|
@ -0,0 +1,45 @@
|
|||
<div class="card mb-3">
|
||||
<div class="card-header bg-primary text-white py-1">Duplicates</div>
|
||||
|
||||
<div class="text-muted card-body" ng-if="duplicates.length == 0">No duplicates</div>
|
||||
|
||||
<table class="table table-sm mt-2" ng-if="duplicates.length > 0">
|
||||
<thead>
|
||||
<tr class="d-flex">
|
||||
<th class="col-4 pl-3" style="border-top: none;">Related organization</th>
|
||||
<th class="col-1 text-center" style="border-top: none;">Acronym</th>
|
||||
<th class="col-2 text-center" style="border-top: none;">Country</th>
|
||||
<th class="col-3" style="border-top: none;">Source</th>
|
||||
<th class="col-2" style="border-top: none;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="d-flex" ng-repeat="sr in duplicates">
|
||||
<td class="col-4 pl-3">{{sr.oaName}} <span class="small" ng-if="sr.oaUrl"><br />
|
||||
<b>URL: </b><a href="{{sr.oaUrl}}" target="_blank">{{sr.oaUrl}}</a></span>
|
||||
</td>
|
||||
<td class="col-1 text-center small">{{sr.oaAcronym}}</td>
|
||||
<td class="col-2 text-center small"><img ng-src="resources/images/flags/{{sr.oaCountry}}.gif" /> {{sr.oaCountry}}</td>
|
||||
<td class="col-3 small"><b>Collected from:</b> {{sr.oaCollectedFrom}}<br /> <b>Original Id:</b> <span class="text-monospace">{{sr.oaOriginalId}}</span></td>
|
||||
<td class="col-2 text-right">
|
||||
<div class="btn-group btn-group-toggle btn-group-sm" data-toggle="buttons">
|
||||
<label class="btn" ng-class="{'btn-danger' : sr.relType == 'is_different', 'btn-outline-danger' : sr.relType != 'is_different'}"> <input type="radio" autocomplete="off" ng-model="sr.relType"
|
||||
value="is_different" ng-class="{'active' : sr.relType == 'is_different'}"><i class="fas fa-times fa-fw"></i>
|
||||
</label>
|
||||
<label class="btn" ng-class="{'btn-info' : sr.relType == 'suggested', 'btn-outline-info' : sr.relType != 'suggested'}"> <input type="radio" autocomplete="off" ng-model="sr.relType"
|
||||
value="suggested" ng-class="{'active' : sr.relType == 'suggested'}"><i class="fas fa-question fa-fw"></i>
|
||||
</label>
|
||||
<label class="btn" ng-class="{'btn-success' : sr.relType == 'is_similar', 'btn-outline-success' : sr.relType != 'is_similar'}"> <input type="radio" autocomplete="off" ng-model="sr.relType"
|
||||
value="is_similar" ng-class="{'active' : sr.relType == 'is_similar'}" /><i class="fas fa-check fa-fw"></i>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="card-footer text-right" ng-if="showSaveButton && duplicates.length > 0">
|
||||
<button class="btn btn-sm btn-primary" ng-click="saveFunction()">save</button>
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,282 @@
|
|||
<div class="card-body">
|
||||
<form name="organizationForm">
|
||||
<fieldset>
|
||||
<legend>Official name and type</legend>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text bg-primary text-white">name</div>
|
||||
</div>
|
||||
<input name="org_nm" type="text" class="form-control"
|
||||
placeholder="organization name..." ng-model="org.name"
|
||||
required="required"
|
||||
ng-class="{'is-invalid' : organizationForm.org_nm.$error.required}" />
|
||||
<div class="input-group-append input-group-prepend">
|
||||
<div class="input-group-text bg-primary text-white">type</div>
|
||||
</div>
|
||||
<select name="org_tp" class="custom-select" ng-model="org.type"
|
||||
required="required"
|
||||
ng-class="{'is-invalid' : organizationForm.org_tp.$error.required}">
|
||||
<option disabled="disabled" value=''>type...</option>
|
||||
<option ng-repeat="t in vocabularies.orgTypes">{{t}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="mt-4">
|
||||
<legend>Geographical location</legend>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text bg-primary text-white">city</div>
|
||||
</div>
|
||||
<input name="org_ct" type="text" class="form-control" placeholder=""
|
||||
ng-model="org.city" />
|
||||
<div class="input-group-append input-group-prepend">
|
||||
<div class="input-group-text bg-primary text-white">country</div>
|
||||
</div>
|
||||
<select name="org_cntr" class="custom-select" ng-model="org.country"
|
||||
required="required"
|
||||
ng-class="{'is-invalid' : organizationForm.org_cntr.$error.required}">
|
||||
<option disabled="disabled" value=''>country...</option>
|
||||
<option ng-repeat="c in vocabularies.countries">{{c}}</option>
|
||||
</select>
|
||||
<div class="input-group-append input-group-prepend">
|
||||
<div class="input-group-text bg-primary text-white">lat</div>
|
||||
</div>
|
||||
<input name="org_lat" type="text" class="form-control"
|
||||
placeholder="0.0" ng-model="org.lat" />
|
||||
<div class="input-group-append input-group-prepend">
|
||||
<div class="input-group-text bg-primary text-white">lng</div>
|
||||
</div>
|
||||
<input name="org_lng" type="text" class="form-control"
|
||||
placeholder="0.0" ng-model="org.lng" />
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="mt-4">
|
||||
<legend>Other names and identifiers</legend>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-lg-8 mb-2">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white text-center py-1">Acronyms</div>
|
||||
<table class="table table-sm">
|
||||
<tbody>
|
||||
<tr ng-repeat="a in org.acronyms">
|
||||
<td>{{a}}</td>
|
||||
<td class="text-right" style="width: 44px">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger"
|
||||
ng-click="org.acronyms.splice($index, 1)">
|
||||
<i class="fa fa-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr ng-init="newAcronym=''">
|
||||
<td><input type="text" class="form-control form-control-sm"
|
||||
placeholder="new acronym..." ng-model='newAcronym' /></td>
|
||||
<td class="text-right" style="width: 44px">
|
||||
<button type="button" class="btn btn-sm btn-outline-success"
|
||||
ng-click="org.acronyms.push(newAcronym); newAcronym=''"
|
||||
ng-disabled="!newAcronym || org.acronyms.indexOf(newAcronym) !== -1">
|
||||
<i class="fa fa-plus"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-lg-8 mb-2">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white text-center py-1">Aliases</div>
|
||||
<table class="table table-sm">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th>name</th>
|
||||
<th style="width: 156px">language</th>
|
||||
<th style="width: 44px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="n in org.otherNames">
|
||||
<td>{{n.name}}</td>
|
||||
<td>{{n.lang}}</td>
|
||||
<td class="text-right">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger"
|
||||
ng-click="org.otherNames.splice($index, 1)">
|
||||
<i class="fa fa-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr ng-init="newOtherName=newLang=''">
|
||||
<td><input type="text" class="form-control form-control-sm"
|
||||
placeholder="new alias..." ng-model="newOtherName" /></td>
|
||||
<td><select class="custom-select custom-select-sm"
|
||||
ng-model="newLang">
|
||||
<option disabled="disabled" value=''>language...</option>
|
||||
<option ng-repeat="l in vocabularies.languages">{{l}}</option>
|
||||
</select></td>
|
||||
<td class="text-right" style="width: 44px">
|
||||
<button type="button" class="btn btn-sm btn-outline-success"
|
||||
ng-click="org.otherNames.push({'name': newOtherName, 'lang': newLang}); newOtherName=newLang=''"
|
||||
ng-disabled="!newOtherName || !newLang">
|
||||
<i class="fa fa-plus"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-lg-8 mb-2">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white text-center py-1">Identifiers</div>
|
||||
<table class="table table-sm">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th>id</th>
|
||||
<th style="width: 156px">type</th>
|
||||
<th style="width: 44px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="id in org.otherIdentifiers">
|
||||
<td>{{id.id}}</td>
|
||||
<td>{{id.type}}</td>
|
||||
<td class="text-right" style="width: 44px">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger"
|
||||
ng-click="org.otherIdentifiers.splice($index, 1)">
|
||||
<i class="fa fa-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr ng-init="newId=newIdType=''">
|
||||
<td><input type="text" class="form-control form-control-sm"
|
||||
placeholder="new id..." ng-model="newId" /></td>
|
||||
<td><select class="custom-select custom-select-sm"
|
||||
ng-model="newIdType">
|
||||
<option disabled="disabled" value=''>type...</option>
|
||||
<option ng-repeat="t in vocabularies.idTypes">{{t}}</option>
|
||||
</select></td>
|
||||
<td class="text-right" style="width: 44px">
|
||||
<button type="button" class="btn btn-sm btn-outline-success"
|
||||
ng-click="org.otherIdentifiers.push({'id': newId, 'type': newIdType}); newId=newIdType=''"
|
||||
ng-disabled="!newId || !newIdType">
|
||||
<i class="fa fa-plus"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-lg-8 mb-2">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white text-center py-1">Urls</div>
|
||||
<table class="table table-sm">
|
||||
<tbody>
|
||||
<tr ng-repeat="u in org.urls">
|
||||
<td><a href="{{u}}" target="_blank">{{u}}</a></td>
|
||||
<td class="text-right" style="width: 44px">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger"
|
||||
ng-click="org.urls.splice($index, 1)">
|
||||
<i class="fa fa-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr ng-init="newUrl=''">
|
||||
<td><input type="text" class="form-control form-control-sm"
|
||||
placeholder="http://..." ng-model="newUrl" /></td>
|
||||
<td class="text-right" style="width: 44px">
|
||||
<button type="button" class="btn btn-sm btn-outline-success"
|
||||
ng-click="org.urls.push(newUrl); newUrl=''"
|
||||
ng-disabled="!newUrl || org.urls.indexOf(newUrl) !== -1">
|
||||
<i class="fa fa-plus"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="mt-4">
|
||||
<legend>Relations</legend>
|
||||
<div class="form-group row">
|
||||
<div class="col-lg-8 mb-2">
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white text-center py-1">Relations</div>
|
||||
<table class="table table-sm">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th class="pl-3" style="border-top: none;">Related organization</th>
|
||||
<th style="border-top: none; width: 156px">Type</th>
|
||||
<th style="border-top: none; width: 44px"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-if="org.relations.length == 0">
|
||||
<td class="text-center text-muted" colspan="3">No relations</td>
|
||||
</tr>
|
||||
<tr ng-repeat="r in org.relations">
|
||||
<td class="pl-3"><a href="#!/edit/0/{{r.relatedOrgId}}" title="{{r.relatedOrgId}}">{{r.relatedOrgName}}</a></td>
|
||||
<td>{{r.type}}</td>
|
||||
<td class="text-right">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" ng-click="org.relations.splice($index, 1)"><i class="fa fa-trash"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="text" placeholder="add a related organization..." readonly="readonly"
|
||||
class="form-control form-control-sm" style="background-color: white; color: #007bff;"
|
||||
ng-model="newRelation.name" ng-click="resetSelectedRelation()"
|
||||
data-toggle="modal" data-target="#selectRelatedOrgModal"/>
|
||||
</td>
|
||||
<td>
|
||||
<select class="custom-select custom-select-sm" ng-model="newRelType">
|
||||
<option disabled="disabled" value=''>rel type...</option>
|
||||
<option ng-repeat="t in vocabularies.relTypes">{{t}}</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<button type="button" class="btn btn-sm btn-outline-success" ng-disabled="!newRelType || !newRelation.id" ng-click="addNewRelation()"><i class="fa fa-plus"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<button type="submit" class="btn btn-primary" ng-click="save()" ng-disabled="organizationForm.$invalid">save</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<select-org-modal modal-id="selectRelatedOrgModal" selected-org="newRelation"></select-org-modal>
|
|
@ -0,0 +1,10 @@
|
|||
<div class="card-header">
|
||||
<ul class="nav nav-tabs card-header-tabs">
|
||||
<li class="nav-item">
|
||||
<a href="javascript:void(0)" class="nav-link" ng-class="{'active': selected == 1}" ng-click="loadOrg()">Metadata Management</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="javascript:void(0)" class="nav-link" ng-class="{'active': selected == 2}" ng-click="loadDedupEvents()">Dedup Events <span class="badge badge-primary ml-2">{{info.nDuplicates}}</span> <span class="badge badge-danger">{{info.nConflicts}}</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
|
@ -0,0 +1,51 @@
|
|||
<div class="modal fade" id="{{modalId}}" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Resolve conflicts</h5>
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
</div>
|
||||
<div class="modal-body" style="min-height: 300px">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="card border-primary">
|
||||
<div class="card-header text-white bg-primary">Suggested organizations</div>
|
||||
<div class="card-body" ng-repeat="o in orgs | filter:{show:'secondary'}" ng-class="{'pb-0' : $index==0 , 'py-0' : $index > 0 }">
|
||||
<org-details org="o" org-title="{{o.id}}" show="{{o.show}}"></org-details>
|
||||
<div class="text-right mb-3">
|
||||
<button type="button" class="btn btn-sm btn-primary" ng-click="selectOrg(o)">select >></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body text-secondary text-center" ng-show="selectedOrgs.length == orgs.length">no organization(s)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="card border-primary">
|
||||
<div class="card-header text-white bg-primary">New group</div>
|
||||
<div class="card-body" ng-repeat="o in selectedOrgs" ng-class="{'pb-0' : $index==0 , 'py-0' : $index > 0 }">
|
||||
<org-details org="o" org-title="{{($index==0)?'Master organization':'Secondary organization ' + $index}}" show="{{o.show}}"></org-details>
|
||||
</div>
|
||||
<div class="card-body" ng-show="selectedOrgs.length == 0">
|
||||
<div class="card border-secondary">
|
||||
<div class="card-body text-secondary text-center">select master organization</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body pt-0" ng-show="selectedOrgs.length == 1">
|
||||
<div class="card border-secondary">
|
||||
<div class="card-body text-secondary text-center">select secondary organization(s)</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer" ng-show="selectedOrgs.length > 0">
|
||||
<button type="button" class="btn btn-sm btn-secondary" ng-click="reset()" ng-show="selectedOrgs.length > 0">reset</button>
|
||||
<button type="button" class="btn btn-sm btn-primary float-right" ng-click="createGroup()" ng-show="selectedOrgs.length > 1">create group</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,27 @@
|
|||
<div class="modal fade" id="{{modalId}}" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Select Organization</h5>
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
</div>
|
||||
<div class="modal-body" style="min-height: 300px">
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="form-control" ng-model="searchText" />
|
||||
<div class="input-group-append">
|
||||
<button type="button" class="btn btn-outline-primary" ng-click="search(searchText, 0, 25)">Search</button>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-show="searchValue">
|
||||
|
||||
<org-results orgs="searchOrgs"
|
||||
prev-function="search(searchValue, searchOrgs.number - 1, searchOrgs.size)"
|
||||
next-function="search(searchValue, searchOrgs.number + 1, searchOrgs.size)"
|
||||
selected-org="selectedOrg"
|
||||
mode="select-modal"></org-results>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,8 @@
|
|||
<div class="card">
|
||||
<div class="card-header">
|
||||
<ul class="nav nav-tabs card-header-tabs">
|
||||
<li class="nav-item"><a href="javascript:void(0)" class="nav-link active">Metadata</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<org-form-metadata org="org" vocabularies="vocabularies" mode="insert"></org-form-metadata>
|
||||
</div>
|
|
@ -0,0 +1,11 @@
|
|||
<div class="card-body">
|
||||
|
||||
<org-details org="currentOrgDetails" org-title="Current organization" show="default"></org-details>
|
||||
|
||||
<org-form-duplicates duplicates="events.duplicates" save-function="saveDuplicates()" show-save-button="1"></org-form-duplicates>
|
||||
|
||||
<org-form-conflicts conflicts="events.conflicts" save-function="saveConflicts()" org-id="{{currentOrgDetails.id}}" show-save-button="1"></org-form-conflicts>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<div class="card mb-3" ng-show="show != 'hidden'">
|
||||
<div class="card-header py-1" ng-class="{
|
||||
'text-white bg-primary' : show == 'default',
|
||||
'text-white bg-success' : show == 'success',
|
||||
'text-white bg-info' : show == 'info',
|
||||
'bg-secondary' : show == 'secondary',
|
||||
}">{{orgTitle}}</div>
|
||||
<table class="table table-sm table-condensed">
|
||||
<tr class="d-flex">
|
||||
<th class="col-4 pl-3">Name</th>
|
||||
<td class="col-8">{{org.name}}</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<th class="col-4 pl-3">Type</th>
|
||||
<td class="col-8">{{org.type}}</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<th class="col-4 pl-3">Place</th>
|
||||
<td class="col-8">{{org.city}}, {{org.country}}</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<th class="col-4 pl-3">Acronyms</th>
|
||||
<td class="col-8">{{org.acronyms.join(', ')}}</td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<th class="col-4 pl-3">Also known as</th>
|
||||
<td class="col-8"><span ng-repeat="n in org.otherNames">{{n.name}}<br /></span></td>
|
||||
</tr>
|
||||
<tr class="d-flex">
|
||||
<th class="col-4 pl-3">Urls</th>
|
||||
<td class="col-8"><span ng-repeat="u in org.urls"><a href="{{u}}" target="_blank">{{u}}</a><br /></span></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
|
@ -0,0 +1,49 @@
|
|||
<p ng-if="mode != 'select-modal'">
|
||||
<span ng-if="orgs.totalElements > 0">Page: {{orgs.number + 1}} / {{orgs.totalPages}}<br />Total elements: {{orgs.totalElements}}<br />{{searchMessage}}</span>
|
||||
<span ng-if="orgs.totalElements == 0">Page: -<br />Total elements: 0<br />{{searchMessage}}</span>
|
||||
<span ng-if="!(orgs.totalElements || orgs.totalElements === 0)">Page:<br />Total elements:<br />{{searchMessage}}</span>
|
||||
</p>
|
||||
|
||||
<p ng-if="mode == 'select-modal'" class="text-right">
|
||||
<span ng-if="orgs.totalElements > 0"><b>Page:</b> {{orgs.number + 1}} / {{orgs.totalPages}} <b>- Total elements:</b> {{orgs.totalElements}}</span>
|
||||
<span ng-if="orgs.totalElements == 0"><b>Total elements:</b> 0</span>
|
||||
</p>
|
||||
|
||||
<h4 ng-if="orgs.totalElements == 0" class="text-center">
|
||||
No results
|
||||
</h4>
|
||||
|
||||
<div ng-if="orgs.totalElements > 0">
|
||||
<nav>
|
||||
<ul class="pagination justify-content-center">
|
||||
<li class="page-item" ng-class="{'disabled' : orgs.first }">
|
||||
<a class="page-link" href="javascript:void(0)" ng-click="prevFunction()">« Previous</a>
|
||||
</li>
|
||||
<li class="page-item" ng-class="{'disabled' : orgs.last }">
|
||||
<a class="page-link" href="javascript:void(0)" ng-click="nextFunction()">Next »</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<table class="table table-sm table-hover">
|
||||
<thead class="thead-light">
|
||||
<tr class="d-flex">
|
||||
<th class="col-6">Organization name</th>
|
||||
<th class="col-4">Place</th>
|
||||
<th class="col-1 text-center">Acronyms</th>
|
||||
<th class="col-1 text-right">Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="o in orgs.content" class="d-flex">
|
||||
<td class="col-6">
|
||||
<a ng-if="mode == 'select-modal'" href="javascript:void(0)" title="select" ng-click="selectOrg(o)" data-dismiss="modal">{{o.name}}</a>
|
||||
<a ng-if="mode != 'select-modal'" href="#!/edit/0/{{o.id}}" title="{{o.id}}">{{o.name}}</a>
|
||||
</td>
|
||||
<td class="col-4"><img ng-src="resources/images/flags/{{o.country}}.gif" /> {{o.city}}, {{o.country}}</td>
|
||||
<td class="col-1 text-center">{{o.acronyms.join()}}</td>
|
||||
<td class="col-1 text-right">{{o.type}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
|
@ -0,0 +1,4 @@
|
|||
<org-results search-message="Searching for country: {{fieldValue}}"
|
||||
orgs="orgs"
|
||||
prev-function="prev()"
|
||||
next-function="next()"></org-results>
|
|
@ -0,0 +1,4 @@
|
|||
<org-results search-message="Searching for type: {{fieldValue}}"
|
||||
orgs="orgs"
|
||||
prev-function="prev()"
|
||||
next-function="next()"></org-results>
|
|
@ -0,0 +1,13 @@
|
|||
<div class="row">
|
||||
<div class="offset-md-1 offset-lg-2 offset-xl-4 col-md-10 col-lg-8 col-xl-4">
|
||||
<form style="margin-top:200px;" ng-submit="search()">
|
||||
<div class="input-group input-group-lg">
|
||||
<input type="text" class="form-control" ng-model="searchText" autofocus="true" />
|
||||
<div class="input-group-append">
|
||||
<button type="submit" class="btn btn-outline-primary">Search</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<org-results search-message="Searching for: {{searchText}}"
|
||||
orgs="orgs"
|
||||
prev-function="prev()"
|
||||
next-function="next()"></org-results>
|
|
@ -0,0 +1,19 @@
|
|||
<div class="card">
|
||||
|
||||
<div class="card-header">
|
||||
<ul class="nav nav-tabs card-header-tabs">
|
||||
<li class="nav-item text-nowrap">
|
||||
<a href="#!/suggestions/_/1" class="nav-link" ng-class="{'active': currentTab == 1}">New Duplicates <span class="badge badge-primary ml-2">{{info.total.nDuplicates}}</span></a>
|
||||
</li>
|
||||
<li class="nav-item text-nowrap">
|
||||
<a href="#!/suggestions/_/2" class="nav-link" ng-class="{'active': currentTab == 2}">New Conflicts <span class="badge badge-danger ml-2">{{info.total.nConflicts}}</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<all-duplicates duplicates="duplicates" country="{{country}}" info="info" info-method="getInfo()" ng-if="currentTab == 1"></all-duplicates>
|
||||
<all-conflicts conflicts="conflicts" country="{{country}}" info="info" info-method="getInfo()" ng-if="currentTab == 2"></all-conflicts>
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,116 @@
|
|||
<h4>Users</h4>
|
||||
<br />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-10 col-lg-8">
|
||||
<input type="text" class="form-control form-control-sm mb-3" ng-model="userFilter.email" placeholder="Filter...">
|
||||
|
||||
<table class="table table-sm table-hover">
|
||||
<thead class="thead-light">
|
||||
<tr class="d-flex">
|
||||
<th class="col-4">User</th>
|
||||
<th class="col-1 text-center">Enabled</th>
|
||||
<th class="col-1 text-center">Super Admin</th>
|
||||
<th class="col-1 text-center">National Admin</th>
|
||||
<th class="col-3">Countries</th>
|
||||
<th class="col-2"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="u in users | filter:userFilter" class="d-flex">
|
||||
<th class="col-4" ng-class="{'text-secondary': !u.valid}">{{u.email}}</th>
|
||||
<td class="col-1 text-center text-success">
|
||||
<i class="fa fa-check-circle" ng-if="u.valid"></i>
|
||||
<span class="text-warning" ng-if="u.role == 'PENDING'">not configured</span>
|
||||
<span class="text-danger" ng-if="!u.valid && (u.role != 'PENDING')">disabled</span>
|
||||
</td>
|
||||
<td class="col-1 text-center">
|
||||
<i class="fa fa-check-circle" ng-if="u.role == 'ADMIN'"></i>
|
||||
</td>
|
||||
<td class="col-1 text-center">
|
||||
<i class="fa fa-check-circle" ng-if="u.role == 'NATIONAL_ADMIN'"></i>
|
||||
</td>
|
||||
<td class="col-3">
|
||||
<span ng-if="(u.role != 'ADMIN')">
|
||||
<img ng-src="resources/images/flags/{{c}}.gif" title="{{c}}" class="mr-1" ng-repeat="c in u.countries" />
|
||||
<span class="text-warning" ng-if="u.countries.length == 0"><i class="fa fa-exclamation-triangle"></i> no countries</span>
|
||||
</span>
|
||||
<span class="text-muted" ng-if="u.role == 'ADMIN'">All countries</span>
|
||||
</td>
|
||||
<td class="col-2 text-right">
|
||||
<a href="mailto:{{u.email}}" class="btn btn-sm btn-outline-info"><i class="fa fa-at"></i></a>
|
||||
<button type="button" class="btn btn-sm btn-outline-info" data-toggle="modal" data-target="#editUserModal" ng-click="setCurrentUser(u)"><i class="fa fa-edit"></i></button>
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" ng-click="deleteUser(u.email)"><i class="fa fa-trash"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="editUserModal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Edit user</h5>
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
</div>
|
||||
<div class="modal-body" style="min-height: 300px; max-height: 500px; overflow-y: auto;">
|
||||
<form>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-2 col-form-label">Email</label>
|
||||
<div class="col-sm-10"><a href="mailto:{{currentUser.email}}">{{currentUser.email}}</a></div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-2 col-form-label">Enabled</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" ng-model="currentUser.valid" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row" ng-if="superAdminMode && currentUser.valid">
|
||||
<label class="col-sm-2 col-form-label">Role</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" value="USER" ng-model="currentUser.role">
|
||||
<label class="form-check-label">USER</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" value="NATIONAL_ADMIN" ng-model="currentUser.role">
|
||||
<label class="form-check-label">NATIONAL ADMIN</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="radio" value="ADMIN" ng-model="currentUser.role">
|
||||
<label class="form-check-label">SUPER ADMIN</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3" ng-if="currentUser.valid && ((currentUser.role == 'USER') || (currentUser.role == 'NATIONAL_ADMIN'))">
|
||||
<div class="card-header bg-primary text-white py-1">Countries</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<div class="col-xs-6 col-sm-3 col-md-2 col-lg-1" ng-repeat="c in vocabularies.countries">
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" checklist-model="currentUser.countries" checklist-value="c"/>
|
||||
<label class="form-check-label">{{c}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary" data-dismiss="modal" ng-click="saveUser(currentUser)">Save changes</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 807 B |
Binary file not shown.
After Width: | Height: | Size: 947 B |
Binary file not shown.
After Width: | Height: | Size: 898 B |
Binary file not shown.
After Width: | Height: | Size: 1006 B |
Binary file not shown.
After Width: | Height: | Size: 949 B |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue