/*- * Copyright 2020 Hochschule für Technik Stuttgart * * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.hft.stuttgart.quality.marshaller; import java.util.List; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; import javax.xml.bind.JAXBElement; import org.citygml4j.builder.jaxb.unmarshal.citygml.ade.ADEUnmarshallerHelper; import org.citygml4j.model.citygml.ade.binding.ADEModelObject; import org.citygml4j.model.citygml.ade.binding.ADEUnmarshaller; import org.citygml4j.util.mapper.CheckedTypeMapper; import org.citygml4j.xml.io.reader.MissingADESchemaException; import de.hft.stuttgart.quality.model.AllPolygonsWrongOrientation; import de.hft.stuttgart.quality.model.AttributeMissing; import de.hft.stuttgart.quality.model.AttributeWrongValue; import de.hft.stuttgart.quality.model.ConsecutivePointsSame; import de.hft.stuttgart.quality.model.Edge; import de.hft.stuttgart.quality.model.HoleOutside; import de.hft.stuttgart.quality.model.InnerRingsNested; import de.hft.stuttgart.quality.model.InteriorDisconnected; import de.hft.stuttgart.quality.model.IntersectingRings; import de.hft.stuttgart.quality.model.MultipleConnectedComponents; import de.hft.stuttgart.quality.model.NonManifoldEdge; import de.hft.stuttgart.quality.model.NonManifoldVertex; import de.hft.stuttgart.quality.model.NonPlanarDistancePlane; import de.hft.stuttgart.quality.model.NonPlanarNormalsDeviation; import de.hft.stuttgart.quality.model.OrientationRingsSame; import de.hft.stuttgart.quality.model.PolygonWrongOrientation; import de.hft.stuttgart.quality.model.RingNotClosed; import de.hft.stuttgart.quality.model.RingSelfIntersection; import de.hft.stuttgart.quality.model.SolidNotClosed; import de.hft.stuttgart.quality.model.SolidSelfIntersection; import de.hft.stuttgart.quality.model.TooFewPoints; import de.hft.stuttgart.quality.model.TooFewPolygons; import de.hft.stuttgart.quality.model.Validation; import de.hft.stuttgart.quality.model.ValidationError; import de.hft.stuttgart.quality.model.ValidationResult; import de.hft.stuttgart.quality.model.jaxb.AllPolygonsWrongOrientationType; import de.hft.stuttgart.quality.model.jaxb.AttributeMissingType; import de.hft.stuttgart.quality.model.jaxb.AttributeWrongValueType; import de.hft.stuttgart.quality.model.jaxb.ConsecutivePointsSameType; import de.hft.stuttgart.quality.model.jaxb.EdgeType; import de.hft.stuttgart.quality.model.jaxb.HoleOutsideType; import de.hft.stuttgart.quality.model.jaxb.InnerRingsNestedType; import de.hft.stuttgart.quality.model.jaxb.InteriorDisconnectedType; import de.hft.stuttgart.quality.model.jaxb.IntersectingRingsType; import de.hft.stuttgart.quality.model.jaxb.MultipleConnectedComponentsType; import de.hft.stuttgart.quality.model.jaxb.NonManifoldEdgeType; import de.hft.stuttgart.quality.model.jaxb.NonManifoldVertexType; import de.hft.stuttgart.quality.model.jaxb.NonPlanarDistancePlaneType; import de.hft.stuttgart.quality.model.jaxb.NonPlanarNormalsDeviationType; import de.hft.stuttgart.quality.model.jaxb.OrientationRingsSameType; import de.hft.stuttgart.quality.model.jaxb.PolygonWrongOrientationType; import de.hft.stuttgart.quality.model.jaxb.RingNotClosedType; import de.hft.stuttgart.quality.model.jaxb.RingSelfIntersectionType; import de.hft.stuttgart.quality.model.jaxb.SolidNotClosedType; import de.hft.stuttgart.quality.model.jaxb.SolidSelfIntersectionType; import de.hft.stuttgart.quality.model.jaxb.TooFewPointsType; import de.hft.stuttgart.quality.model.jaxb.TooFewPolygonsType; import de.hft.stuttgart.quality.model.jaxb.ValidationErrorType; import de.hft.stuttgart.quality.model.jaxb.ValidationResultType; import de.hft.stuttgart.quality.model.jaxb.ValidationType; import de.hft.stuttgart.quality.util.UncheckedMissingADESchemaException; public class QualityAdeUnmarshaller implements ADEUnmarshaller { private final ReentrantLock lock = new ReentrantLock(); private CheckedTypeMapper typeMapper; private ADEUnmarshallerHelper helper; private CheckedTypeMapper getTypeMapper() { if (typeMapper == null) { lock.lock(); try { if (typeMapper == null) { typeMapper = CheckedTypeMapper.create() .with(ValidationType.class, this::unmarshalValidationType) .with(ValidationResultType.class, this::umarshalValidationResultType) .with(ConsecutivePointsSameType.class, this::unmarshalConsecutivePointsSameType) .with(TooFewPointsType.class, this::unmarshalTooFewPointsType) .with(RingSelfIntersectionType.class, this::unmarshalRingSelfIntersectionType) .with(RingNotClosedType.class, this::unmarshalRingNotClosedType) .with(InteriorDisconnectedType.class, this::unmarshalInteriorDisconnectedType) .with(IntersectingRingsType.class, this::unmarshalIntersectingRingsType) .with(NonPlanarDistancePlaneType.class, this::unmarshalNonPlanarDistancePlaneType) .with(InnerRingsNestedType.class, this::unmarshalInnerRingsType) .with(HoleOutsideType.class, this::unmarshalHoleOutsideType) .with(OrientationRingsSameType.class, this::unmarshalOrientationRingsSameType) .with(NonPlanarNormalsDeviationType.class, this::unmarshalNonPlanarNormalsDeviationType) .with(AllPolygonsWrongOrientationType.class, this::unmarshalAllPolygonsWrongOrientationType) .with(PolygonWrongOrientationType.class, this::unmarshalPolygonWrongOrientationType) .with(SolidSelfIntersectionType.class, this::unmarshalSolidSelfIntersectionType) .with(NonManifoldVertexType.class, this::unmarshalNonManifoldVertexType) .with(NonManifoldEdgeType.class, this::unmarshalNonManifoldEdgeType) .with(SolidNotClosedType.class, this::unmarshalSolidNotClosedType) .with(TooFewPolygonsType.class, this::unmarshalTooFewPolygonsType) .with(MultipleConnectedComponentsType.class, this::unmarshalMultipleConnectedComponentsType) .with(AttributeWrongValueType.class, this::unmarshalAttributeWrongValueType) .with(AttributeMissingType.class, this::unmarshalAttributeMissingType); } } finally { lock.unlock(); } } return typeMapper; } @Override public void setADEUnmarshallerHelper(ADEUnmarshallerHelper helper) { this.helper = helper; } @Override public ADEModelObject unmarshal(JAXBElement src) throws MissingADESchemaException { return unmarshal(src.getValue()); } @Override public ADEModelObject unmarshal(Object src) throws MissingADESchemaException { return getTypeMapper().apply(src); } private Validation unmarshalValidationType(ValidationType src) { Validation dest = new Validation(); dest.setValidationDate(src.getValidationDate()); dest.setValidationSoftware(src.getValidationSoftware()); dest.setValidationPlan(src.getValidationPlan()); dest.setStatistics(src.getStatistics()); return dest; } private ValidationResult umarshalValidationResultType(ValidationResultType src) throws MissingADESchemaException { ValidationResult dest = new ValidationResult(); dest.setResult(src.getResult()); if (src.isSetErrors()) { try { dest.getErrors() .addAll(src.getErrors().stream().map(this::unmarshalError).collect(Collectors.toList())); } catch (UncheckedMissingADESchemaException e) { throw e.getCause(); } } return dest; } private ValidationError unmarshalError(ValidationErrorType err) { try { return (ValidationError) getTypeMapper().apply(err); } catch (MissingADESchemaException e) { throw new UncheckedMissingADESchemaException(e); } } private ConsecutivePointsSame unmarshalConsecutivePointsSameType(ConsecutivePointsSameType src) { ConsecutivePointsSame dest = new ConsecutivePointsSame(); dest.setLinearRingId(src.getLinearRingId()); dest.setVertex1(helper.getGMLUnmarshaller().unmarshalDirectPosition(src.getVertex1())); dest.setVertex2(helper.getGMLUnmarshaller().unmarshalDirectPosition(src.getVertex2())); return dest; } private TooFewPoints unmarshalTooFewPointsType(TooFewPointsType src) { TooFewPoints dest = new TooFewPoints(); dest.setLinearRingId(src.getLinearRingId()); return dest; } private RingSelfIntersection unmarshalRingSelfIntersectionType(RingSelfIntersectionType src) { RingSelfIntersection dest = new RingSelfIntersection(); if (src.getEdge1() != null) { dest.setEdge1(unmarshalEdge(src.getEdge1())); } if (src.getEdge2() != null) { dest.setEdge2(unmarshalEdge(src.getEdge2())); } dest.setLinearRingId(src.getLinearRingId()); dest.setType(src.getType()); if (src.getVertex1() != null) { dest.setVertex1(helper.getGMLUnmarshaller().unmarshalDirectPosition(src.getVertex1())); } if (src.getVertex2() != null) { dest.setVertex2(helper.getGMLUnmarshaller().unmarshalDirectPosition(src.getVertex2())); } return dest; } private RingNotClosed unmarshalRingNotClosedType(RingNotClosedType src) { RingNotClosed dest = new RingNotClosed(); dest.setLinearRingId(src.getLinearRingId()); return dest; } private Edge unmarshalEdge(EdgeType src) { Edge dest = new Edge(); if (src.getFrom() != null) { dest.setFrom(helper.getGMLUnmarshaller().unmarshalDirectPosition(src.getFrom())); } if (src.getTo() != null) { dest.setTo(helper.getGMLUnmarshaller().unmarshalDirectPosition(src.getTo())); } return dest; } private InteriorDisconnected unmarshalInteriorDisconnectedType(InteriorDisconnectedType src) { InteriorDisconnected dest = new InteriorDisconnected(); dest.setPolygonId(src.getPolygonId()); return dest; } private IntersectingRings unmarshalIntersectingRingsType(IntersectingRingsType src) { IntersectingRings dest = new IntersectingRings(); dest.setPolygonId(src.getPolygonId()); dest.setLinearRingId1(src.getLinearRingId1()); dest.setLinearRingId2(src.getLinearRingId2()); return dest; } private InnerRingsNested unmarshalInnerRingsType(InnerRingsNestedType src) { InnerRingsNested dest = new InnerRingsNested(); dest.setPolygonId(src.getPolygonId()); dest.setLinearRingId1(src.getLinearRingId1()); dest.setLinearRingId2(src.getLinearRingId2()); return dest; } private NonPlanarDistancePlane unmarshalNonPlanarDistancePlaneType(NonPlanarDistancePlaneType src) { NonPlanarDistancePlane dest = new NonPlanarDistancePlane(); dest.setPolygonId(src.getPolygonId()); if (src.getVertex() != null) { dest.setVertex(helper.getGMLUnmarshaller().unmarshalDirectPosition(src.getVertex())); } if (src.getDistance() != null) { dest.setDistance(helper.getGMLUnmarshaller().unmarshalLength(src.getDistance())); } return dest; } private HoleOutside unmarshalHoleOutsideType(HoleOutsideType src) { HoleOutside dest = new HoleOutside(); dest.setPolygonId(src.getPolygonId()); dest.setLinearRingId(src.getLinearRingId()); return dest; } private NonPlanarNormalsDeviation unmarshalNonPlanarNormalsDeviationType(NonPlanarNormalsDeviationType src) { NonPlanarNormalsDeviation dest = new NonPlanarNormalsDeviation(); dest.setPolygonId(src.getPolygonId()); if (src.getDeviation() != null) { dest.setDeviation(helper.getGMLUnmarshaller().unmarshalAngle(src.getDeviation())); } return dest; } private OrientationRingsSame unmarshalOrientationRingsSameType(OrientationRingsSameType src) { OrientationRingsSame dest = new OrientationRingsSame(); dest.setPolygonId(src.getPolygonId()); dest.setLinearRingId(src.getLinearRingId()); return dest; } private AllPolygonsWrongOrientation unmarshalAllPolygonsWrongOrientationType(AllPolygonsWrongOrientationType src) { AllPolygonsWrongOrientation dest = new AllPolygonsWrongOrientation(); dest.setGeometryId(src.getGeometryId()); return dest; } private PolygonWrongOrientation unmarshalPolygonWrongOrientationType(PolygonWrongOrientationType src) { PolygonWrongOrientation dest = new PolygonWrongOrientation(); dest.setGeometryId(src.getGeometryId()); if (src.isSetEdges()) { List edges = dest.getEdges(); for (EdgeType e : src.getEdges()) { edges.add(unmarshalEdge(e)); } } return dest; } private SolidSelfIntersection unmarshalSolidSelfIntersectionType(SolidSelfIntersectionType src) { SolidSelfIntersection dest = new SolidSelfIntersection(); dest.setGeometryId(src.getGeometryId()); dest.setPolygonId1(src.getPolygonId1()); dest.setPolygonId2(src.getPolygonId2()); return dest; } private NonManifoldVertex unmarshalNonManifoldVertexType(NonManifoldVertexType src) { NonManifoldVertex dest = new NonManifoldVertex(); dest.setGeometryId(src.getGeometryId()); if (src.getVertex() != null) { dest.setVertex(helper.getGMLUnmarshaller().unmarshalDirectPosition(src.getVertex())); } return dest; } private NonManifoldEdge unmarshalNonManifoldEdgeType(NonManifoldEdgeType src) { NonManifoldEdge dest = new NonManifoldEdge(); dest.setGeometryId(src.getGeometryId()); if (src.isSetEdges()) { List edges = dest.getEdges(); for (EdgeType e : src.getEdges()) { edges.add(unmarshalEdge(e)); } } return dest; } private SolidNotClosed unmarshalSolidNotClosedType(SolidNotClosedType src) { SolidNotClosed dest = new SolidNotClosed(); dest.setGeometryId(src.getGeometryId()); if (src.isSetEdges()) { List edges = dest.getEdges(); for (EdgeType e : src.getEdges()) { edges.add(unmarshalEdge(e)); } } return dest; } private TooFewPolygons unmarshalTooFewPolygonsType(TooFewPolygonsType src) { TooFewPolygons dest = new TooFewPolygons(); dest.setGeometryId(src.getGeometryId()); return dest; } private MultipleConnectedComponents unmarshalMultipleConnectedComponentsType(MultipleConnectedComponentsType src) { MultipleConnectedComponents dest = new MultipleConnectedComponents(); dest.setGeometryId(src.getGeometryId()); if (src.isSetComponents()) { dest.getComponents().addAll(src.getComponents()); } return dest; } private AttributeWrongValue unmarshalAttributeWrongValueType(AttributeWrongValueType src) { AttributeWrongValue dest = new AttributeWrongValue(); dest.setAttributeName(src.getAttributeName()); dest.setChildId(src.getChildId()); dest.setGeneric(src.isGeneric()); return dest; } private AttributeMissing unmarshalAttributeMissingType(AttributeMissingType src) { AttributeMissing dest = new AttributeMissing(); dest.setAttributeName(src.getAttributeName()); dest.setChildId(src.getChildId()); dest.setGeneric(src.isGeneric()); return dest; } }