-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #172 from InseeFr/develop
feat: questionnaire composition + restricted stamp properties
- Loading branch information
Showing
67 changed files
with
11,288 additions
and
367 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
src/main/java/fr/insee/pogues/exception/DeReferencingException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package fr.insee.pogues.exception; | ||
|
||
/** | ||
* Exception thrown if an error occurs during questionnaire de-referencing (composition feature). | ||
*/ | ||
public class DeReferencingException extends Exception { | ||
|
||
public DeReferencingException(String message, Exception e) { | ||
super(message, e); | ||
} | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/fr/insee/pogues/exception/IllegalFlowControlException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package fr.insee.pogues.exception; | ||
|
||
public class IllegalFlowControlException extends Exception { | ||
|
||
public IllegalFlowControlException(String message) { | ||
super(message); | ||
} | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/fr/insee/pogues/exception/IllegalIterationException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package fr.insee.pogues.exception; | ||
|
||
public class IllegalIterationException extends Exception { | ||
|
||
public IllegalIterationException(String message) { | ||
super(message); | ||
} | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/fr/insee/pogues/exception/NullReferenceException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package fr.insee.pogues.exception; | ||
|
||
/** Thrown when a referenced questionnaire is null when doing questionnaire de-referencing. */ | ||
public class NullReferenceException extends Exception { | ||
|
||
public NullReferenceException(String message) { | ||
super(message); | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/fr/insee/pogues/exception/PoguesDeserializationException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package fr.insee.pogues.exception; | ||
|
||
public class PoguesDeserializationException extends Exception { | ||
|
||
public PoguesDeserializationException(String message, Exception e) { | ||
super(message, e); | ||
} | ||
|
||
public PoguesDeserializationException(String message) { | ||
super(message); | ||
} | ||
|
||
} |
22 changes: 22 additions & 0 deletions
22
src/main/java/fr/insee/pogues/persistence/service/VariablesService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package fr.insee.pogues.persistence.service; | ||
|
||
import org.json.simple.JSONArray; | ||
import org.json.simple.JSONObject; | ||
|
||
public interface VariablesService { | ||
|
||
/** | ||
* Used for pogues frontend | ||
* @param id questionnaire id | ||
* @return variables as json string with caveats from pogues-model (like format for datedatatype, ...) | ||
*/ | ||
String getVariablesByQuestionnaire(String id); | ||
|
||
/** | ||
* Used for public enemy, delivers | ||
* @param id | ||
* @return variables as json directly from DB | ||
*/ | ||
JSONArray getVariablesByQuestionnaireForPublicEnemy(String id); | ||
|
||
} |
97 changes: 97 additions & 0 deletions
97
src/main/java/fr/insee/pogues/persistence/service/VariablesServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package fr.insee.pogues.persistence.service; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.ByteArrayOutputStream; | ||
import java.io.InputStream; | ||
import java.nio.charset.StandardCharsets; | ||
|
||
import javax.xml.bind.JAXBContext; | ||
import javax.xml.bind.Marshaller; | ||
import javax.xml.bind.Unmarshaller; | ||
import javax.xml.transform.stream.StreamSource; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.io.IOUtils; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.eclipse.persistence.jaxb.MarshallerProperties; | ||
import org.eclipse.persistence.jaxb.UnmarshallerProperties; | ||
import org.json.simple.JSONArray; | ||
import org.json.simple.JSONObject; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.jdbc.core.JdbcTemplate; | ||
import org.springframework.stereotype.Service; | ||
|
||
import fr.insee.pogues.model.Questionnaire; | ||
import fr.insee.pogues.persistence.query.QuestionnairesServiceQuery; | ||
|
||
@Service | ||
@Slf4j | ||
public class VariablesServiceImpl implements VariablesService { | ||
|
||
private static final Logger logger = LogManager.getLogger(VariablesServiceImpl.class); | ||
|
||
@Autowired | ||
JdbcTemplate jdbcTemplate; | ||
|
||
@Autowired | ||
private QuestionnairesServiceQuery questionnaireServiceQuery; | ||
|
||
public VariablesServiceImpl() {} | ||
|
||
public VariablesServiceImpl(QuestionnairesServiceQuery questionnairesServiceQuery) { | ||
this.questionnaireServiceQuery = questionnairesServiceQuery; | ||
} | ||
|
||
public JSONArray getVariablesByQuestionnaireForPublicEnemy(String id){ | ||
try { | ||
JSONObject questionnaire = questionnaireServiceQuery.getQuestionnaireByID(id); | ||
// We test the existence of the questionnaire in repository | ||
if (questionnaire != null) { | ||
JSONObject variables = (JSONObject) questionnaire.get("Variables"); | ||
return (JSONArray) variables.get("Variable"); | ||
} | ||
} catch (Exception e) { | ||
log.error("Exception occurred when trying to get variables from questionnaire with id={}", id, e); | ||
} | ||
return null; | ||
} | ||
|
||
public String getVariablesByQuestionnaire(String id){ | ||
StreamSource json = null; | ||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | ||
try { | ||
JSONObject questionnaire = questionnaireServiceQuery.getQuestionnaireByID(id); | ||
// We test the existence of the questionnaire in repository | ||
if (questionnaire != null) { | ||
logger.info("Deserializing questionnaire "); | ||
JAXBContext context = JAXBContext.newInstance(Questionnaire.class); | ||
Unmarshaller unmarshaller = context.createUnmarshaller(); | ||
unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json"); | ||
unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false); | ||
try(InputStream inQuestionnaire = new ByteArrayInputStream(questionnaire.toString().getBytes())){ | ||
json = new StreamSource(inQuestionnaire); | ||
Questionnaire questionnaireJava = unmarshaller.unmarshal(json, Questionnaire.class).getValue(); | ||
logger.info("Questionnaire " + questionnaireJava.getId() + " successfully deserialized"); | ||
logger.info("Serializing variables for questionnaire {}", questionnaireJava.getId()); | ||
JAXBContext context2 = JAXBContext.newInstance(Questionnaire.Variables.class); | ||
Marshaller marshaller = context2.createMarshaller(); | ||
marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json"); | ||
// Set it to true if you need to include the JSON root element in the JSON output | ||
marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, true); | ||
// Set it to true if you need the JSON output to formatted | ||
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); | ||
// Marshal the questionnaire object to JSON and put the output in a string | ||
marshaller.marshal(questionnaireJava.getVariables(), baos); | ||
} | ||
return baos.toString(StandardCharsets.UTF_8); | ||
} | ||
} catch (Exception e) { | ||
log.error("Exception occurred when trying to get variables from questionnaire with id={}", id, e); | ||
} finally { | ||
IOUtils.closeQuietly(baos); | ||
} | ||
return null; | ||
} | ||
|
||
} |
6 changes: 6 additions & 0 deletions
6
src/main/java/fr/insee/pogues/transforms/visualize/PoguesJSONToPoguesJSONDeref.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package fr.insee.pogues.transforms.visualize; | ||
|
||
import fr.insee.pogues.transforms.Transformer; | ||
|
||
public interface PoguesJSONToPoguesJSONDeref extends Transformer { | ||
} |
115 changes: 115 additions & 0 deletions
115
src/main/java/fr/insee/pogues/transforms/visualize/PoguesJSONToPoguesJSONDerefImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package fr.insee.pogues.transforms.visualize; | ||
|
||
import fr.insee.pogues.exception.NullReferenceException; | ||
import fr.insee.pogues.model.Questionnaire; | ||
import fr.insee.pogues.persistence.service.QuestionnairesService; | ||
import fr.insee.pogues.utils.PoguesDeserializer; | ||
import fr.insee.pogues.utils.PoguesSerializer; | ||
import fr.insee.pogues.transforms.visualize.composition.QuestionnaireComposition; | ||
import fr.insee.pogues.utils.json.JSONFunctions; | ||
import org.apache.commons.io.IOUtils; | ||
import org.apache.logging.log4j.LogManager; | ||
import org.apache.logging.log4j.Logger; | ||
import org.json.simple.JSONObject; | ||
import org.json.simple.parser.JSONParser; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.io.InputStream; | ||
import java.io.OutputStream; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
@Service | ||
public class PoguesJSONToPoguesJSONDerefImpl implements PoguesJSONToPoguesJSONDeref{ | ||
|
||
static final Logger logger = LogManager.getLogger(PoguesJSONToPoguesJSONDerefImpl.class); | ||
|
||
private static final String NULL_INPUT_MESSAGE = "Null input"; | ||
private static final String NULL_OUTPUT_MESSAGE = "Null output"; | ||
|
||
@Autowired | ||
QuestionnairesService questionnairesService; | ||
|
||
public PoguesJSONToPoguesJSONDerefImpl() {} | ||
|
||
public PoguesJSONToPoguesJSONDerefImpl(QuestionnairesService questionnairesService) { | ||
this.questionnairesService = questionnairesService; | ||
} | ||
|
||
@Override | ||
public void transform(InputStream input, OutputStream output, Map<String, Object> params, String surveyName) throws Exception { | ||
if (null == input) { | ||
throw new NullPointerException(NULL_INPUT_MESSAGE); | ||
} | ||
if (null == output) { | ||
throw new NullPointerException(NULL_OUTPUT_MESSAGE); | ||
} | ||
String jsonDeref = transform(input, params, surveyName); | ||
output.write(jsonDeref.getBytes(StandardCharsets.UTF_8)); | ||
} | ||
|
||
@Override | ||
public String transform(InputStream input, Map<String, Object> params, String surveyName) throws Exception { | ||
if (null == input) { | ||
throw new NullPointerException(NULL_INPUT_MESSAGE); | ||
} | ||
return transform(IOUtils.toString(input, StandardCharsets.UTF_8), params, surveyName); | ||
} | ||
|
||
@Override | ||
public String transform(String input, Map<String, Object> params, String surveyName) throws Exception { | ||
if (null == input) { | ||
throw new NullPointerException(NULL_INPUT_MESSAGE); | ||
} | ||
// TODO: This parameter could be replaced by logical check in back-office | ||
// (when Pogues-Model supports "childQuestionnaireRef") | ||
if (!(boolean) params.get("needDeref")) { | ||
logger.info("No de-referencing needed"); | ||
return input; | ||
} | ||
Questionnaire questionnaire = transformAsQuestionnaire(input); | ||
return PoguesSerializer.questionnaireJavaToString(questionnaire); | ||
} | ||
|
||
public Questionnaire transformAsQuestionnaire(String input) throws Exception { | ||
if (null == input) { | ||
throw new NullPointerException(NULL_INPUT_MESSAGE); | ||
} | ||
// Parse Pogues json questionnaire | ||
JSONParser parser = new JSONParser(); | ||
JSONObject jsonQuestionnaire = (JSONObject) parser.parse(input); | ||
// Get referenced questionnaire identifiers | ||
// TODO: The "childQuestionnaireRef" in the json should be supported by Pogues-Model | ||
List<String> references = JSONFunctions.getChildReferencesFromQuestionnaire(jsonQuestionnaire); | ||
// Deserialize json into questionnaire object | ||
Questionnaire questionnaire = PoguesDeserializer.questionnaireToJavaObject(jsonQuestionnaire); | ||
// | ||
deReference(references, questionnaire); | ||
logger.info("Sequences inserted"); | ||
// | ||
return questionnaire; | ||
} | ||
|
||
private void deReference(List<String> references, Questionnaire questionnaire) throws Exception { | ||
for (String reference : references) { | ||
JSONObject referencedJsonQuestionnaire = questionnairesService.getQuestionnaireByID(reference); | ||
if (referencedJsonQuestionnaire == null) { | ||
throw new NullReferenceException(String.format( | ||
"Null reference behind reference '%s' in questionnaire '%s'.", | ||
reference, questionnaire.getId())); | ||
} else { | ||
Questionnaire referencedQuestionnaire = PoguesDeserializer.questionnaireToJavaObject(referencedJsonQuestionnaire); | ||
// Coherence check | ||
if (! reference.equals(referencedQuestionnaire.getId())) { | ||
logger.warn("Reference '{}' found in questionnaire '{}' mismatch referenced questionnaire's id '{}'", | ||
reference, questionnaire.getId(), referencedQuestionnaire.getId()); | ||
} | ||
// | ||
QuestionnaireComposition.insertReference(questionnaire, referencedQuestionnaire); | ||
} | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.