-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Kjeld Froberg
committed
Jun 8, 2012
1 parent
1d50a5c
commit 9ad260e
Showing
122 changed files
with
2,382 additions
and
0 deletions.
There are no files selected for viewing
45 changes: 45 additions & 0 deletions
45
common/common/src/main/java/com/trifork/stamdata/specs/SorRelationsRecordSpecs.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,45 @@ | ||
/** | ||
* The contents of this file are subject to the Mozilla Public | ||
* License Version 1.1 (the "License"); you may not use this file | ||
* except in compliance with the License. You may obtain a copy of | ||
* the License at http://www.mozilla.org/MPL/ | ||
* | ||
* Software distributed under the License is distributed on an "AS | ||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | ||
* implied. See the License for the specific language governing | ||
* rights and limitations under the License. | ||
* | ||
* Contributor(s): Contributors are attributed in the source code | ||
* where applicable. | ||
* | ||
* The Original Code is "Stamdata". | ||
* | ||
* The Initial Developer of the Original Code is Trifork Public A/S. | ||
* | ||
* Portions created for the Original Code are Copyright 2011, | ||
* Lægemiddelstyrelsen. All Rights Reserved. | ||
* | ||
* Portions created for the FMKi Project are Copyright 2011, | ||
* National Board of e-Health (NSI). All Rights Reserved. | ||
*/ | ||
package com.trifork.stamdata.specs; | ||
|
||
import static com.trifork.stamdata.persistence.RecordSpecification.field; | ||
|
||
import com.trifork.stamdata.persistence.RecordSpecification; | ||
|
||
public final class SorRelationsRecordSpecs | ||
{ | ||
protected SorRelationsRecordSpecs() {} | ||
|
||
public static final RecordSpecification RELATIONS_RECORD_SPEC = RecordSpecification.createSpecification("SORRelationer", "SORRelationerPID", | ||
field("sor_parent", 100), | ||
field("sor_child", 100) | ||
); | ||
|
||
public static final RecordSpecification SHAK_YDER_RECORD_SPEC = RecordSpecification.createSpecification("SORYderSHAKRelationer", "SORYderSHAKRelationerPID", | ||
field("shak_yder", 100), | ||
field("sor", 100) | ||
); | ||
|
||
} |
304 changes: 304 additions & 0 deletions
304
...ger/src/main/java/com/trifork/stamdata/importer/jobs/sor/relations/SorRelationParser.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,304 @@ | ||
/** | ||
* The contents of this file are subject to the Mozilla Public | ||
* License Version 1.1 (the "License"); you may not use this file | ||
* except in compliance with the License. You may obtain a copy of | ||
* the License at http://www.mozilla.org/MPL/ | ||
* | ||
* Software distributed under the License is distributed on an "AS | ||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | ||
* implied. See the License for the specific language governing | ||
* rights and limitations under the License. | ||
* | ||
* Contributor(s): Contributors are attributed in the source code | ||
* where applicable. | ||
* | ||
* The Original Code is "Stamdata". | ||
* | ||
* The Initial Developer of the Original Code is Trifork Public A/S. | ||
* | ||
* Portions created for the Original Code are Copyright 2011, | ||
* Lægemiddelstyrelsen. All Rights Reserved. | ||
* | ||
* Portions created for the FMKi Project are Copyright 2011, | ||
* National Board of e-Health (NSI). All Rights Reserved. | ||
*/ | ||
package com.trifork.stamdata.importer.jobs.sor.relations; | ||
|
||
import static com.trifork.stamdata.Preconditions.checkNotNull; | ||
import static com.trifork.stamdata.importer.tools.SLALoggerHolder.getSLALogger; | ||
|
||
import java.io.File; | ||
import java.sql.SQLException; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
import javax.inject.Inject; | ||
import javax.xml.bind.JAXBContext; | ||
import javax.xml.bind.JAXBElement; | ||
import javax.xml.bind.JAXBException; | ||
import javax.xml.bind.Unmarshaller; | ||
import javax.xml.datatype.XMLGregorianCalendar; | ||
|
||
import oio.sundhedsstyrelsen.organisation._1_0.HealthInstitutionEntityType; | ||
import oio.sundhedsstyrelsen.organisation._1_0.HealthInstitutionType; | ||
import oio.sundhedsstyrelsen.organisation._1_0.InstitutionOwnerEntityType; | ||
import oio.sundhedsstyrelsen.organisation._1_0.InstitutionOwnerType; | ||
import oio.sundhedsstyrelsen.organisation._1_0.OrganizationalUnitEntityType; | ||
import oio.sundhedsstyrelsen.organisation._1_0.OrganizationalUnitType; | ||
import oio.sundhedsstyrelsen.organisation._1_0.SorStatusType; | ||
import oio.sundhedsstyrelsen.organisation._1_0.SorTreeType; | ||
|
||
import org.apache.log4j.Logger; | ||
import org.apache.log4j.MDC; | ||
import org.joda.time.DateTime; | ||
import org.mortbay.log.Log; | ||
|
||
import com.trifork.stamdata.importer.config.KeyValueStore; | ||
import com.trifork.stamdata.importer.parsers.Parser; | ||
import com.trifork.stamdata.importer.parsers.annotations.ParserInformation; | ||
import com.trifork.stamdata.importer.parsers.exceptions.OutOfSequenceException; | ||
import com.trifork.stamdata.importer.parsers.exceptions.ParserException; | ||
import com.trifork.stamdata.persistence.RecordBuilder; | ||
import com.trifork.stamdata.persistence.RecordPersister; | ||
import com.trifork.stamdata.persistence.RecordSpecification; | ||
import com.trifork.stamdata.specs.SorRelationsRecordSpecs; | ||
|
||
import dk.sdsd.nsp.slalog.api.SLALogItem; | ||
|
||
@ParserInformation(id = "sorRelation", name = "SorRelation") | ||
public class SorRelationParser implements Parser { | ||
|
||
private final RecordSpecification recordSpecification; | ||
private final RecordSpecification shakYderSpecification; | ||
private final KeyValueStore keyValueStore; | ||
private static Logger logger = Logger.getLogger(SorRelationParser.class); | ||
private Map<String, String> selfRelationsMap; | ||
private Map<String, HashSet<String>> shakYderMap; | ||
private DateTime snapshotDate; | ||
|
||
@Inject | ||
SorRelationParser(KeyValueStore keyValueStore) { | ||
this.keyValueStore = keyValueStore; | ||
this.recordSpecification = SorRelationsRecordSpecs.RELATIONS_RECORD_SPEC; | ||
this.shakYderSpecification = SorRelationsRecordSpecs.SHAK_YDER_RECORD_SPEC; | ||
} | ||
|
||
@Override | ||
public void process(File dataSet, RecordPersister persister) throws OutOfSequenceException, ParserException, | ||
Exception { | ||
|
||
SLALogItem slaLogItem = getSLALogger().createLogItem("SorRelationParser", "dataSet"); | ||
try { | ||
File files = checkRequiredFiles(dataSet); | ||
|
||
List<InstitutionOwnerEntityType> list = unmarshallFile(files); | ||
selfRelationsMap = new HashMap<String, String>(); | ||
shakYderMap = new HashMap<String, HashSet<String>>(); | ||
for (InstitutionOwnerEntityType institutions : list) { | ||
persistInstitutionRelations(institutions, persister); | ||
} | ||
// persist institutions relations with self | ||
Set<String> keys = selfRelationsMap.keySet(); | ||
for (String sorSelfRelationId : keys) { | ||
persistNode(sorSelfRelationId, sorSelfRelationId, persister); | ||
} | ||
|
||
// persist collected shak/yder numbers | ||
Set<String> syKeys = shakYderMap.keySet(); | ||
for (String shakYderKey : syKeys) { | ||
persistShakYder(shakYderKey, shakYderMap.get(shakYderKey), persister); | ||
} | ||
|
||
slaLogItem.setCallResultOk(); | ||
slaLogItem.store(); | ||
} catch (Exception e) { | ||
slaLogItem.setCallResultError("SorRelationParser Failed - Cause: " + e.getMessage()); | ||
slaLogItem.store(); | ||
throw e; | ||
} finally { | ||
selfRelationsMap = null; | ||
shakYderMap = null; | ||
} | ||
|
||
} | ||
|
||
private void persistInstitutionRelations(InstitutionOwnerEntityType institution, RecordPersister persister) throws SQLException { | ||
|
||
InstitutionOwnerType owner = institution.getInstitutionOwner(); | ||
String ownerId = ""+owner.getSorIdentifier(); | ||
if(!hasValidPeriod(owner.getSorStatus())) { | ||
Log.debug("Institution with SOR id:" +ownerId+" is is no longer valid, toDate: "+owner.getSorStatus().getToDate()); | ||
return; | ||
} | ||
|
||
List<HealthInstitutionEntityType> childInstitutions = institution.getHealthInstitutionEntity(); | ||
|
||
selfRelationsMap.put(ownerId, ""); | ||
|
||
for (HealthInstitutionEntityType hiChild : childInstitutions) { | ||
String childId = ""+hiChild.getHealthInstitution().getSorIdentifier(); | ||
persistNode(ownerId, childId, persister); | ||
|
||
List<OrganizationalUnitEntityType> organizationalUnitEntity = hiChild.getOrganizationalUnitEntity(); | ||
for (OrganizationalUnitEntityType ouChild : organizationalUnitEntity) { | ||
traverseOrganizationalUnitEntity(ownerId, ouChild, persister); | ||
} | ||
traverseHealthInstitutionChild(hiChild, persister); | ||
} | ||
} | ||
|
||
private void traverseHealthInstitutionChild(HealthInstitutionEntityType child, RecordPersister persister) throws SQLException { | ||
HealthInstitutionType healthInstitution = child.getHealthInstitution(); | ||
|
||
String hiChildId = ""+healthInstitution.getSorIdentifier(); | ||
if(!hasValidPeriod(healthInstitution.getSorStatus())) { | ||
Log.debug("Institution with SOR id:" +hiChildId+" is no longer valid, toDate: "+healthInstitution.getSorStatus().getToDate()); | ||
return; | ||
} | ||
|
||
selfRelationsMap.put(hiChildId, ""); | ||
|
||
String shakIdentifier = healthInstitution.getShakIdentifier(); | ||
if(shakIdentifier != null && shakIdentifier.trim().length() > 0) { | ||
putValueInShakYderMap("SHAK="+shakIdentifier, hiChildId); | ||
} | ||
|
||
List<OrganizationalUnitEntityType> organizationalUnitEntity = child.getOrganizationalUnitEntity(); | ||
for (OrganizationalUnitEntityType ouChild : organizationalUnitEntity) { | ||
traverseOrganizationalUnitEntity(hiChildId, ouChild, persister); | ||
} | ||
} | ||
|
||
private void traverseOrganizationalUnitEntity(String parentId, OrganizationalUnitEntityType ouChild, RecordPersister persister) throws SQLException { | ||
OrganizationalUnitType ou = ouChild.getOrganizationalUnit(); | ||
String childId = ""+ou.getSorIdentifier(); | ||
|
||
if(!hasValidPeriod(ou.getSorStatus())) { | ||
Log.debug("Institution with SOR id:" +ou+" is no longer valid, toDate: "+ou.getSorStatus().getToDate()); | ||
return; | ||
} | ||
|
||
// persist relation with owner and with self | ||
persistNode(parentId, childId, persister); | ||
selfRelationsMap.put(childId, ""); | ||
|
||
String shakIdentifier = ou.getShakIdentifier(); | ||
if(shakIdentifier != null && shakIdentifier.trim().length() > 0) { | ||
putValueInShakYderMap("SHAK="+shakIdentifier, childId); | ||
} | ||
String yderIdentifier = ou.getProviderIdentifier(); | ||
if(yderIdentifier != null && yderIdentifier.trim().length() > 0) { | ||
putValueInShakYderMap("Yder="+yderIdentifier, childId); | ||
} | ||
|
||
if(ouChild.getOrganizationalUnitEntity() != null) { | ||
// first persist any existing childs with parent relation | ||
List<OrganizationalUnitEntityType> subChilds = ouChild.getOrganizationalUnitEntity(); | ||
for (OrganizationalUnitEntityType subChild : subChilds) { | ||
traverseOrganizationalUnitEntity(parentId, subChild, persister); | ||
} | ||
// then traverse recursively through childs; | ||
List<OrganizationalUnitEntityType> subChilds2 = ouChild.getOrganizationalUnitEntity(); | ||
for (OrganizationalUnitEntityType subChild : subChilds2) { | ||
String ouChildId = ""+ouChild.getOrganizationalUnit().getSorIdentifier(); | ||
traverseOrganizationalUnitEntity(ouChildId, subChild, persister); | ||
} | ||
} | ||
} | ||
|
||
private void persistNode(String parent, String child, RecordPersister persister) throws SQLException { | ||
RecordBuilder OwnerRecord = new RecordBuilder(recordSpecification); | ||
OwnerRecord.field("sor_parent", parent); | ||
OwnerRecord.field("sor_child", child); | ||
persister.persist(OwnerRecord.build(), recordSpecification); | ||
} | ||
|
||
private void persistShakYder(String shakYder, HashSet<String> sorSet, RecordPersister persister) throws SQLException { | ||
|
||
if(shakYder == null) { | ||
throw new IllegalArgumentException("SHAK or YDER must be set"); | ||
} | ||
|
||
for (String sor : sorSet) { | ||
RecordBuilder OwnerRecord = new RecordBuilder(shakYderSpecification); | ||
OwnerRecord.field("shak_yder", shakYder); | ||
OwnerRecord.field("sor", sor); | ||
persister.persist(OwnerRecord.build(), shakYderSpecification); | ||
} | ||
} | ||
|
||
private void putValueInShakYderMap(String shakYder, String sor) { | ||
|
||
HashSet<String> sorSet = shakYderMap.get(shakYder); | ||
if(sorSet == null) { | ||
sorSet = new HashSet<String>(); | ||
} | ||
sorSet.add(sor); | ||
shakYderMap.put(shakYder, sorSet); | ||
} | ||
|
||
|
||
private boolean hasValidPeriod(SorStatusType sorStatus) { | ||
if(sorStatus != null) { | ||
XMLGregorianCalendar toDate = sorStatus.getToDate(); | ||
if(toDate != null) { | ||
DateTime toDateTime = new DateTime(toDate.toGregorianCalendar().getTime()); | ||
if(snapshotDate.isAfter(toDateTime)) { | ||
return false; | ||
} | ||
} | ||
} | ||
// if toDate of sorStatus cannot be found assume entity is valid. | ||
return true; | ||
} | ||
|
||
private List<InstitutionOwnerEntityType> unmarshallFile(File dataSet) { | ||
List<InstitutionOwnerEntityType> list = new ArrayList<InstitutionOwnerEntityType>(); | ||
|
||
try { | ||
JAXBContext jaxbContext = JAXBContext.newInstance(SorTreeType.class.getPackage().getName()); | ||
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); | ||
File[] input = null; | ||
if(dataSet.isDirectory()) { | ||
input = dataSet.listFiles(); | ||
} else { | ||
input = new File[] {dataSet}; | ||
} | ||
|
||
for (int i = 0; i < input.length; i++) { | ||
JAXBElement<SorTreeType> jaxbSOR = (JAXBElement<SorTreeType>) jaxbUnmarshaller.unmarshal(input[i]); | ||
SorTreeType sor = jaxbSOR.getValue(); | ||
snapshotDate = new DateTime(sor.getSnapshotDate().toGregorianCalendar().getTime()); | ||
List<InstitutionOwnerEntityType> institutionOwnerEntity = sor.getInstitutionOwnerEntity(); | ||
list.addAll(institutionOwnerEntity); | ||
} | ||
} catch (JAXBException e) { | ||
logger.error("", e); | ||
} | ||
return list; | ||
} | ||
|
||
private File checkRequiredFiles(File dataSet) { | ||
|
||
checkNotNull(dataSet); | ||
|
||
File[] input = null; | ||
if(dataSet.isDirectory()) { | ||
input = dataSet.listFiles(); | ||
} else { | ||
input = new File[] {dataSet}; | ||
} | ||
|
||
for (int i = 0; i < input.length; i++) { | ||
String fileName = input[i].getName(); | ||
MDC.put("filename", fileName); | ||
} | ||
|
||
return dataSet; | ||
} | ||
|
||
} |
3 changes: 3 additions & 0 deletions
3
...ta-manager/src/main/resources/com/trifork/stamdata/importer/jobs/sor/relations/jaxb.index
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,3 @@ | ||
SorTree | ||
InstitutionOwnerEntity | ||
InstitutionOwner |
11 changes: 11 additions & 0 deletions
11
dodi/data-manager/src/main/resources/sorschema/ActivityAddressInformation.xsd
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,11 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<xs:schema xmlns="urn:oio:sundhedsstyrelsen:organisation:1.0.0" | ||
xmlns:xs="http://www.w3.org/2001/XMLSchema" | ||
targetNamespace="urn:oio:sundhedsstyrelsen:organisation:1.0.0" | ||
elementFormDefault="qualified" | ||
attributeFormDefault="unqualified" | ||
xml:lang="EN" > | ||
<xs:include schemaLocation="AddressInformation.xsd"/> | ||
|
||
<xs:element name="ActivityAddressInformation" type="AddressInformationType"/> | ||
</xs:schema> |
17 changes: 17 additions & 0 deletions
17
dodi/data-manager/src/main/resources/sorschema/ActivityAddressInformation.xsd.meta.xml
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,17 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Metadata xmlns="http://rep.oio.dk/infostructurebase/schemas/2004/09/13/"> | ||
<Title>ActivityAddressInformation</Title> | ||
<DescriptionStructure> | ||
<DescriptionEnglish /> | ||
<DescriptionDanish>Oplysninger om enhedens aktivitetsadresse. Aktivitetsadressen kan angives som værende den samme som enhedens besøgsadresse. Obligatorisk oplysning.</DescriptionDanish> | ||
</DescriptionStructure> | ||
<Author>Sundhedsstyrelsen, SOR</Author> | ||
<LabelStructure> | ||
<LabelDanish>Aktivitetsadresse</LabelDanish> | ||
</LabelStructure> | ||
<ObjectTerm>Adresse</ObjectTerm> | ||
<PropertyTerm></PropertyTerm> | ||
<RepresentationTerm></RepresentationTerm> | ||
<Version>1.0.0</Version> | ||
</Metadata> | ||
|
Oops, something went wrong.