org.commonjava.aprox.depgraph.json.ProjectRelationshipSerializerModule.java Source code

Java tutorial

Introduction

Here is the source code for org.commonjava.aprox.depgraph.json.ProjectRelationshipSerializerModule.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Red Hat, Inc..
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package org.commonjava.aprox.depgraph.json;

import static org.commonjava.aprox.depgraph.json.SerializationConstants.CURRENT_JSON_VERSION;
import static org.commonjava.aprox.depgraph.json.SerializationConstants.DECLARING_REF;
import static org.commonjava.aprox.depgraph.json.SerializationConstants.INDEX;
import static org.commonjava.aprox.depgraph.json.SerializationConstants.JSON_VERSION;
import static org.commonjava.aprox.depgraph.json.SerializationConstants.MANAGED;
import static org.commonjava.aprox.depgraph.json.SerializationConstants.PLUGIN_REF;
import static org.commonjava.aprox.depgraph.json.SerializationConstants.POM_LOCATION_URI;
import static org.commonjava.aprox.depgraph.json.SerializationConstants.RELATIONSHIP_TYPE;
import static org.commonjava.aprox.depgraph.json.SerializationConstants.SCOPE;
import static org.commonjava.aprox.depgraph.json.SerializationConstants.TARGET_REF;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import javax.enterprise.context.ApplicationScoped;

import org.commonjava.aprox.model.core.io.AproxSerializationException;
import org.commonjava.maven.atlas.graph.rel.BomRelationship;
import org.commonjava.maven.atlas.graph.rel.DependencyRelationship;
import org.commonjava.maven.atlas.graph.rel.ExtensionRelationship;
import org.commonjava.maven.atlas.graph.rel.ParentRelationship;
import org.commonjava.maven.atlas.graph.rel.PluginDependencyRelationship;
import org.commonjava.maven.atlas.graph.rel.PluginRelationship;
import org.commonjava.maven.atlas.graph.rel.ProjectRelationship;
import org.commonjava.maven.atlas.graph.rel.RelationshipType;
import org.commonjava.maven.atlas.ident.DependencyScope;
import org.commonjava.maven.atlas.ident.ref.ArtifactRef;
import org.commonjava.maven.atlas.ident.ref.ProjectRef;
import org.commonjava.maven.atlas.ident.ref.ProjectVersionRef;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.io.SerializedString;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

@ApplicationScoped
public class ProjectRelationshipSerializerModule extends SimpleModule {

    private static final long serialVersionUID = 1L;

    public ProjectRelationshipSerializerModule() {
        super("ProjectRelationship<?> Serializer");
        addSerializer(ProjectRelationship.class, new ProjectRelationshipSerializer());
        addDeserializer(ProjectRelationship.class, new ProjectRelationshipDeserializer());
    }

    @Override
    public int hashCode() {
        return getClass().getSimpleName().hashCode() + 17;
    }

    @Override
    public boolean equals(final Object other) {
        return getClass().equals(other.getClass());
    }

    @SuppressWarnings("rawtypes")
    private static final class ProjectRelationshipSerializer extends StdSerializer<ProjectRelationship> {
        ProjectRelationshipSerializer() {
            super(ProjectRelationship.class);
        }

        @SuppressWarnings("incomplete-switch")
        @Override
        public void serialize(final ProjectRelationship value, final JsonGenerator gen,
                final SerializerProvider provider) throws IOException, JsonGenerationException {
            gen.writeStartObject();
            gen.writeNumberField(JSON_VERSION.getValue(), SerializationConstants.CURRENT_JSON_VERSION);
            gen.writeStringField(RELATIONSHIP_TYPE.getValue(), value.getType().name());
            provider.defaultSerializeField(DECLARING_REF.getValue(), value.getDeclaring(), gen);
            provider.defaultSerializeField(TARGET_REF.getValue(), value.getTarget(), gen);
            gen.writeNumberField(INDEX.getValue(), value.getIndex());

            switch (value.getType()) {
            case DEPENDENCY: {
                gen.writeStringField(SCOPE.getValue(), ((DependencyRelationship) value).getScope().realName());
                break;
            }
            case PLUGIN_DEP: {
                provider.defaultSerializeField(PLUGIN_REF.getValue(),
                        ((PluginDependencyRelationship) value).getPlugin(), gen);
                break;
            }
            }
            gen.writeEndObject();
        }

    }

    @SuppressWarnings("rawtypes")
    private static final class ProjectRelationshipDeserializer extends StdDeserializer<ProjectRelationship> {
        private static final long serialVersionUID = 1L;

