/* * Copyright 2016 Christoph Böhme * * 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.culturegraph.mf.javaintegration.pojo; import java.beans.PropertyEditor; import java.beans.PropertyEditorManager; import java.util.ArrayDeque; import java.util.Deque; import org.culturegraph.mf.framework.FluxCommand; import org.culturegraph.mf.framework.ObjectReceiver; import org.culturegraph.mf.framework.StreamReceiver; import org.culturegraph.mf.framework.annotations.Description; import org.culturegraph.mf.framework.annotations.In; import org.culturegraph.mf.framework.annotations.Out; import org.culturegraph.mf.framework.helpers.DefaultStreamPipe; /** * Creates and fills a new object instance with stream data and sends the result * to the given object receiver. * * @param <T> The type of the object to create. * @author Thomas Seidel */ @Description("Creates a pojo (Plain Old Java Object) based on a record containing the member values") @In(StreamReceiver.class) @Out(Object.class) @FluxCommand("encode-pojo") public class PojoEncoder<T> extends DefaultStreamPipe<ObjectReceiver<T>> { static { // Initialize the property manager to map the primitive data types to // the corresponding object based types, e.g. int to Integer PropertyEditorManager.registerEditor(Boolean.class, PropertyEditorManager.findEditor(boolean.class).getClass()); PropertyEditorManager.registerEditor(Integer.class, PropertyEditorManager.findEditor(int.class).getClass()); PropertyEditorManager.registerEditor(Long.class, PropertyEditorManager .findEditor(long.class).getClass()); } private final TypeEncoderFactory typeEncoderFactory = new TypeEncoderFactory(); private final Deque<TypeEncoder> typeEncoderStack = new ArrayDeque<>(); private final Class<T> pojoClass; public PojoEncoder(final Class<T> pojoClass) { this.pojoClass = pojoClass; } @Override public void startRecord(final String identifier) { typeEncoderStack.clear(); typeEncoderStack.push(new ComplexTypeEncoder(pojoClass)); } @Override public void endRecord() { assert typeEncoderStack.size() == 1; @SuppressWarnings("unchecked") final T instance = (T) typeEncoderStack.peek().getInstance(); getReceiver().process(instance); typeEncoderStack.clear(); } @Override public void startEntity(final String name) { final TypeEncoder currentTypeEncoder = typeEncoderStack.peek(); final ValueType newType = currentTypeEncoder.getValueType(name); final TypeEncoder newTypeEncoder = typeEncoderFactory.create(newType); currentTypeEncoder.setValue(name, newTypeEncoder.getInstance()); typeEncoderStack.push(newTypeEncoder); } @Override public void endEntity() { typeEncoderStack.pop(); } @Override public void literal(final String name, final String value) { final TypeEncoder currentTypeEncoder = typeEncoderStack.peek(); final Class<?> targetType = currentTypeEncoder.getValueType(name) .getRawClass(); currentTypeEncoder.setValue(name, createObjectFromString(value, targetType)); } private static Object createObjectFromString(final String value, final Class<?> targetType) { final PropertyEditor propertyEditor = PropertyEditorManager .findEditor(targetType); propertyEditor.setAsText(value); return propertyEditor.getValue(); } @Override public void onCloseStream() { typeEncoderStack.clear(); } @Override public void onResetStream() { typeEncoderStack.clear(); } }