This project has retired. For details please refer to its Attic page.
Source code
001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.reef.tang.implementation.protobuf;
020
021import org.apache.reef.tang.ClassHierarchy;
022import org.apache.reef.tang.exceptions.BindException;
023import org.apache.reef.tang.exceptions.NameResolutionException;
024import org.apache.reef.tang.implementation.Constructor;
025import org.apache.reef.tang.implementation.InjectionPlan;
026import org.apache.reef.tang.implementation.Subplan;
027import org.apache.reef.tang.implementation.java.JavaInstance;
028import org.apache.reef.tang.proto.InjectionPlanProto;
029import org.apache.reef.tang.types.ClassNode;
030import org.apache.reef.tang.types.ConstructorDef;
031import org.apache.reef.tang.types.Node;
032
033import java.util.Arrays;
034import java.util.List;
035
036public class ProtocolBufferInjectionPlan {
037
038  <T> InjectionPlanProto.InjectionPlan newConstructor(final String fullName,
039                                                      final List<InjectionPlanProto.InjectionPlan> plans) {
040    return InjectionPlanProto.InjectionPlan
041        .newBuilder()
042        .setName(fullName)
043        .setConstructor(
044            InjectionPlanProto.Constructor.newBuilder().addAllArgs(plans)
045                .build()).build();
046  }
047
048  <T> InjectionPlanProto.InjectionPlan newSubplan(final String fullName,
049                                                  final int selectedPlan,
050                                                  final List<InjectionPlanProto.InjectionPlan> plans) {
051    return InjectionPlanProto.InjectionPlan
052        .newBuilder()
053        .setName(fullName)
054        .setSubplan(
055            InjectionPlanProto.Subplan.newBuilder()
056                .setSelectedPlan(selectedPlan).addAllPlans(plans).build())
057        .build();
058  }
059
060  <T> InjectionPlanProto.InjectionPlan newInstance(final String fullName,
061                                                   final String value) {
062    return InjectionPlanProto.InjectionPlan.newBuilder().setName(fullName)
063        .setInstance(InjectionPlanProto.Instance.newBuilder().setValue(value))
064        .build();
065  }
066
067  public <T> InjectionPlanProto.InjectionPlan serialize(final InjectionPlan<T> ip) {
068    if (ip instanceof Constructor) {
069      final Constructor<T> cons = (Constructor<T>) ip;
070      final InjectionPlan<?>[] args = cons.getArgs();
071      final InjectionPlanProto.InjectionPlan[] protoArgs = new InjectionPlanProto.InjectionPlan[args.length];
072      for (int i = 0; i < args.length; i++) {
073        protoArgs[i] = serialize(args[i]);
074      }
075      return newConstructor(ip.getNode().getFullName(),
076          Arrays.asList(protoArgs));
077    } else if (ip instanceof Subplan) {
078      final Subplan<T> sp = (Subplan<T>) ip;
079      final InjectionPlan<?>[] args = sp.getPlans();
080      final InjectionPlanProto.InjectionPlan[] subPlans = new InjectionPlanProto.InjectionPlan[args.length];
081      for (int i = 0; i < args.length; i++) {
082        subPlans[i] = serialize(args[i]);
083      }
084      return newSubplan(ip.getNode().getFullName(), sp.getSelectedIndex(),
085          Arrays.asList(subPlans));
086    } else if (ip instanceof JavaInstance) {
087      final JavaInstance<T> ji = (JavaInstance<T>) ip;
088      return newInstance(ip.getNode().getFullName(), ji.getInstanceAsString());
089    } else {
090      throw new IllegalStateException(
091          "Encountered unknown type of InjectionPlan: " + ip);
092    }
093  }
094
095  private Object parse(final String type, final String value) {
096    // XXX this is a placeholder for now.  We need a parser API that will
097    // either produce a live java object or (partially) validate stuff to
098    // see if it looks like the target language will be able to handle this
099    // type + value.
100    return value;
101  }
102
103  @SuppressWarnings("unchecked")
104  public <T> InjectionPlan<T> deserialize(final ClassHierarchy ch,
105                                          final InjectionPlanProto.InjectionPlan ip) throws NameResolutionException,
106      BindException {
107    final String fullName = ip.getName();
108    if (ip.hasConstructor()) {
109      final InjectionPlanProto.Constructor cons = ip.getConstructor();
110
111      final ClassNode<T> cn = (ClassNode<T>) ch.getNode(fullName);
112
113      final InjectionPlanProto.InjectionPlan[] protoBufArgs = cons
114          .getArgsList().toArray(new InjectionPlanProto.InjectionPlan[0]);
115      final ClassNode<?>[] cnArgs = new ClassNode[protoBufArgs.length];
116
117      for (int i = 0; i < protoBufArgs.length; i++) {
118        cnArgs[i] = (ClassNode<?>) ch.getNode(protoBufArgs[i].getName());
119      }
120
121      final InjectionPlan<?>[] ipArgs = new InjectionPlan[protoBufArgs.length];
122
123      for (int i = 0; i < protoBufArgs.length; i++) {
124        ipArgs[i] = deserialize(ch, protoBufArgs[i]);
125      }
126
127      final ConstructorDef<T> constructor = cn.getConstructorDef(cnArgs);
128      return new Constructor<T>(cn, constructor, ipArgs);
129    } else if (ip.hasInstance()) {
130      final InjectionPlanProto.Instance ins = ip.getInstance();
131      final T instance = (T) parse(ip.getName(), ins.getValue());
132      return new JavaInstance<T>(ch.getNode(ip.getName()), instance);
133    } else if (ip.hasSubplan()) {
134      final InjectionPlanProto.Subplan subplan = ip.getSubplan();
135      final InjectionPlanProto.InjectionPlan[] protoBufPlans = subplan
136          .getPlansList().toArray(new InjectionPlanProto.InjectionPlan[0]);
137
138      final InjectionPlan<T>[] subPlans = new InjectionPlan[protoBufPlans.length];
139      for (int i = 0; i < protoBufPlans.length; i++) {
140        subPlans[i] = deserialize(ch, protoBufPlans[i]);
141      }
142      final Node n = ch.getNode(fullName);
143      return new Subplan<T>(n, subPlans);
144    } else {
145      throw new IllegalStateException(
146          "Encountered unknown type of injection plan: " + ip);
147    }
148  }
149}