Java tutorial
/* * Copyright 2013 Agorava * * 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 org.agorava.linkedin.jackson; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.agorava.api.atinject.BeanResolver; import org.agorava.linkedin.model.Company; import org.agorava.linkedin.model.LinkedInNetworkUpdate; import org.agorava.linkedin.model.UpdateAction; import org.agorava.linkedin.model.UpdateContent; import org.agorava.linkedin.model.UpdateContentCompany; import org.agorava.linkedin.model.UpdateContentConnection; import org.agorava.linkedin.model.UpdateContentFollow; import org.agorava.linkedin.model.UpdateContentGroup; import org.agorava.linkedin.model.UpdateContentPersonActivity; import org.agorava.linkedin.model.UpdateContentRecommendation; import org.agorava.linkedin.model.UpdateContentShare; import org.agorava.linkedin.model.UpdateContentStatus; import org.agorava.linkedin.model.UpdateContentViral; import org.agorava.linkedin.model.UpdateType; import java.io.IOException; import java.lang.reflect.Field; /** * @author Antoine Sabot-Durand */ class LinkedInNetworkUpdateListDeserializer extends JsonDeserializer<LinkedInNetworkUpdate> { @Override public LinkedInNetworkUpdate deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { ObjectMapper mapper = BeanResolver.getInstance().resolve(ObjectMapper.class); jp.setCodec(mapper); JsonNode dataNode = jp.readValueAs(JsonNode.class); if (dataNode != null) { LinkedInNetworkUpdate linkedInNetworkUpdate = (LinkedInNetworkUpdate) mapper .reader(new TypeReference<LinkedInNetworkUpdate>() { }).readValue(dataNode); UpdateContent updatedContent = null; UpdateType type = linkedInNetworkUpdate.getUpdateType(); JsonNode updatedNode = dataNode.get("updateContent"); JsonNode person = updatedNode.get("person"); if (type == UpdateType.MSFC) { // Totally different. Looks like a bad API to be honest. person = updatedNode.get("companyPersonUpdate").get("person"); } switch (type) { case CONN: updatedContent = mapper.reader(new TypeReference<UpdateContentConnection>() { }).readValue(person); break; case STAT: updatedContent = mapper.reader(new TypeReference<UpdateContentStatus>() { }).readValue(person); break; case JGRP: updatedContent = mapper.reader(new TypeReference<UpdateContentGroup>() { }).readValue(person); break; case PREC: case SVPR: updatedContent = mapper.reader(new TypeReference<UpdateContentRecommendation>() { }).readValue(person); break; case APPM: updatedContent = mapper.reader(new TypeReference<UpdateContentPersonActivity>() { }).readValue(person); break; case MSFC: updatedContent = mapper.reader(new TypeReference<UpdateContentFollow>() { }).readValue(person); break; case VIRL: updatedContent = mapper.reader(new TypeReference<UpdateContentViral>() { }).readValue(person); break; case SHAR: updatedContent = mapper.reader(new TypeReference<UpdateContentShare>() { }).readValue(person); break; case CMPY: updatedContent = mapper.reader(new TypeReference<UpdateContentCompany>() { }).readValue(updatedNode); break; default: try { updatedContent = mapper.reader(new TypeReference<UpdateContent>() { }).readValue(person); } catch (Exception e) { throw new RuntimeException(e); } } // Need to use reflection to set private updateContent field try { Field f = LinkedInNetworkUpdate.class.getDeclaredField("updateContent"); f.setAccessible(true); f.set(linkedInNetworkUpdate, updatedContent); } catch (Exception e) { throw new RuntimeException(e); } if (type == UpdateType.MSFC) { // Set the action via reflection as it's private String action = updatedNode.get("companyPersonUpdate").get("action").get("code").asText(); try { Field f = UpdateContentFollow.class.getDeclaredField("action"); f.setAccessible(true); f.set(updatedContent, action); } catch (Exception e) { throw new RuntimeException(e); } // Set following via reflection as it's private Company company = mapper.reader(new TypeReference<Company>() { }).readValue(updatedNode.get("company")); try { Field f = UpdateContentFollow.class.getDeclaredField("following"); f.setAccessible(true); f.set(updatedContent, company); } catch (Exception e) { throw new RuntimeException(e); } } else if (type == UpdateType.VIRL) { JsonNode originalUpdate = updatedNode.path("updateAction").path("originalUpdate"); UpdateAction updateAction = mapper.reader(new TypeReference<UpdateAction>() { }).readValue(originalUpdate); String code = updatedNode.path("updateAction").path("action").path("code").textValue(); // Set private immutable field action on updateAction try { Field f = UpdateAction.class.getDeclaredField("action"); f.setAccessible(true); f.set(updateAction, code); } catch (Exception e) { throw new RuntimeException(e); } // Set private immutable field updateAction on updatedContent try { Field f = UpdateContentViral.class.getDeclaredField("updateAction"); f.setAccessible(true); f.set(updatedContent, updateAction); } catch (Exception e) { throw new RuntimeException(e); } } return linkedInNetworkUpdate; } return null; } }