/* * Copyright 2004-2009 the original author or authors. * * 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.compass.core.converter.mapping.json; import java.lang.reflect.Array; import org.compass.core.Property; import org.compass.core.Resource; import org.compass.core.ResourceFactory; import org.compass.core.config.CompassEnvironment; import org.compass.core.converter.ConversionException; import org.compass.core.converter.json.JsonFullPathHolder; import org.compass.core.converter.mapping.ResourceMappingConverter; import org.compass.core.json.JsonObject; import org.compass.core.json.RawJsonObject; import org.compass.core.mapping.Mapping; import org.compass.core.mapping.ResourceMapping; import org.compass.core.mapping.json.JsonContentMapping; import org.compass.core.mapping.json.RootJsonObjectMapping; import org.compass.core.marshall.MarshallingContext; import org.compass.core.spi.InternalResource; /** * @author kimchy */ public class RootJsonObjectMappingConverter extends AbstractJsonObjectMappingConverter implements ResourceMappingConverter { public boolean marshall(Resource resource, Object root, Mapping mapping, MarshallingContext context) throws ConversionException { // no need to marshall if it is null if (root == null && !context.handleNulls()) { return false; } if (root instanceof Resource) { Resource rootResource = (Resource) root; resource.copy(rootResource); ((InternalResource) resource).addUID(); return true; } RootJsonObjectMapping jsonObjectMapping = (RootJsonObjectMapping) mapping; JsonObject jsonObject = (JsonObject) root; jsonObject = getActualJsonObject(jsonObject, jsonObjectMapping, context, resource); // initialize full path JsonFullPathHolder fullPathHolder = new JsonFullPathHolder(); context.setAttribute(JsonFullPathHolder.CONTEXT_KEY, fullPathHolder); boolean store = doMarshall(resource, jsonObject, jsonObjectMapping, context); JsonContentMapping contentMapping = jsonObjectMapping.getContentMapping(); if (contentMapping != null) { Object content = jsonObject; if (root instanceof RawJsonObject) { content = ((RawJsonObject) root).getJson(); } contentMapping.getConverter().marshall(resource, content, contentMapping, context); } ((InternalResource) resource).addUID(); return store; } public Object unmarshall(Resource resource, Mapping mapping, MarshallingContext context) throws ConversionException { RootJsonObjectMapping jsonObjectMapping = (RootJsonObjectMapping) mapping; if (jsonObjectMapping.getContentMapping() == null) { return null; } JsonContentMapping contentMapping = jsonObjectMapping.getContentMapping(); return contentMapping.getConverter().unmarshall(resource, contentMapping, context); } public boolean marshallIds(Resource idResource, Object id, ResourceMapping resourceMapping, MarshallingContext context) throws ConversionException { ResourceFactory resourceFactory = context.getResourceFactory(); RootJsonObjectMapping jsonObjectMapping = (RootJsonObjectMapping) resourceMapping; Mapping[] ids = resourceMapping.getIdMappings(); if (id instanceof JsonObject) { JsonObject jsonObject = getActualJsonObject((JsonObject) id, jsonObjectMapping, context, idResource); for (Mapping id1 : ids) { Object value = jsonObject.opt(id1.getName()); if (jsonObject.isNullValue(value)) { throw new ConversionException("Trying to load resource with id name [" + id1.getName() + "] null"); } id1.getConverter().marshall(idResource, value, id1, context); } } else if (id instanceof Resource) { for (Mapping id1 : ids) { Resource rId = (Resource) id; idResource.addProperty(rId.getProperty(id1.getPath().getPath())); } } else if (id instanceof Object[]) { if (Array.getLength(id) != ids.length) { throw new ConversionException("Trying to load resource with [" + Array.getLength(id) + "] while has ids mappings of [" + ids.length + "]"); } if (Property.class.isAssignableFrom(id.getClass().getComponentType())) { for (int i = 0; i < ids.length; i++) { idResource.addProperty((Property) Array.get(id, i)); } } else { for (int i = 0; i < ids.length; i++) { idResource.addProperty(resourceFactory.createProperty(ids[i].getPath().getPath(), Array.get(id, i).toString(), Property.Store.YES, Property.Index.NOT_ANALYZED)); } } } else { if (ids.length != 1) { throw new ConversionException( "Trying to load resource which has more than one id mappings with only one id value"); } if (id instanceof Property) { idResource.addProperty((Property) id); } else { idResource.addProperty(resourceFactory.createProperty(ids[0].getPath().getPath(), id.toString(), Property.Store.YES, Property.Index.NOT_ANALYZED)); } } ((InternalResource) idResource).addUID(); return true; } public Object[] unmarshallIds(Object id, ResourceMapping resourceMapping, MarshallingContext context) throws ConversionException { throw new ConversionException("Not supported, please use json-content mapping"); } private JsonObject getActualJsonObject(JsonObject jsonObject, RootJsonObjectMapping jsonObjectMapping, MarshallingContext context, Resource resource) { // in case it is an xml string value, convert it into an xml object if (jsonObject instanceof RawJsonObject) { String json = ((RawJsonObject) jsonObject).getJson(); JsonContentMapping jsonContentMapping = jsonObjectMapping.getContentMapping(); JsonContentMappingConverter jsonContentMappingConverter; if (jsonContentMapping != null) { jsonContentMappingConverter = (JsonContentMappingConverter) jsonContentMapping.getConverter(); } else { jsonContentMappingConverter = (JsonContentMappingConverter) context.getConverterLookup(). lookupConverter(CompassEnvironment.Converter.DefaultTypeNames.Mapping.JSON_CONTENT_MAPPING); } jsonObject = jsonContentMappingConverter.getContentConverter().fromJSON(resource.getAlias(), json); } return jsonObject; } }