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                                                      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                                                  int selectedPlan, List<InjectionPlanProto.InjectionPlan> plans) {
050    return InjectionPlanProto.InjectionPlan
051        .newBuilder()
052        .setName(fullName)
053        .setSubplan(
054            InjectionPlanProto.Subplan.newBuilder()
055                .setSelectedPlan(selectedPlan).addAllPlans(plans).build())
056        .build();
057  }
058
059  <T> InjectionPlanProto.InjectionPlan newInstance(final String fullName,
060                                                   final String value) {
061    return InjectionPlanProto.InjectionPlan.newBuilder().setName(fullName)
062        .setInstance(InjectionPlanProto.Instance.newBuilder().setValue(value))
063        .build();
064  }
065
066  public <T> InjectionPlanProto.InjectionPlan serialize(InjectionPlan<T> ip) {
067    if (ip instanceof Constructor) {
068      Constructor<T> cons = (Constructor<T>) ip;
069      InjectionPlan<?>[] args = cons.getArgs();
070      InjectionPlanProto.InjectionPlan[] protoArgs = new InjectionPlanProto.InjectionPlan[args.length];
071      for (int i = 0; i < args.length; i++) {
072        protoArgs[i] = serialize(args[i]);
073      }
074      return newConstructor(ip.getNode().getFullName(),
075          Arrays.asList(protoArgs));
076    } else if (ip instanceof Subplan) {
077      Subplan<T> sp = (Subplan<T>) ip;
078      InjectionPlan<?>[] args = sp.getPlans();
079      InjectionPlanProto.InjectionPlan[] subPlans = new InjectionPlanProto.InjectionPlan[args.length];
080      for (int i = 0; i < args.length; i++) {
081        subPlans[i] = serialize(args[i]);
082      }
083      return newSubplan(ip.getNode().getFullName(), sp.getSelectedIndex(),
084          Arrays.asList(subPlans));
085    } else if (ip instanceof JavaInstance) {
086      JavaInstance<T> ji = (JavaInstance<T>) ip;
087      return newInstance(ip.getNode().getFullName(), ji.getInstanceAsString());
088    } else {
089      throw new IllegalStateException(
090          "Encountered unknown type of InjectionPlan: " + ip);
091    }
092  }
093
094  private Object parse(String type, String value) {
095    // XXX this is a placeholder for now.  We need a parser API that will
096    // either produce a live java object or (partially) validate stuff to
097    // see if it looks like the target language will be able to handle this
098    // type + value.
099    return value;
100  }
101
102  @SuppressWarnings("unchecked")
103  public <T> InjectionPlan<T> deserialize(ClassHierarchy ch,
104                                          InjectionPlanProto.InjectionPlan ip) throws NameResolutionException,
105      BindException {
106    final String fullName = ip.getName();
107    if (ip.hasConstructor()) {
108      final InjectionPlanProto.Constructor cons = ip.getConstructor();
109
110      final ClassNode<T> cn = (ClassNode<T>) ch.getNode(fullName);
111
112      final InjectionPlanProto.InjectionPlan protoBufArgs[] = cons
113          .getArgsList().toArray(new InjectionPlanProto.InjectionPlan[0]);
114      final ClassNode<?>[] cnArgs = new ClassNode[protoBufArgs.length];
115
116      for (int i = 0; i < protoBufArgs.length; i++) {
117        cnArgs[i] = (ClassNode<?>) ch.getNode(protoBufArgs[i].getName());
118      }
119
120      final InjectionPlan<?> ipArgs[] = new InjectionPlan[protoBufArgs.length];
121
122      for (int i = 0; i < protoBufArgs.length; i++) {
123        ipArgs[i] = (InjectionPlan<?>) deserialize(ch, protoBufArgs[i]);
124      }
125
126      final ConstructorDef<T> constructor = cn.getConstructorDef(cnArgs);
127      return new Constructor<T>(cn, constructor, ipArgs);
128    } else if (ip.hasInstance()) {
129      InjectionPlanProto.Instance ins = ip.getInstance();
130      T instance = (T) parse(ip.getName(), ins.getValue());
131      return new JavaInstance<T>(ch.getNode(ip.getName()), instance);
132    } else if (ip.hasSubplan()) {
133      final InjectionPlanProto.Subplan subplan = ip.getSubplan();
134      final InjectionPlanProto.InjectionPlan protoBufPlans[] = subplan
135          .getPlansList().toArray(new InjectionPlanProto.InjectionPlan[0]);
136
137      final InjectionPlan<T> subPlans[] = new InjectionPlan[protoBufPlans.length];
138      for (int i = 0; i < protoBufPlans.length; i++) {
139        subPlans[i] = (InjectionPlan<T>) deserialize(ch, protoBufPlans[i]);
140      }
141      Node n = ch.getNode(fullName);
142      return new Subplan<T>(n, subPlans);
143    } else {
144      throw new IllegalStateException(
145          "Encountered unknown type of injection plan: " + ip);
146    }
147  }
148}