Java tutorial
/** * Copyright 2013 Cloudera Inc. * * 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 com.cloudera.cdk.data; import com.cloudera.cdk.data.partition.DayOfMonthFieldPartitioner; import com.cloudera.cdk.data.partition.HashFieldPartitioner; import com.cloudera.cdk.data.partition.HourFieldPartitioner; import com.cloudera.cdk.data.partition.IdentityFieldPartitioner; import com.cloudera.cdk.data.partition.MinuteFieldPartitioner; import com.cloudera.cdk.data.partition.MonthFieldPartitioner; import com.cloudera.cdk.data.partition.PartitionFunctions; import com.cloudera.cdk.data.partition.RangeFieldPartitioner; import com.cloudera.cdk.data.partition.YearFieldPartitioner; import com.google.common.annotations.Beta; import com.google.common.base.Objects; import com.google.common.collect.Lists; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.jexl2.Expression; import org.apache.commons.jexl2.JexlEngine; /** * Internal utility class for persisting partition strategies, * not a part of the public API. */ @Beta class PartitionExpression { private JexlEngine engine; private Expression expression; private boolean isStrict; public PartitionExpression(String expression, boolean isStrict) { this.engine = new JexlEngine(); Map<String, Object> fns = new HashMap<String, Object>(); fns.put(null, PartitionFunctions.class); this.engine.setFunctions(fns); this.engine.setStrict(true); this.engine.setSilent(false); this.engine.setCache(10); this.expression = engine.createExpression(expression); this.isStrict = isStrict; } @SuppressWarnings("deprecation") public PartitionStrategy evaluate() { Object object = expression.evaluate(null); if (object instanceof FieldPartitioner) { return new PartitionStrategy((FieldPartitioner) object); } else if (object instanceof Object[]) { /* * JEXL doesn't recognize that [hash(...), range(...)] is an array of * FieldPartitioner. Instead, it thinks it's Object[]. */ List<FieldPartitioner> partitioners = Lists.newArrayList(); for (Object o : ((Object[]) object)) { partitioners.add((FieldPartitioner) o); } return new PartitionStrategy(partitioners); } else { throw new IllegalArgumentException( "Partition expression did not produce FieldPartitioner result (or array) for value:" + object); } } /** * Convert a PartitionStrategy into a serialized expression. This can be used * to set a PartitionStrategy in an Avro property if the PartitionStrategy is * passed as an object. */ public static String toExpression(PartitionStrategy partitionStrategy) { List<FieldPartitioner> fieldPartitioners = partitionStrategy.getFieldPartitioners(); if (fieldPartitioners.size() == 1) { return toExpression(fieldPartitioners.get(0)); } StringBuilder sb = new StringBuilder(); sb.append("["); for (FieldPartitioner fieldPartitioner : fieldPartitioners) { if (sb.length() > 1) { sb.append(", "); } sb.append(toExpression(fieldPartitioner)); } sb.append("]"); return sb.toString(); } private static String toExpression(FieldPartitioner fieldPartitioner) { // TODO: add other strategies if (fieldPartitioner instanceof HashFieldPartitioner) { return String.format("hash(\"%s\", \"%s\", %s)", fieldPartitioner.getSourceName(), fieldPartitioner.getName(), fieldPartitioner.getCardinality()); } else if (fieldPartitioner instanceof IdentityFieldPartitioner) { return String.format("identity(\"%s\", %s)", fieldPartitioner.getName(), fieldPartitioner.getCardinality()); } else if (fieldPartitioner instanceof RangeFieldPartitioner) { List<String> upperBounds = ((RangeFieldPartitioner) fieldPartitioner).getUpperBounds(); StringBuilder builder = new StringBuilder(); for (String bound : upperBounds) { if (builder.length() > 0) { builder.append(", "); } builder.append("\"").append(bound).append("\""); } return String.format("range(\"%s\", %s", fieldPartitioner.getName(), builder.toString()); } else if (fieldPartitioner instanceof YearFieldPartitioner) { return String.format("year(\"%s\", \"%s\")", fieldPartitioner.getSourceName(), fieldPartitioner.getName()); } else if (fieldPartitioner instanceof MonthFieldPartitioner) { return String.format("month(\"%s\", \"%s\")", fieldPartitioner.getSourceName(), fieldPartitioner.getName()); } else if (fieldPartitioner instanceof DayOfMonthFieldPartitioner) { return String.format("day(\"%s\", \"%s\")", fieldPartitioner.getSourceName(), fieldPartitioner.getName()); } else if (fieldPartitioner instanceof HourFieldPartitioner) { return String.format("hour(\"%s\", \"%s\")", fieldPartitioner.getSourceName(), fieldPartitioner.getName()); } else if (fieldPartitioner instanceof MinuteFieldPartitioner) { return String.format("minute(\"%s\", \"%s\")", fieldPartitioner.getSourceName(), fieldPartitioner.getName()); } throw new IllegalArgumentException("Unrecognized PartitionStrategy: " + fieldPartitioner); } @Override public String toString() { return Objects.toStringHelper(this).add("expression", expression).add("isStrict", isStrict) .add("engine", engine).toString(); } }