        ProjectRelationshipDeserializer() {
            super(ProjectRelationship.class);
        }

        @Override
        public ProjectRelationship deserialize(final JsonParser jp, final DeserializationContext ctx)
                throws IOException, JsonProcessingException {
            final int version = expectField(jp, JSON_VERSION).nextIntValue(CURRENT_JSON_VERSION);
            if (version > CURRENT_JSON_VERSION) {
                throw new AproxSerializationException(
                        "Cannot deserialize ProjectRelationship JSON with version: " + version,
                        jp.getCurrentLocation());
            }

            final JsonDeserializer<Object> prDeser = ctx
                    .findRootValueDeserializer(ctx.getTypeFactory().constructType(ProjectRef.class));
            final JsonDeserializer<Object> pvrDeser = ctx
                    .findRootValueDeserializer(ctx.getTypeFactory().constructType(ProjectVersionRef.class));
            final JsonDeserializer<Object> arDeser = ctx
                    .findRootValueDeserializer(ctx.getTypeFactory().constructType(ArtifactRef.class));

            final RelationshipType type = RelationshipType
                    .getType(expectField(jp, RELATIONSHIP_TYPE).nextTextValue());

            expectField(jp, DECLARING_REF).nextTextValue();
            final ProjectVersionRef declaring = (ProjectVersionRef) pvrDeser.deserialize(jp, ctx);

            final String uri = expectField(jp, POM_LOCATION_URI).nextTextValue();
            URI pomLocation;
            try {
                pomLocation = new URI(uri);
            } catch (final URISyntaxException e) {
                throw new AproxSerializationException(
                        "Invalid " + POM_LOCATION_URI + ": '" + uri + "': " + e.getMessage(),
                        jp.getCurrentLocation(), e);
            }

            switch (type) {
            case DEPENDENCY: {
                expectField(jp, TARGET_REF).nextTextValue();
                final ArtifactRef target = (ArtifactRef) arDeser.deserialize(jp, ctx);

                final DependencyScope scope = DependencyScope.getScope(expectField(jp, SCOPE).nextTextValue());

                return new DependencyRelationship(pomLocation, declaring, target, scope, getIndex(jp),
                        isManaged(jp));
            }
            case EXTENSION: {
                expectField(jp, TARGET_REF).nextTextValue();
                final ProjectVersionRef target = (ProjectVersionRef) pvrDeser.deserialize(jp, ctx);

                return new ExtensionRelationship(pomLocation, declaring, target, getIndex(jp));
            }
            case PARENT: {
                expectField(jp, TARGET_REF).nextTextValue();
                final ProjectVersionRef target = (ProjectVersionRef) pvrDeser.deserialize(jp, ctx);

                return new ParentRelationship(pomLocation, declaring, target);
            }
            case PLUGIN: {
                expectField(jp, TARGET_REF).nextTextValue();
                final ProjectVersionRef target = (ProjectVersionRef) pvrDeser.deserialize(jp, ctx);

                return new PluginRelationship(pomLocation, declaring, target, getIndex(jp), isManaged(jp));
            }
            case PLUGIN_DEP: {
                expectField(jp, PLUGIN_REF).nextTextValue();
                final ProjectRef plugin = (ProjectRef) prDeser.deserialize(jp, ctx);

                expectField(jp, TARGET_REF).nextTextValue();
                final ArtifactRef target = (ArtifactRef) arDeser.deserialize(jp, ctx);

                return new PluginDependencyRelationship(pomLocation, declaring, plugin, target, getIndex(jp),
                        isManaged(jp));
            }
            case BOM: {
                expectField(jp, TARGET_REF).nextTextValue();
                final ProjectVersionRef target = (ProjectVersionRef) pvrDeser.deserialize(jp, ctx);

                return new BomRelationship(pomLocation, declaring, target, getIndex(jp));
            }
            }

            return null;
        }

        private JsonParser expectField(final JsonParser jp, final SerializedString named)
                throws JsonParseException, IOException {
            if (!jp.nextFieldName(named)) {
                throw new AproxSerializationException("Expected field: " + named, jp.getCurrentLocation());
            }

            return jp;
        }

        private boolean isManaged(final JsonParser jp) throws JsonParseException, IOException {
            return expectField(jp, MANAGED).nextBooleanValue();
        }

        private int getIndex(final JsonParser jp) throws JsonParseException, IOException {
            return expectField(jp, INDEX).nextIntValue(0);
        }
    }

}