blob: 0f2f5fb99d4b92cf44e73fafae5393e8a5818a0d [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Org.Apache.REEF.Tang.Exceptions;
using Org.Apache.REEF.Tang.Implementations.InjectionPlan;
using Org.Apache.REEF.Tang.Interface;
using Org.Apache.REEF.Tang.Types;
using Org.Apache.REEF.Utilities.Logging;
using ProtoBuf;
namespace Org.Apache.REEF.Tang.Protobuf
{
internal sealed class ProtocolBufferInjectionPlan
{
private static readonly Logger LOGGER = Logger.GetLogger(typeof(ProtocolBufferInjectionPlan));
private static InjectionPlan NewConstructor(string fullName, List<InjectionPlan> plans)
{
Constructor cconstr = new Constructor();
foreach (InjectionPlan p in plans)
{
cconstr.args.Add(p);
}
InjectionPlan plan = new InjectionPlan();
plan.name = fullName;
plan.constructor = cconstr;
return plan;
}
private static InjectionPlan NewSubplan(string fullName, int selectedPlan, List<InjectionPlan> plans)
{
Subplan subPlan = new Subplan();
subPlan.selected_plan = selectedPlan;
foreach (InjectionPlan p in plans)
{
subPlan.plans.Add(p);
}
InjectionPlan plan = new InjectionPlan();
plan.name = fullName;
plan.subplan = subPlan;
return plan;
}
private static InjectionPlan NewInstance(string fullName, string value)
{
Instance instance = new Instance();
instance.value = value;
InjectionPlan plan = new InjectionPlan();
plan.name = fullName;
plan.instance = instance;
return plan;
}
public static void Serialize(string fileName, Implementations.InjectionPlan.InjectionPlan ip)
{
InjectionPlan plan = Serialize(ip);
using (var file = File.Create(fileName))
{
Serializer.Serialize<InjectionPlan>(file, plan);
}
}
public static InjectionPlan Serialize(Implementations.InjectionPlan.InjectionPlan ip)
{
if (ip is Implementations.InjectionPlan.Constructor)
{
Implementations.InjectionPlan.Constructor cons = (Implementations.InjectionPlan.Constructor)ip;
Implementations.InjectionPlan.InjectionPlan[] args = cons.GetArgs();
InjectionPlan[] protoArgs = new InjectionPlan[args.Length];
for (int i = 0; i < args.Length; i++)
{
protoArgs[i] = Serialize(args[i]);
}
return NewConstructor(ip.GetNode().GetFullName(), protoArgs.ToList<InjectionPlan>());
}
if (ip is Implementations.InjectionPlan.Subplan)
{
Implementations.InjectionPlan.Subplan sp = (Implementations.InjectionPlan.Subplan)ip;
Implementations.InjectionPlan.InjectionPlan[] args = sp.GetPlans();
InjectionPlan[] subPlans = new InjectionPlan[args.Length];
for (int i = 0; i < args.Length; i++)
{
subPlans[i] = Serialize(args[i]);
}
return NewSubplan(ip.GetNode().GetFullName(), sp.GetSelectedIndex(), subPlans.ToList<InjectionPlan>());
}
if (ip is CsInstance)
{
CsInstance ji = (CsInstance)ip;
return NewInstance(ip.GetNode().GetFullName(), ji.GetInstanceAsString());
}
Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException(
"Encountered unknown type of InjectionPlan: " + ip), LOGGER);
return null;
}
public static Implementations.InjectionPlan.InjectionPlan DeSerialize(string fileName, IClassHierarchy ch)
{
InjectionPlan protoPlan;
using (var file = File.OpenRead(fileName))
{
protoPlan = Serializer.Deserialize<InjectionPlan>(file);
}
return Deserialize(ch, protoPlan);
}
public static Implementations.InjectionPlan.InjectionPlan Deserialize(IClassHierarchy ch, InjectionPlan ip)
{
string fullName = ip.name;
if (ip.constructor != null)
{
Constructor cons = ip.constructor;
IClassNode cn = (IClassNode)ch.GetNode(fullName);
InjectionPlan[] protoBufArgs = cons.args.ToArray();
IClassNode[] cnArgs = new IClassNode[protoBufArgs.Length];
for (int i = 0; i < protoBufArgs.Length; i++)
{
INode no = ch.GetNode(protoBufArgs[i].name);
if (no is IClassNode)
{
cnArgs[i] = (IClassNode)no;
}
else if (no is INamedParameterNode)
{
INamedParameterNode np = (INamedParameterNode)no;
cnArgs[i] = (IClassNode)ch.GetNode(np.GetFullArgName());
}
}
Implementations.InjectionPlan.InjectionPlan[] ipArgs = new Implementations.InjectionPlan.InjectionPlan[protoBufArgs.Length];
for (int i = 0; i < protoBufArgs.Length; i++)
{
ipArgs[i] = (Implementations.InjectionPlan.InjectionPlan)Deserialize(ch, protoBufArgs[i]);
}
IConstructorDef constructor = cn.GetConstructorDef(cnArgs);
return new Implementations.InjectionPlan.Constructor(cn, constructor, ipArgs);
}
if (ip.instance != null)
{
Instance ins = ip.instance;
object instance = Parse(ip.name, ins.value);
return new CsInstance(ch.GetNode(ip.name), instance);
}
if (ip.subplan != null)
{
Subplan subplan = ip.subplan;
InjectionPlan[] protoBufPlans = subplan.plans.ToArray();
Implementations.InjectionPlan.InjectionPlan[] subPlans = new Implementations.InjectionPlan.InjectionPlan[protoBufPlans.Length];
for (int i = 0; i < protoBufPlans.Length; i++)
{
subPlans[i] = (Implementations.InjectionPlan.InjectionPlan)Deserialize(ch, protoBufPlans[i]);
}
INode n = ch.GetNode(fullName);
return new Implementations.InjectionPlan.Subplan(n, subPlans);
}
Org.Apache.REEF.Utilities.Diagnostics.Exceptions.Throw(new IllegalStateException("Encountered unknown type of InjectionPlan: " + ip), LOGGER);
return null;
}
private static object Parse(string type, string value)
{
// XXX this is a placeholder for now. We need a parser API that will
// either produce a live java object or (partially) validate stuff to
// see if it looks like the target language will be able to handle this
// type + value.
return value;
}
}
}