JR Utily

1ere etape reorganisation

Showing 100 changed files with 421 additions and 2011 deletions
grogEE.iml
.idea/
lib/
target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
.nb-gradle/
\ No newline at end of file
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>Data layer of GROG</name>
<url>http://legrog.org</url>
<parent>
<groupId>org.legrog</groupId>
<artifactId>grog-cubi</artifactId>
<version>3.0-SNAPSHOT</version>
</parent>
<artifactId>grog-entities</artifactId>
<packaging>jar</packaging>
<properties>
<hibernate-commons-annotations.version>5.0.1.Final</hibernate-commons-annotations.version>
<hibernate-jpa-2.1-api.version>1.0.0.Final</hibernate-jpa-2.1-api.version>
<solr.version>6.3.0</solr.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>${solr.version}</version>
</dependency>
<!-- **** TOOLS : LOGS + UTILS **** -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<!-- ** Hibernate deps ** -->
<dependency>
<groupId>antlr</groupId>
<artifactId>antlr</artifactId>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.common</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>${hibernate-commons-annotations.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>${hibernate-jpa-2.1-api.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
</dependencies>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>Executable to import empty DB of GROG</name>
<url>http://legrog.org</url>
<parent>
<groupId>org.legrog</groupId>
<artifactId>grog-cubi</artifactId>
<version>3.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<artifactId>grog-db-generator</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.legrog</groupId>
<artifactId>grog-entities</artifactId>
<version>3.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
package org.legrog.entities;
import javax.persistence.*;
/*
Entité persistante représentant les propriétés qui sont paramétrées pour un utilisateur.
Migréee depuis la v2.
*/
@Entity
public class AccountAttribute {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int userAttributeId;
public int getUserAttributeId() {
return userAttributeId;
}
/**
* The linked account.
*/
@ManyToOne
private Account account;
/**
* Retrieve the account this attribute is attached to.
* hibernate.many-to-one
* column="ID_UTILISATEUR"
* class="org.roliste.data.db.Account"
* not-null="true"
* access="property"
* lazy="proxy"
* properties-name="PropertyPerUser"
* foreign-key="FK_ATTRIBUTUTILISATEUR_UTILISATEUR"
* @return the {link org.roliste.data.db.Account} this attribute is attached to.
* Shall not be <code>null</code>.
* see #setAccount(org.roliste.data.db.Account)
*/
public Account getAccount() {
return account;
}
/**
* Set the account this attribute is attached to.
* @param account the new {link org.roliste.data.db.Account} this attribute will be attached to. Shall not be <code>null</code>.
* @see #getAccount()
*/
public void setAccount(Account account) {
this.account = account;
}
/**
* The linked property.
*/
@ManyToOne
private AccountProperty accountProperty;
/**
* Retrieve the property this attribute is attached to.
* hibernate.many-to-one
* column="ID_PROP"
* class="org.roliste.data.db.AccountProperty"
* not-null="true"
* access="property"
* lazy="false"
* properties-name="PropertyPerUser"
* foreign-key="FK_ATTRIBUTUTILISATEUR_PROPRIETE"
* @return the {link org.roliste.data.db.AccountProperty} this attribute is attached to.
* Shall not be <code>null</code>.
* see #setProperty(org.roliste.data.db.AccountProperty)
*/
public AccountProperty getProperty() {
return accountProperty;
}
/**
* Set the property this attribute is attached to.
* @param prop the new {link org.roliste.data.db.AccountProperty} this attribute will be attached to. Shall not be <code>null</code>.
* @see #getProperty()
*/
public void setProperty(AccountProperty prop) {
accountProperty = prop;
}
/**
* The property value.
*/
private String value;
/**
* Returns the property value.
* @return the {@link String} value. If property is known to be some other kind of value, you shall
* convert it yourself. May be <code>null</code>, in cases where the sole existence of the attribute
* is the value, or for unset attributes.
* @see #setValue(String)
* hibernate.property
* column="ATTR_VALUE"
* access="property"
* length="200"
*/
public String getValue() {
return value;
}
/**
* Initializes attribute value.
* @param value the new {@link String} value.
* @see #getValue()
*/
public void setValue(String value) {
this.value = value;
}
/**
* Returns a string representation of this account attribute definition.
* @return a string representing this account attribute definition.
* hidden
*/
@Override
public String toString()
{
return "ID_ATTR=" + getUserAttributeId() + " ATTR_PROP=" + accountProperty + " ATTR_VALUE=" + value;
}
}
package org.legrog.entities;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AccountAttributeRepository extends JpaRepository<AccountAttribute, Integer> {
}
package org.legrog.entities;
import javax.persistence.*;
/*
Entité persistente représentant la codification des propriétés qui peuvent être paramétrées pour un utilisateur.
Importée depuis la v2.
*/
@Entity
public class AccountProperty {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) /* Permet la population */
private int userPropertyId;
/**
*
* hibernate.id
* generator-class="identity"
* column="ID_PROP"
* access="property"
*/
public Integer getUserPropertyId() {
return userPropertyId;
}
/**
* The property name.
*/
private String name;
/**
* Returns the property name.
* @return the {@link String} attribute identifier.
* @see #setName(String)
* hibernate.property
* column="ATTR_NAME"
* not-null="true"
* unique="true"
* access="property"
* length="50"
*/
public String getName() {
return name;
}
/**
* Initializes the property name.
* @param name the new {@link String} identifier.
* @see #getName()
*/
public void setName(String name) {
this.name = name;
}
/**
* The property tag.
*/
private String tag;
/**
* Returns the property tag.
* @return the {@link String} value.
* @see #setTag(String)
* hibernate.property
* column="PROP_TAG"
* access="property"
* length="100"
*/
public String getTag() {
return tag;
}
/**
* Initializes property tag.
* @param tag the new {@link String} tag.
* @see #getTag()
*/
public void setTag(String tag) {
this.tag = tag;
}
/**
* The property validation status.
* A property may be temporarily deactivated.
*/
private boolean visible;
/**
* Indicates if the property is visible / usable.
* If not, users should not be able to access the privileges
* they inherit from having this property set.
* @return the visible flag.
* @see #setVisible(boolean)
* hibernate.property
* column="IND_VISIBLE"
* access="property"
*/
public boolean isVisible() {
return visible;
}
/**
* Initializes the property visible flag.
* @param visible the new flag value.
* @see #isVisible
*/
public void setVisible(boolean visible) {
this.visible = visible;
}
/**
* Returns a string representation of this property definition.
* @return a string representing this property definition.
* hidden
*/
@Override
public String toString()
{
return "ID_PROP=" + getUserPropertyId() + "PROP_NAME=" + name + " PROP_TAG=" + tag + " IND_VISIBLE=" + visible;
}
}
\ No newline at end of file
package org.legrog.entities;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AccountPropertyRepository extends JpaRepository<AccountProperty, Integer> {
}
package org.legrog.entities;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface AccountRepository extends JpaRepository<Account, Integer> {
/**
*
* @param integers list of Ids for the Accounts we're looking for
* @return Accounts looked for
*/
List<Account> findByUserIdIn(List<Integer> integers);
/**
*
* @return accounts that have a presentation
*/
List<Account> findByPresentationIsNotNull();
}
package org.legrog.entities;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.*;
/**
* The database representation of a account role or group.
* A given {@link Account} may be part of one or more {@link AccountRole}.
* <br/>
* Warning: due to laziness of mapped objects, private attributes of all DB entities shall never be used directly.
* You shall always use the getter/setter methods.
* alias AccountRole
*
*/
/*
Importé depuis la v2.
*/
@Entity
// TODO évaluer extend v2
public class AccountRole /* extends org.roliste.data.DbEntity */
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int userRoleId;
/**
* The role identifier.
*/
private String rolename;
/**
* The {@link Account}s for this account role.
*/
@ManyToMany(mappedBy = "roles")
private Set<Account> accounts;
/**
* Builds a new and empty account role definition.
* All attributes are set to their default value.
* <br/>
* Needed by Hibernate for Java reflection.
*/
public AccountRole() {
super();
rolename = null;
visible = true;
// no need to synchronize this
accounts = new HashSet<Account>();
}
public int getUserRoleId() {
return userRoleId;
}
public void setUserRoleId(int userRoleId) {
this.userRoleId = userRoleId;
}
/**
* Returns the role identifier.
* @return the {@link String} identifier.
* @see #setRolename(String)
* hibernate.property
* column="NOM_ROLE"
* not-null="true"
* unique="true"
* access="property"
* length="50"
*/
public String getRolename() {
return rolename;
}
/**
* Initializes the role identifier.
* @param name the new {@link String} identifier.
* @see #getRolename()
*/
public void setRolename(String name) {
rolename = name;
}
/**
* The role validation status.
* A role may be temporarily deactivated.
*/
private boolean visible;
/**
* Indicates if the role is visible.
* If not, accounts should not be able to access the privileges
* they inherit from being part of this role.
* @return the visible flag.
* @see #setVisible(boolean)
* hibernate.property
* column="IND_VISIBLE"
* access="property"
*/
public boolean isVisible() {
return visible;
}
/**
* Initializes the account visible flag.
* @param visible the new flag value.
* @see #isVisible
*/
public void setVisible(boolean visible) {
this.visible = visible;
}
/**
* Retrieves the list of {@link Account}s for this account role.
* SHALL be used as a read-only attribute. In particular, avoid
* using {@link Set#add(Object)} or {@link Set#remove(Object)} on
* the returned value without caution.
* @return a {@link Set} of {@link Account}. May be <code>null</code>.
* @see #setAccounts(Set)
* hibernate.many-to-many
* column="UTILISATEUR_FK"
* class="org.roliste.data.db.Person"
* foreign-key="FK_UTILISATEURROLE_UTILISATEUR"
* hibernate.key
* column="ROLE_FK"
* not-null="true"
* foreign-key="FK_UTILISATEURROLE_ROLEUTILISATEUR"
* hibernate.set
* access="property"
* table="role_utilisateur"
* lazy="true"
* inverse="true"
*/
public Set<Account> getAccounts() {
return accounts;
}
/**
* Sets the list of {@link Account}s for this account role.
* @param accounts the new {@link Set} of {@link Account}s. May be
* <code>null</code> (we don't handle the relation from this side).
* @see #getAccounts()
*/
protected void setAccounts(Set<Account> accounts) {
this.accounts = accounts;
}
/**
* Returns a string representation of this account role definition.
* @return a string representing this account role definition.
* hidden
*/
@Override
public String toString() {
return "ID_ROLE=" + getUserRoleId() + " NOM_ROLE=" + rolename + " IND_VISIBLE=" + visible;
}
}
\ No newline at end of file
package org.legrog.entities;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AccountRoleRepository extends JpaRepository<AccountRole, Integer> {
}
\ No newline at end of file
package org.legrog.entities;
import java.util.List;
/**
* Search interface for IndexedAccount
*/
public interface AccountSearchRepository {
/**
*
* @param string String searched in indexed Accounts
* @return Accounts that match the string
*/
List<IndexedAccount> search(String string) throws SearchingException;
/**
*
* @param indexedAccounts IndexedAccounts to reindex
*/
public void reindex(List<IndexedAccount> indexedAccounts) throws IndexingException;
}
package org.legrog.entities;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Implementation of AccountSearchRepository using SolrJ
*/
public class AccountSearchRepositorySolrj implements AccountSearchRepository {
Logger logger = LoggerFactory.getLogger(getClass());
SolrClient solrClient;
protected static String collectionName = "accounts";
@Inject
AccountSearchRepositorySolrj(SolrClient solrClient) {
this.solrClient = solrClient;
}
//no args constructor to make it proxyable
AccountSearchRepositorySolrj() {
}
@Override
public List<IndexedAccount> search(String string) throws SearchingException {
SolrQuery solrQuery = new SolrQuery(string);
QueryResponse queryResponse;
try {
queryResponse = solrClient.query(collectionName, solrQuery);
} catch (IOException ioe) {
throw new SearchingException(ioe);
} catch (SolrServerException sse) {
logger.error("SolrServerException {}", sse);
throw new SearchingException(sse.getRootCause());
}
if (queryResponse != null) {
return queryResponse.getBeans(IndexedAccount.class);
} else {
return new ArrayList<>();
}
}
@Override
public void reindex(List<IndexedAccount> indexedAccounts) throws IndexingException {
try {
UpdateResponse updateResponse = solrClient.addBeans(collectionName, indexedAccounts);
solrClient.commit(collectionName);
logger.trace("reindex indexedAccounts SolrJ UpdateResponse {}", updateResponse);
} catch (IOException ioe) {
throw new IndexingException(ioe);
} catch (SolrServerException sse) {
logger.error("SolrServerException {}", sse);
throw new IndexingException(sse.getRootCause());
}
}
}
package org.legrog.entities;
/**
* Available actions are an enumeration
*/
public enum ActionType {
VALIDATE;
}
\ No newline at end of file
package org.legrog.entities;
import javax.persistence.*;
/**
* Country persistence entity
* Id and name seem enough
*/
@Entity
public class Country {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer countryId;
private String countryName;
public Integer getCountryId() {
return countryId;
}
public void setCountryId(Integer countryId) {
this.countryId = countryId;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
@Override
public String toString()
{
return "ID_PAYS=" + countryId + " LIB_PAYS=" + countryName;
}
}
\ No newline at end of file
package org.legrog.entities;
import org.springframework.data.jpa.repository.JpaRepository;
public interface CountryRepository extends JpaRepository<Country, Integer> {
}
package org.legrog.entities;
/* DbMaskableEntity en v2, mais je pense le nouveau nom plus clair */
public interface DisplayNameConfigurable {
String getFirstName();
String getLastName();
String getNickName();
/* ScreenName en v2, mais je pense la nouveau nom plus clair */
String getDisplayName();
}
package org.legrog.entities;
/**
* This enumeration provide options for name masking of authors and users.
* Every {link org.roliste.data.DbMaskableEntity} provide first name, last name and nickname
* capabilities, that may be "masked", thus shown in some specific way depending on chosen
* NameMask.
*/
/*
v3 {@link org.legrog.entities.DisplayNameConfigurable}
*/
public enum DisplayNameMask
{
PRENOMNOM("Prénom Nom")
{
public String listMask(DisplayNameConfigurable person)
{
return NOMPRENOM.getDisplayName(person);
}
public String getDisplayName(DisplayNameConfigurable person)
{
StringBuilder sb = new StringBuilder();
if (person.getFirstName() != null)
{
sb.append(person.getFirstName());
}
if (person.getLastName() != null)
{
sb.append(' ');
sb.append(person.getLastName());
}
return sb.toString();
}
},
NOMPRENOM("Nom, Prénom")
{
public String listMask(DisplayNameConfigurable person)
{
return NOMPRENOM.getDisplayName(person);
}
public String getDisplayName(DisplayNameConfigurable person)
{
StringBuilder sb = new StringBuilder();
if (person.getLastName() != null)
{
sb.append(person.getLastName());
if (person.getFirstName() != null)
{
sb.append(", ");
sb.append(person.getFirstName());
}
}
else
{
sb.append("!Pas de nom");
}
return sb.toString();
}
},
PSEUDO("Pseudo")
{
public String listMask(DisplayNameConfigurable person)
{
return PSEUDO.getDisplayName(person);
}
public String getDisplayName(DisplayNameConfigurable person)
{
StringBuilder sb = new StringBuilder();
if (person.getNickName() != null)
{
sb.append(person.getNickName());
}
else
{
sb.append("!Pas de pseudo");
}
return sb.toString();
}
},
COMPLET("Prénom 'Pseudo' Nom")
{
public String listMask(DisplayNameConfigurable person)
{
return NOMPRENOM.getDisplayName(person);
}
public String getDisplayName(DisplayNameConfigurable person)
{
StringBuilder myResult = new StringBuilder();
if (person.getFirstName() != null)
{
myResult.append(person.getFirstName());
myResult.append(' ');
}
if ( person.getNickName() != null )
{
myResult.append('\'');
myResult.append(person.getNickName());
myResult.append('\'');
myResult.append(' ');
}
if (person.getLastName() != null)
{
myResult.append(person.getLastName());
}
return myResult.toString();
}
};
private final String symbol;
DisplayNameMask(String symbol) {
this.symbol = symbol;
}
public String getSymbol()
{
return symbol;
}
public String toString()
{
return symbol;
}
public abstract String getDisplayName(DisplayNameConfigurable person);
public abstract String listMask(DisplayNameConfigurable person);
}
\ No newline at end of file
package org.legrog.entities;
import org.apache.solr.client.solrj.beans.Field;
import javax.persistence.Id;
import javax.persistence.Lob;
/**
* Simplified class for searching indexed Accounts
*/
public class IndexedAccount {
@Id
@Field
private Integer userId;
@Lob
@Field
private String presentation;
/**
*
* @param account Account to be simplified as IndexedAccount
*/
public IndexedAccount(Account account) {
this.userId = account.getUserId();
this.presentation = account.getPresentation();
}
public IndexedAccount() {
//no args constructor to make it proxyable
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getPresentation() {
return presentation;
}
public void setPresentation(String presentation) {
this.presentation = presentation;
}
}
package org.legrog.entities;
import org.apache.solr.client.solrj.beans.Field;
import javax.persistence.Id;
import javax.persistence.Lob;
/**
* Simplified class for indexing and searching validated publishers: content from PublisherVersion with id from Publisher
*/
public class IndexedPublisher {
@Id
@Field
private Integer publisherId;
@Field
private String publisherName;
@Lob
@Field
private String publisherHistory;
/**
* Extracts data needed for indexing from Publisher and its validated PublisherVersion
*
* @param publisher Publisher we want to be indexed
*/
public IndexedPublisher(Publisher publisher) {
PublisherVersion publisherVersion = publisher.getValidatedVersion();
this.publisherId = publisher.getPublisherId();
this.publisherName = publisherVersion.getPublisherName();
this.publisherHistory = publisherVersion.getPublisherHistory();
}
public IndexedPublisher() {
//no args constructor to make it proxyable
}
public Integer getPublisherId() {
return publisherId;
}
public String getPublisherName() {
return publisherName;
}
public String getPublisherHistory() {
return publisherHistory;
}
public void setPublisherId(Integer publisherId) {
this.publisherId = publisherId;
}
public void setPublisherName(String publisherName) {
this.publisherName = publisherName;
}
public void setPublisherHistory(String publisherHistory) {
this.publisherHistory = publisherHistory;
}
}
\ No newline at end of file
package org.legrog.entities;
import javax.ejb.ApplicationException;
/**
* Exception when indexing fails, whatever the reason. Has to be dealt with at service level.
*/
@ApplicationException(rollback = true)
public class IndexingException extends Exception {
final Throwable rootCause;
IndexingException(Throwable rootCause) {
this.rootCause = rootCause;
}
public Throwable getRootCause() {
return rootCause;
}
}
package org.legrog.entities;
import javax.persistence.*;
import java.util.Set;
/**
* Persisted entity for a publisher
* Has versions of type PublisherVersion
* May have a validated PublisherVersion among those
* Has access to PublisherAction related to it
*/
@Entity
public class Publisher /* extends org.roliste.data.DbLinkableEntity */ {
// TODO L'éventuel usage de Linkable reste à confirmer https://tree.taiga.io/project/jr-utily-grog-v3/us/48
// TODO Attention, en v2 Linkable implique Traceable (journalisable) qui devrait aussi être évalué
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer publisherId;
@OneToOne
private PublisherVersion validatedVersion;
@OneToMany(mappedBy = "publisher", fetch = FetchType.EAGER)
private Set<PublisherVersion> versions;
@OneToMany(mappedBy = "publisher", fetch = FetchType.EAGER)
private Set<PublisherAction> actions;
public Integer getPublisherId() {
return publisherId;
}
public void setPublisherId(Integer publisherId) {
this.publisherId = publisherId;
}
public PublisherVersion getValidatedVersion() {
return validatedVersion;
}
public void setValidatedVersion(PublisherVersion activeVersion) {
this.validatedVersion = activeVersion;
}
public Set<PublisherVersion> getVersions() {
return versions;
}
public void setVersions(Set<PublisherVersion> versions) {
this.versions = versions;
}
public Set<PublisherAction> getActions() {
return actions;
}
public void setActions(Set<PublisherAction> actions) {
this.actions = actions;
}
@Override
public String toString() {
return "PUBLISHER_ID = " + publisherId + ", Validated Version = " + validatedVersion;
}
}
package org.legrog.entities;
import javax.persistence.*;
import java.sql.Timestamp;
/**
* Pesisted entity for actions made on PublisherVersion
*/
@Entity
public class PublisherAction {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer publisherActionId;
@Enumerated
private ActionType actionType;
@ManyToOne
private Account publisherActionActor;
@ManyToOne
private PublisherVersion publisherVersion;
private Timestamp publisherActionDatetime;
// Simplified access instead of going through PublisherVersion
@ManyToOne
private Publisher publisher;
public void setPublisherActionActor(Account publisherActionActor) {
this.publisherActionActor = publisherActionActor;
}
public void setPublisherActionDatetime(Timestamp publisherActionDatetime) {
this.publisherActionDatetime = publisherActionDatetime;
}
public void setActionType(ActionType actionType) {
this.actionType = actionType;
}
public void setPublisherVersion(PublisherVersion publisherVersion) {
this.publisherVersion = publisherVersion;
}
public void setPublisher(Publisher publisher) {
this.publisher = publisher;
}
public ActionType getActionType() {
return actionType;
}
public Account getPublisherActionActor() {
return publisherActionActor;
}
public PublisherVersion getPublisherVersion() {
return publisherVersion;
}
public Timestamp getPublisherActionDatetime() {
return publisherActionDatetime;
}
public Publisher getPublisher() {
return publisher;
}
public Integer getPublisherActionId() {
return publisherActionId;
}
public void setPublisherActionId(Integer publisherActionId) {
this.publisherActionId = publisherActionId;
}
@Override
public String toString() {
return "publisherActionId = " + publisherActionId + ", actionType = " + actionType +
", publisherActionAuthor = " + publisherActionActor + ", publisherVersion = " + publisherVersion +
", publisherActionDatetime = " + publisherActionDatetime + ", publisher = " + publisher;
}
}
\ No newline at end of file
package org.legrog.entities;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
/**
* Interface for accessing PublisherAction
*/
public interface PublisherActionRepository extends JpaRepository<PublisherAction, Integer> {
/**
* Returns last action of a type for a publisher
*
* @param actionType ActionType requested
* @param publisher Publisher concerned by the action
* @return PublisherAction
*/
PublisherAction findFirstByActionTypeAndPublisherOrderByPublisherActionDatetimeDesc(ActionType actionType, Publisher publisher);
/**
* Returns all actions for a PublisherVersion
*
* @param publisherVersion PublisherVersion concerned by the actions
* @return List<PublisherAction>
*/
List<PublisherAction> findByPublisherVersion(PublisherVersion publisherVersion);
}
package org.legrog.entities;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface PublisherRepository extends JpaRepository<Publisher, Integer> {
List<Publisher> findByValidatedVersionIsNotNull();
}
package org.legrog.entities;
import java.util.List;
/**
* Indexing/Search interface for IndexedPublisher
*/
public interface PublisherSearchRepository {
/**
* Indexes an IndexedPublisher
*
* @param indexedPublisher IndexedPublisher to be indexed
* @return IndexedPublisher
*/
IndexedPublisher save(IndexedPublisher indexedPublisher) throws IndexingException;
/**
* Searches for IndexedPublishers
*
* @param string String looked for in IndexedPublishers
* @return list of matching IndexedPublishers
*/
List<IndexedPublisher> search(String string) throws SearchingException;
/**
*
* @param inxdexedPublishers IndexedPublishers to reindex
*/
public void reindex(List<IndexedPublisher> inxdexedPublishers) throws IndexingException;
}
package org.legrog.entities;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Implementation of PublisherSearchRepository using SolrJ
*/
public class PublisherSearchRepositorySolrj implements PublisherSearchRepository {
Logger logger = LoggerFactory.getLogger(getClass());
SolrClient solrClient;
protected static String collectionName = "publishers";
@Inject
PublisherSearchRepositorySolrj(SolrClient solrClient) {
this.solrClient = solrClient;
}
//no args constructor to make it proxyable
PublisherSearchRepositorySolrj() {
}
@Override
public IndexedPublisher save(IndexedPublisher indexedPublisher) throws IndexingException {
try {
UpdateResponse updateResponse = solrClient.addBean(collectionName, indexedPublisher, 1);
logger.trace("validatePublisherVersion SolrJ UpdateResponse {}", updateResponse);
} catch (IOException ioe) {
throw new IndexingException(ioe);
} catch (SolrServerException sse) {
logger.error("SolrServerException {}", sse);
throw new IndexingException(sse.getRootCause());
}
return indexedPublisher;
}
@Override
public List<IndexedPublisher> search(String string) throws SearchingException {
SolrQuery solrQuery = new SolrQuery(string);
QueryResponse queryResponse;
try {
queryResponse = solrClient.query(collectionName, solrQuery);
} catch (IOException ioe) {
throw new SearchingException(ioe);
} catch (SolrServerException sse) {
logger.error("SolrServerException {}", sse);
throw new SearchingException(sse.getRootCause());
}
if (queryResponse != null) {
return queryResponse.getBeans(IndexedPublisher.class);
} else {
return new ArrayList<>();
}
}
@Override
public void reindex(List<IndexedPublisher> indexedPublishers) throws IndexingException {
try {
UpdateResponse updateResponse = solrClient.addBeans(collectionName, indexedPublishers);
solrClient.commit(collectionName);
logger.trace("reindex inxdexedPublishers SolrJ UpdateResponse {}", updateResponse);
} catch (IOException ioe) {
throw new IndexingException(ioe);
} catch (SolrServerException sse) {
logger.error("SolrServerException {}", sse);
throw new IndexingException(sse.getRootCause());
}
}
}
package org.legrog.entities;
import javax.persistence.*;
import java.sql.Timestamp;
/**
* Persisted entity for a publisher version
* Contains the data
* Postal Address is split according to http://schema.org/PostalAddress
*/
@Entity
public class PublisherVersion {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer publisherVersionId;
@ManyToOne
private Publisher publisher;
private String publisherName;
private String publisherStreetAddress;
private String publisherPostalCode;
private String publisherPostOfficeBoxNumber;
private String publisherAddressRegion;
private String publisherAddressLocality;
@ManyToOne
private Country publisherAddressCountry;
private String publisherTelephone;
private String publisherEmail;
private String publisherURL;
@Lob
private String publisherHistory;
@ManyToOne
private Account publisherVersionCreator;
private Timestamp publisherVersionDatetime;
public Timestamp getPublisherVersionDatetime() {
return publisherVersionDatetime;
}
public void setPublisherVersionDatetime(Timestamp publisherVersionDatetime) {
this.publisherVersionDatetime = publisherVersionDatetime;
}
public String getPublisherHistory() {
return publisherHistory;
}
public void setPublisherHistory(String publisherHistory) {
this.publisherHistory = publisherHistory;
}
public String getPublisherStreetAddress() {
return publisherStreetAddress;
}
public void setPublisherStreetAddress(String publisherStreetAddress) {
this.publisherStreetAddress = publisherStreetAddress;
}
public String getPublisherPostalCode() {
return publisherPostalCode;
}
public void setPublisherPostalCode(String publisherPostalCode) {
this.publisherPostalCode = publisherPostalCode;
}
public String getPublisherPostOfficeBoxNumber() {
return publisherPostOfficeBoxNumber;
}
public void setPublisherPostOfficeBoxNumber(String publisherPostOfficeBoxNumber) {
this.publisherPostOfficeBoxNumber = publisherPostOfficeBoxNumber;
}
public String getPublisherAddressRegion() {
return publisherAddressRegion;
}
public void setPublisherAddressRegion(String publisherAddressRegion) {
this.publisherAddressRegion = publisherAddressRegion;
}
public String getPublisherAddressLocality() {
return publisherAddressLocality;
}
public void setPublisherAddressLocality(String publisherAddressLocality) {
this.publisherAddressLocality = publisherAddressLocality;
}
public String getPublisherTelephone() {
return publisherTelephone;
}
public void setPublisherTelephone(String publisherTelephone) {
this.publisherTelephone = publisherTelephone;
}
public String getPublisherEmail() {
return publisherEmail;
}
public void setPublisherEmail(String publisherEmail) {
this.publisherEmail = publisherEmail;
}
public String getPublisherURL() {
return publisherURL;
}
public void setPublisherURL(String publisherURL) {
this.publisherURL = publisherURL;
}
public Integer getPublisherVersionId() {
return publisherVersionId;
}
public void setPublisherVersionId(Integer publisherVersionId) {
this.publisherVersionId = publisherVersionId;
}
public String getPublisherName() {
return publisherName;
}
public void setPublisherName(String publisherName) {
this.publisherName = publisherName;
}
public Country getPublisherAddressCountry() {
return publisherAddressCountry;
}
public void setPublisherAddressCountry(Country publisherAddressCountry) {
this.publisherAddressCountry = publisherAddressCountry;
}
public Account getPublisherVersionCreator() {
return publisherVersionCreator;
}
public void setPublisherVersionCreator(Account publisherVersionCreator) {
this.publisherVersionCreator = publisherVersionCreator;
}
@Override
public String toString() {
return "PUBLISHER_VERSION_ID = " + publisherVersionId + ", Name = " + publisherName + ", St Address = " +
publisherStreetAddress + ", CP = " + publisherPostalCode + ", BP = " + publisherPostOfficeBoxNumber +
", Region = " + publisherAddressRegion + ", Ville = " + publisherAddressLocality + ", Pays = " +
publisherAddressCountry + ", Telephone = " + publisherTelephone + ", email = " + publisherEmail +
", URL = " + publisherURL + ", History = " + publisherHistory +
", Version Author = " + publisherVersionCreator + ", Version DateTime = " + publisherVersionDatetime;
}
public Publisher getPublisher() {
return publisher;
}
public void setPublisher(Publisher publisher) {
this.publisher = publisher;
}
}
\ No newline at end of file
package org.legrog.entities;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface PublisherVersionRepository extends JpaRepository<PublisherVersion, Integer> {
/**
*
* @param integers list of Ids for the PublisherVersions we're looking for
* @return PublisherVersions looked for
*/
List<PublisherVersion> findByPublisherVersionIdIn(List<Integer> integers);
}
package org.legrog.entities;
/**
* Exception when searching fails, whatever the reason. Has to be dealt with at service level.
*/
public class SearchingException extends Exception {
final Throwable rootCause;
SearchingException(Throwable rootCause) {
this.rootCause = rootCause;
}
public Throwable getRootCause() {
return rootCause;
}
}
\ No newline at end of file
package org.legrog.util;
// Code copied from org.h2.server.web.WebSession
/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
///package org.h2.server.web;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import org.h2.bnf.Bnf;
import org.h2.bnf.context.DbContents;
import org.h2.bnf.context.DbContextRule;
import org.h2.message.DbException;
import org.h2.util.New;
import org.h2.server.web.*;
/**
* The web session keeps all data of a user session.
* This class is used by the H2 Console.
*/
class WebSession {
private static final int MAX_HISTORY = 1000;
/**
* The last time this client sent a request.
*/
long lastAccess;
/**
* The session attribute map.
*/
final HashMap<String, Object> map = New.hashMap();
/**
* The current locale.
*/
Locale locale;
/**
* The currently executing statement.
*/
Statement executingStatement;
/**
* The current updatable result set.
*/
ResultSet result;
private final WebServer server;
private final ArrayList<String> commandHistory;
private Connection conn;
private DatabaseMetaData meta;
private DbContents contents = new DbContents();
private Bnf bnf;
private boolean shutdownServerOnDisconnect;
WebSession(WebServer server) {
this.server = server;
// This must be stored in the session rather than in the server.
// Otherwise, one client could allow
// saving history for others (insecure).
this.commandHistory = server.getCommandHistoryList();
}
/**
* Put an attribute value in the map.
*
* @param key the key
* @param value the new value
*/
void put(String key, Object value) {
map.put(key, value);
}
/**
* Get the value for the given key.
*
* @param key the key
* @return the value
*/
Object get(String key) {
if ("sessions".equals(key)) {
return server.getSessions();
}
return map.get(key);
}
/**
* Remove a session attribute from the map.
*
* @param key the key
*/
void remove(String key) {
map.remove(key);
}
/**
* Get the BNF object.
*
* @return the BNF object
*/
Bnf getBnf() {
return bnf;
}
/**
* Load the SQL grammar BNF.
*/
void loadBnf() {
try {
Bnf newBnf = Bnf.getInstance(null);
DbContextRule columnRule =
new DbContextRule(contents, DbContextRule.COLUMN);
DbContextRule newAliasRule =
new DbContextRule(contents, DbContextRule.NEW_TABLE_ALIAS);
DbContextRule aliasRule =
new DbContextRule(contents, DbContextRule.TABLE_ALIAS);
DbContextRule tableRule =
new DbContextRule(contents, DbContextRule.TABLE);
DbContextRule schemaRule =
new DbContextRule(contents, DbContextRule.SCHEMA);
DbContextRule columnAliasRule =
new DbContextRule(contents, DbContextRule.COLUMN_ALIAS);
DbContextRule procedure =
new DbContextRule(contents, DbContextRule.PROCEDURE);
newBnf.updateTopic("procedure", procedure);
newBnf.updateTopic("column_name", columnRule);
newBnf.updateTopic("new_table_alias", newAliasRule);
newBnf.updateTopic("table_alias", aliasRule);
newBnf.updateTopic("column_alias", columnAliasRule);
newBnf.updateTopic("table_name", tableRule);
newBnf.updateTopic("schema_name", schemaRule);
newBnf.linkStatements();
bnf = newBnf;
} catch (Exception e) {
// ok we don't have the bnf
server.traceError(e);
}
}
/**
* Get the SQL statement from history.
*
* @param id the history id
* @return the SQL statement
*/
String getCommand(int id) {
return commandHistory.get(id);
}
/**
* Add a SQL statement to the history.
*
* @param sql the SQL statement
*/
void addCommand(String sql) {
if (sql == null) {
return;
}
sql = sql.trim();
if (sql.length() == 0) {
return;
}
if (commandHistory.size() > MAX_HISTORY) {
commandHistory.remove(0);
}
int idx = commandHistory.indexOf(sql);
if (idx >= 0) {
commandHistory.remove(idx);
}
commandHistory.add(sql);
if (server.isCommandHistoryAllowed()) {
server.saveCommandHistoryList(commandHistory);
}
}
/**
* Get the list of SQL statements in the history.
*
* @return the commands
*/
ArrayList<String> getCommandHistory() {
return commandHistory;
}
/**
* Update session meta data information and get the information in a map.
*
* @return a map containing the session meta data
*/
HashMap<String, Object> getInfo() {
HashMap<String, Object> m = New.hashMap();
m.putAll(map);
m.put("lastAccess", new Timestamp(lastAccess).toString());
try {
m.put("url", conn == null ?
"${text.admin.notConnected}" : conn.getMetaData().getURL());
m.put("user", conn == null ?
"-" : conn.getMetaData().getUserName());
m.put("lastQuery", commandHistory.size() == 0 ?
"" : commandHistory.get(0));
m.put("executing", executingStatement == null ?
"${text.admin.no}" : "${text.admin.yes}");
} catch (SQLException e) {
DbException.traceThrowable(e);
}
return m;
}
void setConnection(Connection conn) throws SQLException {
this.conn = conn;
if (conn == null) {
meta = null;
} else {
meta = conn.getMetaData();
}
contents = new DbContents();
}
DatabaseMetaData getMetaData() {
return meta;
}
Connection getConnection() {
return conn;
}
DbContents getContents() {
return contents;
}
/**
* Shutdown the server when disconnecting.
*/
void setShutdownServerOnDisconnect() {
this.shutdownServerOnDisconnect = true;
}
boolean getShutdownServerOnDisconnect() {
return shutdownServerOnDisconnect;
}
/**
* Close the connection and stop the statement if one is currently
* executing.
*/
void close() {
if (executingStatement != null) {
try {
executingStatement.cancel();
} catch (Exception e) {
// ignore
}
}
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
// ignore
}
}
}
}
\ No newline at end of file
package org.legrog.entities;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.beans.BindingException;
import org.apache.solr.common.params.SolrParams;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import org.legrog.test.MockitoExtension;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* Classe testant AccountSearchRepositorySolrj
*/
@RunWith(JUnitPlatform.class)
@ExtendWith(MockitoExtension.class)
@DisplayName("Indexes and searches with SearchRepository")
public class AccountSearchRepositorySolrjTest {
Logger logger = LoggerFactory.getLogger(getClass());
private AccountSearchRepository accountSearchRepository;
private SolrClient solrClient;
@Captor
ArgumentCaptor<SolrParams> solrParamsArgumentCaptor;
@BeforeEach
public void setup(@Mock SolrClient solrClient) {
accountSearchRepository = new AccountSearchRepositorySolrj(solrClient);
this.solrClient = solrClient;
}
@Nested
@DisplayName("search method")
class SearchTests {
@DisplayName("when repository in IO error, should throw a SearchingException")
@Test
public void searchIOETest() throws IOException, SolrServerException{
when(solrClient.query(Mockito.anyString(), Mockito.any())).thenThrow(new IOException());
Assertions.assertThrows(SearchingException.class, () -> accountSearchRepository.search("a"));
}
@DisplayName("when repository in SolrServerException, should throw an SearchingException with its root cause")
@Test
public void searchSSETest() throws SolrServerException, IOException {
when(solrClient.query(Mockito.any())).thenThrow(new SolrServerException(new BindingException("BE test 2")));
try {
accountSearchRepository.search("b");
} catch (SearchingException se) {
logger.error("SearchingException {}", se);
assertThat(se.getRootCause().getClass()).isEqualTo(BindingException.class);
}
}
@DisplayName("when called, it parameter should be embedded in a query sent through SolrClient")
@Test
public void searchParameterTest() throws IOException, SolrServerException {
try {
accountSearchRepository.search("c");
Mockito.verify(solrClient).query(Mockito.anyString(), solrParamsArgumentCaptor.capture());
} catch (SearchingException se) {
logger.error("SearchingException {}", se);
}
SolrQuery solrQuery = (SolrQuery) solrParamsArgumentCaptor.getValue();
assertThat(solrQuery.getQuery()).isEqualTo("c");
}
}
}
package org.legrog.entities;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.beans.BindingException;
import org.apache.solr.common.params.SolrParams;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import org.legrog.test.MockitoExtension;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Classe testant PublisherSearchRepositorySolrj
*/
@RunWith(JUnitPlatform.class)
@ExtendWith(MockitoExtension.class)
@DisplayName("Indexes and searches with SearchRepository")
public class PublisherSearchRepositorySolrjTest {
Logger logger = LoggerFactory.getLogger(getClass());
private PublisherSearchRepository publisherSearchRepository;
private SolrClient solrClient;
@Captor
ArgumentCaptor<SolrParams> solrParamsArgumentCaptor;
@BeforeEach
public void setup(@Mock SolrClient solrClient) {
publisherSearchRepository = new PublisherSearchRepositorySolrj(solrClient);
this.solrClient = solrClient;
}
@Nested
@DisplayName("save method")
class SaveTests {
@Test
@DisplayName("when called with right parameters, should addBean IndexedPublisher with commitWithinMs of 1 to repository")
public void addBeanTest(@Mock IndexedPublisher indexedPublisher) throws IndexingException, SolrServerException, IOException {
publisherSearchRepository.save(indexedPublisher);
verify(solrClient).addBean(PublisherSearchRepositorySolrj.collectionName, indexedPublisher, 1);
}
@Test
@DisplayName("When repository in IO error, should throw an IndexingException")
public void addBeanIOETest(@Mock IndexedPublisher indexedPublisher) throws SolrServerException, IOException {
when(solrClient.addBean(PublisherSearchRepositorySolrj.collectionName, indexedPublisher, 1)).thenThrow(new IOException());
Assertions.assertThrows(IndexingException.class, () -> publisherSearchRepository.save(indexedPublisher));
}
@Test
@DisplayName("When repository in SolrServerException, should throw an IndexingException with its root cause")
public void addBeanSSETest(@Mock IndexedPublisher indexedPublisher) throws SolrServerException, IOException{
when(solrClient.addBean(indexedPublisher, 1)).thenThrow(new SolrServerException(new BindingException("BE test")));
try {
publisherSearchRepository.save(indexedPublisher);
} catch (IndexingException ie) {
logger.error("IndexingException {}", ie);
assertThat(ie.getRootCause().getClass()).isEqualTo(BindingException.class);
}
}
}
@Nested
@DisplayName("search method")
class SearchTests {
@DisplayName("when repository in IO error, should throw a SearchingException")
@Test
public void searchIOETest() throws IOException, SolrServerException{
when(solrClient.query(Mockito.anyString(), Mockito.any())).thenThrow(new IOException());
Assertions.assertThrows(SearchingException.class, () -> publisherSearchRepository.search("a"));
}
@DisplayName("when repository in SolrServerException, should throw an SearchingException with its root cause")
@Test
public void searchSSETest() throws SolrServerException, IOException {
when(solrClient.query(Mockito.any())).thenThrow(new SolrServerException(new BindingException("BE test 2")));
try {
publisherSearchRepository.search("b");
} catch (SearchingException se) {
logger.error("SearchingException {}", se);
assertThat(se.getRootCause().getClass()).isEqualTo(BindingException.class);
}
}
@DisplayName("when called, it parameter should be embedded in a query sent through SolrClient")
@Test
public void searchParameterTest() throws IOException, SolrServerException {
try {
publisherSearchRepository.search("c");
Mockito.verify(solrClient).query(Mockito.anyString(), solrParamsArgumentCaptor.capture());
} catch (SearchingException se) {
logger.error("SearchingException {}", se);
}
SolrQuery solrQuery = (SolrQuery) solrParamsArgumentCaptor.getValue();
assertThat(solrQuery.getQuery()).isEqualTo("c");
}
}
}
package org.legrog.test;
/*
TAKEN FROM JUnit 5 Sample
https://github.com/junit-team/junit5-samples/blob/master/junit5-mockito-extension/src/main/java/com/example/mockito/MockitoExtension.java
*/
/*
* Copyright 2015-2016 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
*/
import static org.mockito.Mockito.mock;
import java.lang.reflect.Parameter;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
import org.junit.jupiter.api.extension.ExtensionContext.Store;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* {@code MockitoExtension} showcases the {@link TestInstancePostProcessor}
* and {@link ParameterResolver} extension APIs of JUnit 5 by providing
* dependency injection support at the field level and at the method parameter
* level via Mockito 2.x's {@link Mock @Mock} annotation.
*/
public class MockitoExtension implements TestInstancePostProcessor, ParameterResolver {
@Override
public void postProcessTestInstance(Object testInstance, ExtensionContext context) {
MockitoAnnotations.initMocks(testInstance);
}
@Override
public boolean supports(ParameterContext parameterContext, ExtensionContext extensionContext) {
return parameterContext.getParameter().isAnnotationPresent(Mock.class);
}
@Override
public Object resolve(ParameterContext parameterContext, ExtensionContext extensionContext) {
return getMock(parameterContext.getParameter(), extensionContext);
}
private Object getMock(Parameter parameter, ExtensionContext extensionContext) {
Class<?> mockType = parameter.getType();
Store mocks = extensionContext.getStore(Namespace.create(MockitoExtension.class, mockType));
String mockName = getMockName(parameter);
if (mockName != null) {
return mocks.getOrComputeIfAbsent(mockName, key -> mock(mockType, mockName));
} else {
return mocks.getOrComputeIfAbsent(mockType.getCanonicalName(), key -> mock(mockType));
}
}
private String getMockName(Parameter parameter) {
String explicitMockName = parameter.getAnnotation(Mock.class).name().trim();
if (!explicitMockName.isEmpty()) {
return explicitMockName;
} else if (parameter.isNamePresent()) {
return parameter.getName();
}
return null;
}
}
package org.legrog.web.xyz;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import org.legrog.entities.Account;
import org.legrog.entities.PublisherVersion;
import org.legrog.entities.SearchingException;
import org.legrog.test.MockitoExtension;
import org.legrog.web.account.AccountService;
import org.legrog.web.publisher.PublisherSearchView;
import org.legrog.web.publisher.PublisherService;
import org.mockito.Mock;
import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
/**
* Classe testant SearchView
*/
@RunWith(JUnitPlatform.class)
@ExtendWith(MockitoExtension.class)
@DisplayName("Searches for an indexed publisher")
public class SearchViewTest {
private SearchView searchView;
private PublisherService publisherService;
private AccountService accountService;
@BeforeEach
public void setUp(@Mock PublisherService publisherService, @Mock AccountService accountService) {
this.publisherService = publisherService;
this.accountService = accountService;
this.searchView = new SearchView(publisherService, accountService);
}
@Nested
@DisplayName("search method")
class SearchTests {
@Test
@DisplayName("when called, should delegate search to PublisherService and AccountService with same string")
public void searchUsesPublisherService(@Mock PublisherService publisherService, @Mock AccountService accountService) throws SearchingException{
searchView.setSearchString("1");
searchView.search();
Mockito.verify(publisherService).search("1");
Mockito.verify(accountService).search("1");
}
@Test
@DisplayName("when called, should return the answer it gets from PublisherService")
public void searchReturnsDataFromPublisherService(@Mock PublisherService publisherService) throws SearchingException {
List<PublisherVersion> publisherVersionList = new ArrayList<>();
when(publisherService.search("2")).thenReturn(publisherVersionList);
searchView.setSearchString("2");
searchView.search();
assertThat(searchView.getPublisherVersions()).isEqualTo(publisherVersionList);
}
@Test
@DisplayName("when called, should return the answer it gets from AccountService")
public void searchReturnsDataFromAccountService(@Mock AccountService accountService) throws SearchingException {
List<Account> publisherVersionList = new ArrayList<>();
when(accountService.search("3")).thenReturn(publisherVersionList);
searchView.setSearchString("3");
searchView.search();
assertThat(searchView.getPublisherVersions()).isEqualTo(publisherVersionList);
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>Web-application of GROG</name>
<url>http://legrog.org</url>
<description>
Le Guide du Roliste Galactique (GROG) est une encyclopedie en ligne référençant tous les jeux de rôles connus.
Cette version CUBI est la 3e mouture du site.
</description>
<parent>
<groupId>org.legrog</groupId>
<artifactId>grog-cubi</artifactId>
<version>3.0-SNAPSHOT</version>
</parent>
<artifactId>grog-webapp</artifactId>
<packaging>war</packaging>
<properties>
<!-- dependencies version -->
<spring.platform-bom.version>Athens-SR1</spring.platform-bom.version>
<omnifaces.version>2.5.1</omnifaces.version>
<primefaces.version>6.0</primefaces.version>
<myfaces.version>2.2.10</myfaces.version>
<tomee.javaee-api.version>7.0</tomee.javaee-api.version>
<assertj-core.version>1.6.1</assertj-core.version>
<openjpa.version>2.4.1</openjpa.version>
<rewrite.version>3.4.1.Final</rewrite.version>
<hibernate-commons-annotations.version>5.0.1.Final</hibernate-commons-annotations.version>
<hibernate-jpa-2.1-api.version>1.0.0.Final</hibernate-jpa-2.1-api.version>
<junit.platform.version>1.0.0-M3</junit.platform.version>
<junit.jupiter.version>5.0.0-M3</junit.jupiter.version>
<mockito-core.version>2.2.16</mockito-core.version>
<spring-data-solr.version>3.0.0.M1</spring-data-solr.version>
<solr.version>6.3.0</solr.version>
<!-- paths -->
<custom.web.dir>src/main/java/org/legrog/web</custom.web.dir>
<!-- misc -->
<debug.jvm.args />
<tomee.autoreload />
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<profiles>
<profile>
<id>debug</id>
<!--
activate this one to be able to attach a remote debbuger on tomee
-->
<properties>
<debug.jvm.args>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005</debug.jvm.args>
</properties>
</profile>
<profile>
<id>autoreload</id>
<!--
activate this one for tomee to reload (takes times) every times it detect a synchro
reminder : you can always force a reload by typing reload in the console while tomee:run is active
-->
<properties>
<tomee.autoreload>true</tomee.autoreload>
</properties>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.legrog</groupId>
<artifactId>grog-entities</artifactId>
<version>3.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>${solr.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.omnifaces/omnifaces -->
<dependency>
<groupId>org.omnifaces</groupId>
<artifactId>omnifaces</artifactId>
<version>${omnifaces.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.primefaces/primefaces -->
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>${primefaces.version}</version>
</dependency>
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-api</artifactId>
<version>${myfaces.version}</version>
</dependency>
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-impl</artifactId>
<version>${myfaces.version}</version>
<scope>runtime</scope>
</dependency>
<!-- Rewriting tool -->
<dependency>
<groupId>org.ocpsoft.rewrite</groupId>
<artifactId>rewrite-servlet</artifactId>
<version>${rewrite.version}</version>
</dependency>
<dependency>
<groupId>org.ocpsoft.rewrite</groupId>
<artifactId>rewrite-integration-faces</artifactId>
<version>${rewrite.version}</version>
</dependency>
<dependency>
<groupId>org.ocpsoft.rewrite</groupId>
<artifactId>rewrite-integration-cdi</artifactId>
<version>${rewrite.version}</version>
</dependency>
<!-- **** TOOLS : LOGS + UTILS **** -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<!-- **** DATA MANAGEMENT **** -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!--
<version>5.1.6</version>
-->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>${custom.web.dir}</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
<!-- **** TOMEE **** -->
<!-- For now we just get a generic one from the repo and put it in target dir -->
<!-- For production release, we will need another pom doing a real provisionning and build it with grog-cubi already inside -->
<!--
see http://tomee.apache.org/ng/developer/tools/maven/tomee.html
and http://tomee.apache.org/maven/index.html
for conf references (I love when a new reference page doesn't get the same info as the former one)
-->
<plugin>
<groupId>org.apache.tomee.maven</groupId>
<artifactId>tomee-maven-plugin</artifactId>
<version>7.0.1</version>
<configuration>
<context>ROOT</context>
<!-- debug agent to attach a remote debbuger, activate profile for that -->
<args>${debug.jvm.args}</args>
<systemVariables>
<!--
taken from http://tomee-openejb.979440.n4.nabble.com/7-0-0-M3-synchronization-td4677806.html for synchro to work
-->
<openejb.system.apps>true</openejb.system.apps>
<tomee.serialization.class.blacklist>-</tomee.serialization.class.blacklist>
</systemVariables>
<synchronization>
<resourcesDir>${custom.web.dir}</resourcesDir>
<extensions>
<extension>.class</extension> <!-- update each time you build with mvn compile -->
<extension>.xhtml</extension> <!-- update each time you save an xhtml in custom web dir -->
</extensions>
</synchronization>
<reloadOnUpdate>${tomee.autoreload}</reloadOnUpdate>
</configuration>
</plugin>
</plugins>
</build>
</project>
......@@ -15,7 +15,7 @@ public class JpaConfiguration {
*/
@Produces
@RequestScoped
@PersistenceContext(unitName = "migration-pu")
@PersistenceContext(unitName = "development-pu")
public EntityManager entityManager;
}
......
......@@ -10,7 +10,7 @@
<link rel="stylesheet" type="text/css" href="/minimal.css"/>
</head>
<body>
<ui:include src="/navigation.xhtml" />
<ui:include src="/org/legrog/web/navigation.xhtml" />
<a jsf:outcome="listPublisherActions" jsf:rendered="#{not listPublisherActionsView.viewAll}">Voir toutes les actions</a>
......
......@@ -10,7 +10,7 @@
<link rel="stylesheet" type="text/css" href="/minimal.css"/>
</head>
<body>
<ui:include src="/navigation.xhtml" />
<ui:include src="/org/legrog/web/navigation.xhtml" />
<a jsf:outcome="listPublisherVersions" jsf:rendered="#{not listPublisherVersionsView.viewAll}">Voir toutes les versions d'éditeurs</a>
<p jsf:rendered="#{listPublisherVersionsView.publisherVersions.isEmpty()}">Liste des révisions est vide</p>
......
......@@ -10,7 +10,7 @@
<link rel="stylesheet" type="text/css" href="/minimal.css"/>
</head>
<body>
<ui:include src="/navigation.xhtml" />
<ui:include src="/org/legrog/web/navigation.xhtml" />
<form action="" jsf:id="search">
<h:panelGrid columns="2">
......
......@@ -9,7 +9,7 @@
<head>
</head>
<body>
<ui:include src="/navigation.xhtml" />
<ui:include src="/org/legrog/web/navigation.xhtml" />
<form jsf:id="publisherVersion" action="">
<h:panelGrid columns="2">
......
......@@ -6,7 +6,7 @@
xmlns:jsf="http://xmlns.jcp.org/jsf"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:include src="/navigation.xhtml" />
<ui:include src="/org/legrog/web/navigation.xhtml" />
<form action="" jsf:id="country">
<h:panelGrid columns="2">
......
......@@ -5,7 +5,7 @@
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:jsf="http://xmlns.jcp.org/jsf">
<body>
<ui:include src="/navigation.xhtml" />
<ui:include src="/org/legrog/web/navigation.xhtml" />
<ul>
<ui:repeat value="#{listCountriesView.countries}" var="country">
......
......@@ -7,7 +7,7 @@
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:jsf="http://xmlns.jcp.org/jsf">
<body>
<ui:include src="/navigation.xhtml" />
<ui:include src="/org/legrog/web/navigation.xhtml" />
<form action="" jsf:id="reindex">
<button jsf:action="#{reindexView.reindexAll}">Réindexer</button>
......
......@@ -10,7 +10,7 @@
<link rel="stylesheet" type="text/css" href="/minimal.css"/>
</head>
<body>
<ui:include src="/navigation.xhtml" />
<ui:include src="/org/legrog/web/navigation.xhtml" />
<form action="" jsf:id="search">
<h:panelGrid columns="2">
......
......@@ -2,15 +2,15 @@
<tomee>
<Resource id="H2Database" type="javax.sql.DataSource">
JdbcDriver = org.h2.Driver
JdbcUrl = jdbc:h2:mem:test
JdbcUrl = jdbc:h2:~/grog-dev.db
UserName = sa
JtaManaged= true
</Resource>
<Resource id="migrationDatabase" type="javax.sql.DataSource">
JdbcDriver = com.mysql.jdbc.Driver
JdbcUrl = jdbc:mysql://localhost/migration?useSSL=false
UserName = grogdev
password = grogdev
JtaManaged= true
</Resource>
<!--<Resource id="migrationDatabase" type="javax.sql.DataSource">-->
<!--JdbcDriver = com.mysql.jdbc.Driver-->
<!--JdbcUrl = jdbc:mysql://localhost/migration?useSSL=false-->
<!--UserName = grogdev-->
<!--password = grogdev-->
<!--JtaManaged= true-->
<!--</Resource>-->
</tomee>
\ No newline at end of file
......
......@@ -5,6 +5,6 @@
xmlns:jsf="http://xmlns.jcp.org/jsf"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<body>
<ui:include src="/navigation.xhtml" />
<ui:include src="/org/legrog/web/navigation.xhtml" />
</body>
</html>
\ No newline at end of file
......