// Path: src/main/java/org/calrissian/flowmix/api/Policy.java
// public enum Policy implements Serializable {
// 
//     COUNT, TIME, TIME_DELTA_LT
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/FlowOp.java
// public interface FlowOp extends Serializable {
// 
//     String getComponentName();
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/JoinOp.java
// public class JoinOp implements FlowOp, RequiresPartitioning {
// 
//     public static final String JOIN = "join";
// 
//     String leftStream;
//     String rightStream;
// 
//     Policy evictionPolicy;
//     long evictionThreshold;
// 
//     public JoinOp(String leftStream, String rightStream, Policy evictionPolicy, long evictionThreshold) {
//         this.leftStream = leftStream;
//         this.rightStream = rightStream;
//         this.evictionPolicy = evictionPolicy;
//         this.evictionThreshold = evictionThreshold;
//     }
// 
//     public String getLeftStream() {
//         return leftStream;
//     }
// 
//     public String getRightStream() {
//         return rightStream;
//     }
// 
//     public Policy getEvictionPolicy() {
//         return evictionPolicy;
//     }
// 
//     public long getEvictionThreshold() {
//         return evictionThreshold;
//     }
// 
//     @Override
//     public String getComponentName() {
//         return "join";
//     }
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/PartitionOp.java
// public class PartitionOp implements FlowOp {
// 
//   public static final String PARTITION = "partition";
//   private List<String> fields;
// 
//   public PartitionOp(List<String> fields) {
//       this.fields = fields;
//   }
// 
//   public List<String> getFields() {
//       return fields;
//   }
// 
//   @Override
//   public String getComponentName() {
//       return PARTITION;
//   }
// 
//   @Override
//   public String toString() {
//     return "PartitionOp{" +
//             "fields=" + fields +
//             '}';
//   }
// }


import java.util.List;
import org.calrissian.flowmix.api.Policy;
import org.calrissian.flowmix.core.model.op.FlowOp;
import org.calrissian.flowmix.core.model.op.JoinOp;
import org.calrissian.flowmix.core.model.op.PartitionOp;
import static java.util.Collections.EMPTY_LIST;
/*
 * Copyright (C) 2014 The Calrissian 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.calrissian.flowmix.api.builder;





public class JoinBuilder extends AbstractOpBuilder{

    String lhs;
    String rhs;

    Policy evictionPolicy;
    long evictionThreshold = -1;

    public JoinBuilder(StreamBuilder streamBuilder, String lhs, String rhs) {
        super(streamBuilder);
        this.lhs = lhs;
        this.rhs = rhs;
    }

    public JoinBuilder evict(Policy policy, long threshold) {
        this.evictionPolicy = policy;
        this.evictionThreshold = threshold;
        return this;
    }

    @Override
    public StreamBuilder end() {

        if(evictionPolicy == null || evictionThreshold == -1)
            throw new RuntimeException("Eviction policy is required by the join operator");

        if(lhs == null || rhs == null)
            throw new RuntimeException("Left and right side streams required by the join operator");

      List<FlowOp> flowOpList = getStreamBuilder().getFlowOpList();
      FlowOp op = flowOpList.size() == 0 ? null : flowOpList.get(flowOpList.size()-1);
// Path: src/main/java/org/calrissian/flowmix/api/Policy.java
// public enum Policy implements Serializable {
// 
//     COUNT, TIME, TIME_DELTA_LT
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/FlowOp.java
// public interface FlowOp extends Serializable {
// 
//     String getComponentName();
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/JoinOp.java
// public class JoinOp implements FlowOp, RequiresPartitioning {
// 
//     public static final String JOIN = "join";
// 
//     String leftStream;
//     String rightStream;
// 
//     Policy evictionPolicy;
//     long evictionThreshold;
// 
//     public JoinOp(String leftStream, String rightStream, Policy evictionPolicy, long evictionThreshold) {
//         this.leftStream = leftStream;
//         this.rightStream = rightStream;
//         this.evictionPolicy = evictionPolicy;
//         this.evictionThreshold = evictionThreshold;
//     }
// 
//     public String getLeftStream() {
//         return leftStream;
//     }
// 
//     public String getRightStream() {
//         return rightStream;
//     }
// 
//     public Policy getEvictionPolicy() {
//         return evictionPolicy;
//     }
// 
//     public long getEvictionThreshold() {
//         return evictionThreshold;
//     }
// 
//     @Override
//     public String getComponentName() {
//         return "join";
//     }
// }
// 
// Path: src/main/java/org/calrissian/flowmix/core/model/op/PartitionOp.java
// public class PartitionOp implements FlowOp {
// 
//   public static final String PARTITION = "partition";
//   private List<String> fields;
// 
//   public PartitionOp(List<String> fields) {
//       this.fields = fields;
//   }
// 
//   public List<String> getFields() {
//       return fields;
//   }
// 
//   @Override
//   public String getComponentName() {
//       return PARTITION;
//   }
// 
//   @Override
//   public String toString() {
//     return "PartitionOp{" +
//             "fields=" + fields +
//             '}';
//   }
// }


// Path: src/main/java/org/calrissian/flowmix/api/builder/JoinBuilder.java
import java.util.List;
import org.calrissian.flowmix.api.Policy;
import org.calrissian.flowmix.core.model.op.FlowOp;
import org.calrissian.flowmix.core.model.op.JoinOp;
import org.calrissian.flowmix.core.model.op.PartitionOp;
import static java.util.Collections.EMPTY_LIST;

/*
 * Copyright (C) 2014 The Calrissian 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.calrissian.flowmix.api.builder;





public class JoinBuilder extends AbstractOpBuilder{

    String lhs;
    String rhs;

    Policy evictionPolicy;
    long evictionThreshold = -1;

    public JoinBuilder(StreamBuilder streamBuilder, String lhs, String rhs) {
        super(streamBuilder);
        this.lhs = lhs;
        this.rhs = rhs;
    }

    public JoinBuilder evict(Policy policy, long threshold) {
        this.evictionPolicy = policy;
        this.evictionThreshold = threshold;
        return this;
    }

    @Override
    public StreamBuilder end() {

        if(evictionPolicy == null || evictionThreshold == -1)
            throw new RuntimeException("Eviction policy is required by the join operator");

        if(lhs == null || rhs == null)
            throw new RuntimeException("Left and right side streams required by the join operator");

      List<FlowOp> flowOpList = getStreamBuilder().getFlowOpList();
      FlowOp op = flowOpList.size() == 0 ? null : flowOpList.get(flowOpList.size()-1);
      if(op == null || !(op instanceof PartitionOp))