http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/logging/SimpleOneLineLogFormatter.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/logging/SimpleOneLineLogFormatter.java b/utils/common/src/main/java/brooklyn/util/logging/SimpleOneLineLogFormatter.java deleted file mode 100644 index 19ca7e6..0000000 --- a/utils/common/src/main/java/brooklyn/util/logging/SimpleOneLineLogFormatter.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.logging; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.logging.Formatter; -import java.util.logging.Level; -import java.util.logging.LogRecord; - -import com.google.common.base.Throwables; - -//useful for java.util.logger, which by default puts every message on two lines (horrid) -//however we don't typically use java.util.logger... -public class SimpleOneLineLogFormatter extends Formatter { - - public SimpleOneLineLogFormatter() { - this(true, false, false); - } - - public SimpleOneLineLogFormatter(boolean showLevel, boolean showThread, boolean showCaller) { - this.showLevel = showLevel; - this.showThread = showThread; - this.showCaller = showCaller; - } - - - public final boolean showLevel; - public final boolean showThread; - public final boolean showCaller; - - // use shared date and formatter to minimize memory/time overhead - protected final Date date = new Date(); - protected DateFormat dateFormat = new SimpleDateFormat(getDateFormat()); - - public String getDateFormat() { - return "yyyy-MM-dd HH:mm:ss.SSSZ"; - } - - /** uses "YYYY-DD-MM hh:mm:ss.SSS message" format */ - public String format(LogRecord record) { - StringBuffer sb = new StringBuffer(); - appendDate(record, sb); - appendLevel(record, sb); - sb.append(" "); - sb.append(formatMessage(record)); - appendThreadAndCaller(record, sb); - appendDetailsWithNewLine(sb, record); - return sb.toString(); - } - - protected void appendLevel(LogRecord record, StringBuffer sb) { - if (showLevel) { - sb.append(" [").append(record.getLevel()).append("]"); - } - } - - protected void appendDate(LogRecord record, StringBuffer sb) { - synchronized (date) { - date.setTime(record.getMillis()); - sb.append(dateFormat.format(date)); - } - } - - protected void appendThreadAndCaller(LogRecord record, StringBuffer sb) { - if (showThread || showCaller) { - sb.append(" ["); - if (showThread) - sb.append(getThreadName(record)); - if (showThread && showCaller) sb.append(", "); - if (showCaller) { - if (record.getSourceClassName() != null) { - sb.append(record.getSourceClassName()); - } else { - sb.append(record.getLoggerName()); - } - if (record.getSourceMethodName() != null) { - sb.append(" "); - sb.append(record.getSourceMethodName()); - } - } - sb.append("]"); - } - } - - protected void appendDetailsWithNewLine(StringBuffer sb, LogRecord record) { - if (record.getThrown() != null) { - try { - sb.append('\n'); - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - record.getThrown().printStackTrace(pw); - pw.close(); - sb.append(sw.toString()); - } catch (Exception ex) { - //shouldn't happen with printwriter - throw Throwables.propagate(ex); - } - } else { - sb.append('\n'); - } - } - - protected String getThreadName(LogRecord record) { - //try to get the thread's name - //only possible if we are the thread (unless do something messy like cache or access private fields) - //fortunately we typically are the thread - LogRecord lr = new LogRecord(Level.INFO, ""); - if (lr.getThreadID()==record.getThreadID()) - return Thread.currentThread().getName() + " ("+record.getThreadID()+")"; - //otherwise just say the number - return "thread ("+record.getThreadID()+")"; - } - - public static class LogFormatterWithThreadAndCaller extends SimpleOneLineLogFormatter { - public LogFormatterWithThreadAndCaller() { - super(true, true, true); - } - } - -} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/math/BitList.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/math/BitList.java b/utils/common/src/main/java/brooklyn/util/math/BitList.java deleted file mode 100644 index f145352..0000000 --- a/utils/common/src/main/java/brooklyn/util/math/BitList.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.math; - -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.List; - -import com.google.common.collect.Lists; -import com.google.common.primitives.Bytes; - -/** represents an immutable ordered collection of bits with a known length - * <p> - * when converting to and from bytes and larger numbers, this representation - * uses the least-significant first convention both for bits and for bytes (little endian) - * <p> - * (i.e. least significant byte is first, as is the least significant bit; - * ninth element in this list is the least significant bit in the second byte, - * so a list {0,0,0,0,0,0,0,0,1,0} represents 256) - **/ -public class BitList { - - private final BitSet bits; - protected final int length; - - protected BitList(BitSet bits, int length) { - assert length >= bits.length(); - this.bits = bits; - this.length = length; - } - - public static BitList newInstance(BitSet bits, int length) { - return new BitList(bits, length); - } - - public int length() { - return length; - } - - public boolean get(int index) { - if (index<0 || index>=length) - throw new IndexOutOfBoundsException("Index "+index+" in "+this); - return bits.get(index); - } - - public static BitList newInstance(byte ...bytes) { - BitSet bits = new BitSet(); - for (int i=0; i < bytes.length*8; i++) - if ((bytes[i/8] & (1 << (i%8))) > 0) - bits.set(i); - return newInstance(bits, bytes.length*8); - } - - /** as {@link #newInstance(byte...)}, but accepting ints for convenience; - * only the least significant 8 bits of the parameters are considered */ - public static BitList newInstanceFromBytes(int ...bytes) { - BitSet bits = new BitSet(); - for (int i=0; i < bytes.length*8; i++) - if ((bytes[i/8] & (1 << (i%8))) > 0) - bits.set(i); - return newInstance(bits, bytes.length*8); - } - - public static BitList newInstance(List<Boolean> l) { - BitSet bs = new BitSet(); - for (int i=0; i<l.size(); i++) - bs.set(i, l.get(i)); - return new BitList(bs, l.size()); - } - - public static BitList newInstance(boolean ...l) { - BitSet bs = new BitSet(); - for (int i=0; i<l.length; i++) - bs.set(i, l[i]); - return new BitList(bs, l.length); - } - - public static BitList newInstance(BigInteger x) { - BitSet bs = new BitSet(); - for (int i=0; i<x.bitLength(); i++) - if (x.testBit(i)) bs.set(i); - return new BitList(bs, x.bitLength()); - } - - /** - * returns the bits converted to bytes, with least significant bit first - * *and* first 8 bits in the first byte - * <p> - * NB this may be different to BitSet.valueOf available since java 7 (as late as that!) - * which reverses the order of the bytes */ - public byte[] asBytes() { - byte[] bytes = new byte[(length+7)/8]; - for (int i=0; i<bits.length(); i++) - if (bits.get(i)) - bytes[i/8] |= 1 << (i%8); - return bytes; - } - - public int[] asUnsignedBytes() { - int[] bytes = new int[(length+7)/8]; - for (int i=0; i<bits.length(); i++) - if (bits.get(i)) - bytes[i/8] |= 1 << (i%8); - return bytes; - } - - /** nb: BitSet forgets the length */ - public BitSet asBitSet() { - return (BitSet) bits.clone(); - } - - public List<Boolean> asList() { - List<Boolean> list = new ArrayList<Boolean>(); - for (int i=0; i<length(); i++) { - list.add(get(i)); - } - return list; - } - - /** represents the result of this bit list logically ORred with the other */ - public BitList orred(BitList other) { - BitSet result = asBitSet(); - result.or(other.asBitSet()); - return new BitList(result, Math.max(length, other.length)); - } - - /** represents the result of this bit list logically ANDed with the other */ - public BitList anded(BitList other) { - BitSet result = asBitSet(); - result.and(other.asBitSet()); - return new BitList(result, Math.max(length, other.length)); - } - - /** represents the result of this bit list logically XORred with the other */ - public BitList xorred(BitList other) { - BitSet result = asBitSet(); - result.xor(other.asBitSet()); - return new BitList(result, Math.max(length, other.length)); - } - - /** represents the result of this bit list logically notted */ - public BitList notted() { - BitSet result = asBitSet(); - result.flip(0, length); - return new BitList(result, length); - } - - /** creates a new instance with the given length, either reducing the list or padding it with 0's - * (at the end, in both cases) - */ - public BitList resized(int length) { - BitSet b2 = asBitSet(); - if (b2.length()>length) - b2.clear(length, b2.length()); - return newInstance(b2, length); - } - - public BitList reversed() { - BitSet b = new BitSet(); - for (int from=bits.length()-1, to=length-bits.length(); from>=0; from--, to++) { - if (get(from)) b.set(to); - } - return new BitList(b, length); - } - - public int commonPrefixLength(BitList other) { - int i=0; - while (i<length && i<other.length) { - if (get(i)!=other.get(i)) return i; - i++; - } - return i; - } - - /** true iff the length is 0; see also isZero */ - public boolean isEmpty() { - return length==0; - } - - /** true iff all bits are 0 */ - public boolean isZero() { - return bits.cardinality()==0; - } - - public BigInteger asBigInteger() { - if (length==0) return BigInteger.ZERO; - return new BigInteger(Bytes.toArray(Lists.reverse(asByteList()))); - } - - public boolean[] asArray() { - boolean[] result = new boolean[length]; - for (int i=0; i<length; i++) - result[i] = get(i); - return result; - } - - public List<Byte> asByteList() { - return Bytes.asList(asBytes()); - } - - /** returns value of this as a byte(ignoring any too-high bits) */ - public byte byteValue() { - return asBigInteger().byteValue(); - } - - /** returns value of this as an integer (ignoring any too-high bits) */ - public int intValue() { - return asBigInteger().intValue(); - } - - /** returns value of this as a long (ignoring any too-high bits) */ - public long longValue() { - return asBigInteger().longValue(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((bits == null) ? 0 : bits.hashCode()); - result = prime * result + length; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - BitList other = (BitList) obj; - if (bits == null) { - if (other.bits != null) - return false; - } else if (!bits.equals(other.bits)) - return false; - if (length != other.length) - return false; - return true; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (int i=0; i<length; i++) { - if (i%8==0 && i>0) sb.append(":"); //for readability - sb.append(get(i) ? '1' : '0'); - } - return sb.toString(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/math/BitUtils.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/math/BitUtils.java b/utils/common/src/main/java/brooklyn/util/math/BitUtils.java deleted file mode 100644 index fd3159a..0000000 --- a/utils/common/src/main/java/brooklyn/util/math/BitUtils.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.math; - -public class BitUtils { - - /** reverses the bits in a byte, i.e. 128 = 0b1000000 = bit list {0,0,0,0,0,0,0,1}, - * reversed yields 1 = 0b00000001 = bit list {1,0,0,0,0,0,0,0} */ - public static byte reverseBitSignificance(byte b) { - int result = 0; - for (int i=0; i<8; i++) { - result <<= 1; - if ((b&1)==1) result++; - b >>= 1; - } - return (byte)result; - } - - /** as {@link #reverseBitSignificance(byte)} but accepting int for convenience */ - public static byte reverseBitSignificanceInByte(int b) { - return reverseBitSignificance((byte)b); - } - - /** returns an array of bytes where the bits in each byte have been reversed; - * note however the order of the arguments is not reversed; - * useful e.g. in working with IP address CIDR's */ - public static byte[] reverseBitSignificance(byte ...bytes) { - byte[] result = new byte[bytes.length]; - for (int i=0; i<bytes.length; i++) - result[i] = reverseBitSignificance(bytes[i]); - return result; - } - - /** as {@link #reverseBitSignificance(byte...)}, but taking ints for convenience (ignoring high bits) */ - public static byte[] reverseBitSignificanceInBytes(int ...bytes) { - byte[] result = new byte[bytes.length]; - for (int i=0; i<bytes.length; i++) - result[i] = reverseBitSignificance((byte)bytes[i]); - return result; - } - - /** why oh why are bytes signed! */ - public static int unsigned(byte b) { - if (b<0) return b+256; - return b; - } - - /** returns the value in 0..255 which is equivalent mod 256 */ - public static int unsignedByte(int b) { - if (b<0) return (b%256)+256; - return (b%256); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/math/MathFunctions.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/math/MathFunctions.java b/utils/common/src/main/java/brooklyn/util/math/MathFunctions.java deleted file mode 100644 index 8c35d21..0000000 --- a/utils/common/src/main/java/brooklyn/util/math/MathFunctions.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.math; - -import javax.annotation.Nullable; - -import brooklyn.util.text.Strings; - -import com.google.common.base.Function; - -public class MathFunctions { - - public static Function<Number, Integer> plus(final int addend) { - return new Function<Number, Integer>() { - public Integer apply(@Nullable Number input) { - if (input==null) return null; - return input.intValue() + addend; - } - }; - } - - public static Function<Number, Long> plus(final long addend) { - return new Function<Number, Long>() { - public Long apply(@Nullable Number input) { - if (input==null) return null; - return input.longValue() + addend; - } - }; - } - - public static Function<Number, Double> plus(final double addend) { - return new Function<Number, Double>() { - public Double apply(@Nullable Number input) { - if (input==null) return null; - return input.doubleValue() + addend; - } - }; - } - - public static Function<Number, Integer> times(final int multiplicand) { - return new Function<Number, Integer>() { - public Integer apply(@Nullable Number input) { - if (input==null) return null; - return input.intValue() * multiplicand; - } - }; - } - - public static Function<Number, Long> times(final long multiplicand) { - return new Function<Number, Long>() { - public Long apply(@Nullable Number input) { - if (input==null) return null; - return input.longValue() * multiplicand; - } - }; - } - - public static Function<Number, Double> times(final double multiplicand) { - return new Function<Number, Double>() { - public Double apply(@Nullable Number input) { - if (input==null) return null; - return input.doubleValue() * multiplicand; - } - }; - } - - public static Function<Number, Double> divide(final double divisor) { - return new Function<Number, Double>() { - public Double apply(@Nullable Number input) { - if (input==null) return null; - return input.doubleValue() / divisor; - } - }; - } - - public static <T> Function<T, Double> divide(final Function<T, ? extends Number> input, final double divisor) { - return new Function<T, Double>() { - public Double apply(@Nullable T input2) { - if (input==null) return null; - Number n = input.apply(input2); - if (n==null) return null; - return n.doubleValue() / divisor; - } - }; - } - - /** returns a string of up to maxLen length (longer in extreme cases) also capped at significantDigits significantDigits */ - public static Function<Number, String> readableString(final int significantDigits, final int maxLen) { - return new Function<Number, String>() { - public String apply(@Nullable Number input) { - if (input==null) return null; - return Strings.makeRealString(input.doubleValue(), maxLen, significantDigits, 0); - } - }; - } - - /** returns a string where the input number is expressed as percent, with given number of significant digits */ - public static Function<Number, String> percent(final int significantDigits) { - return new Function<Number, String>() { - public String apply(@Nullable Number input) { - if (input==null) return null; - return readableString(significantDigits, significantDigits+3).apply(input.doubleValue() * 100d)+"%"; - } - }; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/math/MathPredicates.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/math/MathPredicates.java b/utils/common/src/main/java/brooklyn/util/math/MathPredicates.java deleted file mode 100644 index 41f4024..0000000 --- a/utils/common/src/main/java/brooklyn/util/math/MathPredicates.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.math; - -import javax.annotation.Nullable; - -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; - -public class MathPredicates { - - /** - * Creates a predicate comparing a given number with {@code val}. - * A number of {@code null} passed to the predicate will always return false. - */ - public static <T extends Number> Predicate<T> greaterThan(final double val) { - return new Predicate<T>() { - public boolean apply(@Nullable T input) { - return (input == null) ? false : input.doubleValue() > val; - } - }; - } - - /** - * Creates a predicate comparing a given number with {@code val}. - * A number of {@code null} passed to the predicate will always return false. - */ - public static <T extends Number> Predicate<T> greaterThanOrEqual(final double val) { - return new Predicate<T>() { - public boolean apply(@Nullable T input) { - return (input == null) ? false : input.doubleValue() >= val; - } - }; - } - - /** - * Creates a predicate comparing a given number with {@code val}. - * A number of {@code null} passed to the predicate will always return false. - */ - public static <T extends Number> Predicate<T> lessThan(final double val) { - return new Predicate<T>() { - public boolean apply(@Nullable T input) { - return (input == null) ? false : input.doubleValue() < val; - } - }; - } - - /** - * Creates a predicate comparing a given number with {@code val}. - * A number of {@code null} passed to the predicate will always return false. - */ - public static <T extends Number> Predicate<T> lessThanOrEqual(final double val) { - return new Predicate<T>() { - public boolean apply(@Nullable T input) { - return (input == null) ? false : input.doubleValue() <= val; - } - }; - } - - /** - * Creates a predicate comparing a given number with {@code val}. - * A number of {@code null} passed to the predicate will always return false. - */ - public static <T extends Number> Predicate<T> equalsApproximately(final Number val, final double delta) { - return new EqualsApproximately<T>(val, delta); - } - /** Convenience for {@link #equalsApproximately(double,double)} with a delta of 10^{-6}. */ - public static <T extends Number> Predicate<T> equalsApproximately(final Number val) { - return equalsApproximately(val, 0.0000001); - } - - private static final class EqualsApproximately<T extends Number> implements Predicate<T> { - private final double val; - private final double delta; - private EqualsApproximately(Number val, double delta) { - this.val = val.doubleValue(); - Preconditions.checkArgument(delta>=0, "delta must be non-negative"); - this.delta = delta; - } - public boolean apply(@Nullable T input) { - return (input == null) ? false : Math.abs(input.doubleValue() - val) <= delta; - } - @Override - public String toString() { - return "equals-approximately("+val+" +- "+delta+")"; - } - } - - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/maven/MavenArtifact.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/maven/MavenArtifact.java b/utils/common/src/main/java/brooklyn/util/maven/MavenArtifact.java deleted file mode 100644 index 5e847e5..0000000 --- a/utils/common/src/main/java/brooklyn/util/maven/MavenArtifact.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.maven; - -import static com.google.common.base.Preconditions.checkNotNull; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.util.collections.MutableList; -import brooklyn.util.javalang.JavaClassNames; -import brooklyn.util.text.Strings; - -public class MavenArtifact { - - private static final Logger log = LoggerFactory.getLogger(MavenArtifact.class); - - protected final @Nonnull String groupId; - protected final @Nonnull String artifactId; - protected final @Nonnull String packaging; - protected final @Nullable String classifier; - protected final @Nonnull String version; - - /** a custom marker inserted after the artifactId and before the version, offset by an additional "-"; - * defaults to null (nothing) - * <p> - * uses: when a shaded JAR is built, sometimes the word shaded is inserted before the version - * (and the "with-dependencies" classifier overwritten) */ - protected @Nullable String customFileNameAfterArtifactMarker; - - /** a custom marker inserted after the version and before the extension, offset by an additional "-" if non-empty; - * defaults to {@link #getClassifier()} if null, but can replace the classifier - * <p> - * uses: removing classifier by specifying "", or adding a notional classifier such as "dist" */ - protected @Nullable String classifierFileNameMarker; - - public MavenArtifact(String groupId, String artifactId, String packaging, String classifier, String version) { - super(); - this.groupId = groupId; - this.artifactId = artifactId; - this.packaging = packaging; - this.classifier = classifier; - this.version = version; - } - - public MavenArtifact(String groupId, String artifactId, String packaging, String version) { - super(); - this.groupId = groupId; - this.artifactId = artifactId; - this.packaging = packaging; - this.classifier = null; - this.version = version; - } - - public static MavenArtifact fromCoordinate(String coordinate) { - String[] parts = checkNotNull(coordinate, "coordinate").split(":"); - if (parts.length==4) - return new MavenArtifact(parts[0], parts[1], parts[2], parts[3]); - if (parts.length==5) - return new MavenArtifact(parts[0], parts[1], parts[2], parts[3], parts[4]); - throw new IllegalArgumentException("Invalid maven coordinate '"+coordinate+"'"); - } - - public String getGroupId() { - return groupId; - } - - public String getArtifactId() { - return artifactId; - } - - public String getVersion() { - return version; - } - - @Nullable public String getClassifier() { - return classifier; - } - - public String getPackaging() { - return packaging; - } - - public boolean isSnapshot() { - return getVersion().toUpperCase().contains("SNAPSHOT"); - } - - /** @see #customFileNameAfterArtifactMarker */ - public String getCustomFileNameAfterArtifactMarker() { - return customFileNameAfterArtifactMarker; - } - - /** @see #customFileNameAfterArtifactMarker */ - public void setCustomFileNameAfterArtifactMarker(String customFileNameMarker) { - this.customFileNameAfterArtifactMarker = customFileNameMarker; - } - - /** @ee {@link #classifierFileNameMarker} */ - public String getClassifierFileNameMarker() { - return classifierFileNameMarker!=null ? classifierFileNameMarker : getClassifier(); - } - - /** @ee {@link #classifierFileNameMarker} */ - public void setClassifierFileNameMarker(String classifierFileNameMarker) { - this.classifierFileNameMarker = classifierFileNameMarker; - } - - /** returns a "groupId:artifactId:version:(classifier:)packaging" string - * which maven refers to as the co-ordinate */ - public String getCoordinate() { - return Strings.join(MutableList.<String>of().append(groupId, artifactId, packaging). - appendIfNotNull(classifier).append(version), ":"); - } - - public String getFilename() { - return artifactId+"-"+ - (Strings.isNonEmpty(getCustomFileNameAfterArtifactMarker()) ? getCustomFileNameAfterArtifactMarker()+"-" : "")+ - version+ - (Strings.isNonEmpty(getClassifierFileNameMarker()) ? "-"+getClassifierFileNameMarker() : "")+ - (Strings.isNonEmpty(getExtension()) ? "."+getExtension() : ""); - } - - /** returns an extension, defaulting to {@link #packaging} if one cannot be inferred */ - @Nullable public String getExtension() { - if ("jar".equalsIgnoreCase(packaging) || "bundle".equalsIgnoreCase(packaging)) - return "jar"; - if ("war".equalsIgnoreCase(packaging)) - return "war"; - log.debug("Unrecognised packaging for autodetecting extension, defaulting to {} for: {}", packaging, this); - return packaging; - } - - @Override - public String toString() { - return JavaClassNames.simpleClassName(this)+"["+getCoordinate()+"]"; - } - - @Override - public int hashCode() { - // autogenerated code - - final int prime = 31; - int result = 1; - result = prime * result + ((artifactId == null) ? 0 : artifactId.hashCode()); - result = prime * result + ((classifier == null) ? 0 : classifier.hashCode()); - result = prime * result + ((classifierFileNameMarker == null) ? 0 : classifierFileNameMarker.hashCode()); - result = prime * result + ((customFileNameAfterArtifactMarker == null) ? 0 : customFileNameAfterArtifactMarker.hashCode()); - result = prime * result + ((groupId == null) ? 0 : groupId.hashCode()); - result = prime * result + ((packaging == null) ? 0 : packaging.hashCode()); - result = prime * result + ((version == null) ? 0 : version.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - // autogenerated code - - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - MavenArtifact other = (MavenArtifact) obj; - if (artifactId == null) { - if (other.artifactId != null) - return false; - } else if (!artifactId.equals(other.artifactId)) - return false; - if (classifier == null) { - if (other.classifier != null) - return false; - } else if (!classifier.equals(other.classifier)) - return false; - if (classifierFileNameMarker == null) { - if (other.classifierFileNameMarker != null) - return false; - } else if (!classifierFileNameMarker.equals(other.classifierFileNameMarker)) - return false; - if (customFileNameAfterArtifactMarker == null) { - if (other.customFileNameAfterArtifactMarker != null) - return false; - } else if (!customFileNameAfterArtifactMarker.equals(other.customFileNameAfterArtifactMarker)) - return false; - if (groupId == null) { - if (other.groupId != null) - return false; - } else if (!groupId.equals(other.groupId)) - return false; - if (packaging == null) { - if (other.packaging != null) - return false; - } else if (!packaging.equals(other.packaging)) - return false; - if (version == null) { - if (other.version != null) - return false; - } else if (!version.equals(other.version)) - return false; - return true; - } - - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/maven/MavenRetriever.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/maven/MavenRetriever.java b/utils/common/src/main/java/brooklyn/util/maven/MavenRetriever.java deleted file mode 100644 index 7840d7b..0000000 --- a/utils/common/src/main/java/brooklyn/util/maven/MavenRetriever.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.maven; - -import java.io.File; - -import brooklyn.util.net.Urls; -import brooklyn.util.text.Strings; - -import com.google.common.base.Function; - -/** returns the URL for accessing the artifact, assuming sonatype for snapshots and maven.org for releases by default, - * with some methods checking local file system, and allowing the generators for each to be specified */ -public class MavenRetriever { - - public static final Function<MavenArtifact,String> CONDITIONAL_SNAPSHOT_URL_GENERATOR = new Function<MavenArtifact, String>() { - public String apply(MavenArtifact artifact) { - if (artifact.groupId.startsWith("org.apache")) { - return APACHE_SNAPSHOT_URL_GENERATOR.apply(artifact); - } else { - return SONATYPE_SNAPSHOT_URL_GENERATOR.apply(artifact); - } - } - }; - - public static final Function<MavenArtifact,String> SONATYPE_SNAPSHOT_URL_GENERATOR = - nexusSnapshotUrlGenerator("https://oss.sonatype.org"); - - public static final Function<MavenArtifact,String> APACHE_SNAPSHOT_URL_GENERATOR = - nexusSnapshotUrlGenerator("https://repository.apache.org"); - - public static Function<MavenArtifact,String> nexusSnapshotUrlGenerator(final String baseUrl) { - return new Function<MavenArtifact, String>() { - public String apply(MavenArtifact artifact) { - return baseUrl+"/service/local/artifact/maven/redirect?" + - "r=snapshots&" + - "v="+Urls.encode(artifact.version)+"&" + - "g="+Urls.encode(artifact.groupId)+"&" + - "a="+Urls.encode(artifact.artifactId)+"&" + - (artifact.classifier!=null ? "c="+Urls.encode(artifact.classifier)+"&" : "")+ - "e="+Urls.encode(artifact.packaging); - } - }; - } - - public static final Function<MavenArtifact,String> MAVEN_CENTRAL_URL_GENERATOR = new Function<MavenArtifact, String>() { - public String apply(MavenArtifact artifact) { - return "http://search.maven.org/remotecontent?filepath="+ - Urls.encode(Strings.replaceAllNonRegex(artifact.groupId, ".", "/")+"/"+ - artifact.artifactId+"/"+artifact.version+"/"+ - artifact.getFilename()); - } - }; - - public static final Function<MavenArtifact,String> LOCAL_REPO_PATH_GENERATOR = new Function<MavenArtifact, String>() { - public String apply(MavenArtifact artifact) { - return System.getProperty("user.home")+"/.m2/repository/"+ - Strings.replaceAllNonRegex(artifact.groupId, ".", "/")+"/"+ - artifact.artifactId+"/"+artifact.version+"/"+ - artifact.getFilename(); - } - }; - - protected Function<MavenArtifact,String> snapshotUrlGenerator = CONDITIONAL_SNAPSHOT_URL_GENERATOR; - protected Function<MavenArtifact,String> releaseUrlGenerator = MAVEN_CENTRAL_URL_GENERATOR; - - public void setSnapshotUrlGenerator(Function<MavenArtifact, String> snapshotUrlGenerator) { - this.snapshotUrlGenerator = snapshotUrlGenerator; - } - - public void setReleaseUrlGenerator(Function<MavenArtifact, String> releaseUrlGenerator) { - this.releaseUrlGenerator = releaseUrlGenerator; - } - - public String getHostedUrl(MavenArtifact artifact) { - if (artifact.isSnapshot()) return snapshotUrlGenerator.apply(artifact); - else return releaseUrlGenerator.apply(artifact); - } - - public String getLocalPath(MavenArtifact artifact) { - return LOCAL_REPO_PATH_GENERATOR.apply(artifact); - } - - public boolean isInstalledLocally(MavenArtifact artifact) { - return new File(getLocalPath(artifact)).exists(); - } - - /** returns a URL for accessing the given artifact, preferring a local file if available, - * else generating a hosted URL (but not checking) */ - public String getLocalUrl(MavenArtifact artifact) { - if (isInstalledLocally(artifact)) return new File(getLocalPath(artifact)).toURI().toString(); - if (artifact.isSnapshot()) return snapshotUrlGenerator.apply(artifact); - else return releaseUrlGenerator.apply(artifact); - } - - /** returns a URL for accessing the artifact from the local machine (ie preferring a local repo), - * using the default remote sits (sonatype for snapshots and maven.org for releases) */ - public static String localUrl(MavenArtifact artifact) { - return new MavenRetriever().getLocalUrl(artifact); - } - - /** returns a URL for accessing the artifact from any machine (ie not allowing a local repo), - * using the default remote sits (sonatype for snapshots and maven.org for releases) */ - public static String hostedUrl(MavenArtifact artifact) { - return new MavenRetriever().getHostedUrl(artifact); - } - - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/net/Cidr.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/net/Cidr.java b/utils/common/src/main/java/brooklyn/util/net/Cidr.java deleted file mode 100644 index 64768f4..0000000 --- a/utils/common/src/main/java/brooklyn/util/net/Cidr.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.net; - - -import java.io.Serializable; -import java.net.InetAddress; -import java.util.Arrays; -import java.util.List; - -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.math.BitList; -import brooklyn.util.math.BitUtils; -import brooklyn.util.text.Strings; - -import com.google.common.collect.ImmutableList; - -/** represents a CIDR (classless inter-domain routing) token, i.e. 10.0.0.0/8 or 192.168.4.0/24 */ -public class Cidr implements Serializable { - - private static final long serialVersionUID = -4605909101590811958L; - - /** 0.0.0.0/0 -- matches all addresses */ - public static final Cidr UNIVERSAL = new Cidr(); - - public static final Cidr _10 = new Cidr(10); - public static final Cidr _172_16 = new Cidr("172.16.0.0/12"); - public static final Cidr _192_168 = new Cidr(192, 168); - public static final Cidr CLASS_A = _10; - public static final Cidr CLASS_B = _172_16; - public static final Cidr CLASS_C = _192_168; - - public static final List<Cidr> PRIVATE_NETWORKS_RFC_1918 = ImmutableList.<Cidr>of(_192_168, _172_16, _10); - - public static final Cidr _169_254 = new Cidr("169.254.0.0/16"); - public static final Cidr LINK_LOCAL = _169_254; - - public static final Cidr _127 = new Cidr("127.0.0.0/8"); - public static final Cidr LOOPBACK = _127; - - public static final List<Cidr> NON_PUBLIC_CIDRS = ImmutableList.<Cidr>builder().addAll(PRIVATE_NETWORKS_RFC_1918).add(LINK_LOCAL).add(LOOPBACK).build(); - - - final int[] subnetBytes = new int[] { 0, 0, 0, 0 }; - final int length; - - - public Cidr(String cidr) { - if (Strings.isBlank(cidr)) - // useful e.g. if user leaves it blank in gui - cidr = "0.0.0.0/0"; - int slash = cidr.indexOf('/'); - if (slash==-1) throw new IllegalArgumentException("CIDR should be of form 192.168.0.0/16 (missing slash); input="+cidr); - String subnet = cidr.substring(0, slash); - String lengthS = cidr.substring(slash+1); - this.length = Integer.parseInt(lengthS); - String[] bytes = subnet.split("\\."); - int i=0; - for (; i<this.length/8; i++) - subnetBytes[i] = Integer.parseInt(bytes[i]); - for (; i<(this.length+7)/8; i++) - // for fractional parts: reverse significance, trim, reverse back - subnetBytes[i] = - BitUtils.unsigned( BitUtils.reverseBitSignificanceInByte( - BitList.newInstanceFromBytes(BitUtils.reverseBitSignificanceInByte(Integer.parseInt(bytes[i]))). - resized(this.length % 8).intValue() )); - } - - /** returns true iff this CIDR is well-formed and canonical, - * i.e. 4 dot-separated bytes followed by a slash and a length, - * where length is <= 32, and the preceding 4 bytes don't include any 1 bits beyond the indicated length; - * e.g. 10.0.0.0/8 -- but not 10.0.0.1/8 or 10.../8 - * (although the latter ones are accepted by the constructor and converted to the canonical CIDR) */ - public static boolean isCanonical(String cidr) { - try { - return cidr.equals(new Cidr(cidr).toString()); - } catch (Throwable e) { - Exceptions.propagateIfFatal(e); - return false; - } - } - - /** allows creation as Cidr(192, 168) for 192.168.0.0/16; - * zero bits or ints included are significant, i.e. Cidr(10, 0) gives 10.0.0.0/16 */ - public Cidr(int ...unsignedBytes) { - length = unsignedBytes.length*8; - System.arraycopy(unsignedBytes, 0, subnetBytes, 0, unsignedBytes.length); - } - - public Cidr(int[] subnetBytes, int length) { - this.length = length; - if (subnetBytes.length>4) - throw new IllegalArgumentException("Cannot create CIDR beyond 4 bytes: "+Arrays.toString(subnetBytes)); - if (length>32) - throw new IllegalArgumentException("Cannot create CIDR beyond 4 bytes: length "+length); - // reverse the bits to remove zeroed bits, then reverse back - byte[] significantSubnetBytes = BitList.newInstance(BitUtils.reverseBitSignificanceInBytes(subnetBytes)).resized(length).asBytes(); - for (int i=0; i<significantSubnetBytes.length; i++) - this.subnetBytes[i] = BitUtils.unsigned(BitUtils.reverseBitSignificance(significantSubnetBytes[i])); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + length; - result = prime * result + Arrays.hashCode(subnetBytes); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Cidr other = (Cidr) obj; - if (length != other.length) - return false; - if (!Arrays.equals(subnetBytes, other.subnetBytes)) - return false; - return true; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - int i=0; - while (i<(length+7)/8) { - if (sb.length()>0) sb.append("."); - sb.append(""+subnetBytes[i]); - i++; - } - while (i<4) { - if (sb.length()>0) sb.append("."); - sb.append("0"); - i++; - } - sb.append("/"); - sb.append(""+length); - return sb.toString(); - } - - public int[] getBytes() { - return Arrays.copyOf(subnetBytes, 4); - } - - public int getLength() { - return length; - } - - public Cidr subnet(int ...extraUnsignedBytes) { - if ((length%8)!=0) throw new IllegalStateException("subnet can only be used for byte boundary subnetted CIDR's; not "+this); - int[] newBytes = getBytes(); - int newLen = this.length + extraUnsignedBytes.length*8; - if (newLen>32) throw new IllegalStateException("further subnet for "+Arrays.toString(extraUnsignedBytes)+" not possible on CIDR "+this); - for (int i=0; i<extraUnsignedBytes.length; i++) { - newBytes[this.length/8 + i] = extraUnsignedBytes[i]; - } - return new Cidr(newBytes, newLen); - } - - /** returns the netmask for this cidr; e.g. for a /24 cidr returns 255.255.255.0 */ - public InetAddress netmask() { - final byte[] netmaskBytes = new byte[] { 0, 0, 0, 0 }; - int lengthLeft = length; - int i=0; - while (lengthLeft>0) { - if (lengthLeft>=8) { - netmaskBytes[i] = (byte)255; - } else { - netmaskBytes[i] = (byte) ( (1 << lengthLeft) - 1 ); - } - lengthLeft -= 8; - i++; - } - return Networking.getInetAddressWithFixedName(netmaskBytes); - } - - /** taking the addresses in the CIDR in order, returns the one in the offset^th position - * (starting with the CIDR itself, even if final bits are 0) */ - public InetAddress addressAtOffset(int offset) { - int[] ints = getBytes(); - ints[3] += offset; - { - int i=3; - while (ints[i]>=256) { - ints[i-1] += (ints[i] / 256); - ints[i] %= 256; - i--; - } - } - byte[] bytes = new byte[] { 0, 0, 0, 0 }; - for (int i=0; i<4; i++) - bytes[i] = (byte) ints[i]; - return Networking.getInetAddressWithFixedName(bytes); - } - - /** returns length of the prefix in common between the two cidrs */ - public int commonPrefixLength(Cidr other) { - return asBitList().commonPrefixLength(other.asBitList()); - } - - public Cidr commonPrefix(Cidr other) { - return new Cidr(other.getBytes(), commonPrefixLength(other)); - } - - /** returns list of bits for the significant (length) bits of this CIDR */ - public BitList asBitList() { - return BitList.newInstance(BitUtils.reverseBitSignificanceInBytes(getBytes())).resized(getLength()); - } - - public boolean contains(Cidr target) { - return commonPrefixLength(target) == getLength(); - } - - // FIXME remove from here, promote NetworkUtils - /** @deprecated use {@link Networking#getInetAddressWithFixedName(byte[])} */ - @Deprecated - public static InetAddress getInetAddressWithFixedName(byte[] ip) { - return Networking.getInetAddressWithFixedName(ip); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/net/HasNetworkAddresses.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/net/HasNetworkAddresses.java b/utils/common/src/main/java/brooklyn/util/net/HasNetworkAddresses.java deleted file mode 100644 index 18d1019..0000000 --- a/utils/common/src/main/java/brooklyn/util/net/HasNetworkAddresses.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.net; - -import java.util.Set; - -import javax.annotation.Nullable; - -import com.google.common.annotations.Beta; - -@Beta -public interface HasNetworkAddresses { - - /** - * <h4>note</h4> hostname is something that is set in the operating system. - * This value may or may not be set in DNS. - * - * @return hostname of the node, or null if unknown - */ - @Nullable - String getHostname(); - - /** - * All public IP addresses, potentially including shared ips. - */ - Set<String> getPublicAddresses(); - - /** - * All private IP addresses. - */ - Set<String> getPrivateAddresses(); -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/net/NetworkMultiAddressUtils.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/net/NetworkMultiAddressUtils.java b/utils/common/src/main/java/brooklyn/util/net/NetworkMultiAddressUtils.java deleted file mode 100644 index e1635f2..0000000 --- a/utils/common/src/main/java/brooklyn/util/net/NetworkMultiAddressUtils.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.net; - -import java.util.Collection; - -/** - * Given several strings, determines which have the longest, and shorted, initial matching prefix. - * Particularly useful as a poor-man's way to determine which IP's are likely to be the same subnet. - */ -public class NetworkMultiAddressUtils { - - // TODO should convert to byte arrays then binary, and look at binary digit match length ! - -// public static Collection<String> sortByInitialSimilarity(final String pattern, Collection<String> targets) { -// List<String> result = new ArrayList<String>(targets); -// Collections.sort(result, new Comparator<String>() { -// @Override -// public int compare(String o1, String o2) { -// int i1 = 0; int i2 = 0; -// for (int i=0; i<pattern.length(); i++) { -// if (o1.length()<i || o2.length()<i) break; -// if (o1.substring(0, i).equals(anObject)) -// } -// } -// }); -// return result; -// } - - public static String getClosest(final String pattern, Collection<String> targets) { - int score = -1; - String best = null; - for (String target: targets) { - int thisScore = matchLength(pattern, target); - if (thisScore > score) { - score = thisScore; - best = target; - } - } - return best; - } - - public static String getFurthest(final String pattern, Collection<String> targets) { - int score = 65535; - String best = null; - for (String target: targets) { - int thisScore = matchLength(pattern, target); - if (thisScore < score) { - score = thisScore; - best = target; - } - } - return best; - } - - private static int matchLength(String pattern, String target) { - int i=0; - while (i<pattern.length() && i<target.length() && pattern.charAt(i)==target.charAt(i)) - i++; - return i; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/net/Networking.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/net/Networking.java b/utils/common/src/main/java/brooklyn/util/net/Networking.java deleted file mode 100644 index 4337dc4..0000000 --- a/utils/common/src/main/java/brooklyn/util/net/Networking.java +++ /dev/null @@ -1,548 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.net; - -import java.io.IOException; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.NetworkInterface; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.regex.Pattern; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.text.Identifiers; -import brooklyn.util.time.Time; - -import com.google.common.base.Preconditions; -import com.google.common.base.Stopwatch; -import com.google.common.base.Throwables; -import com.google.common.net.HostAndPort; -import com.google.common.primitives.UnsignedBytes; - -import static com.google.common.base.Preconditions.checkArgument; - -public class Networking { - - private static final Logger log = LoggerFactory.getLogger(Networking.class); - - public static final int MIN_PORT_NUMBER = 1; - public static final int MAX_PORT_NUMBER = 65535; - - // based on http://stackoverflow.com/questions/106179/regular-expression-to-match-hostname-or-ip-address - // but updated to allow leading zeroes - public static final String VALID_IP_ADDRESS_REGEX = "^((0*[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}(0*[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"; - - public static final Pattern VALID_IP_ADDRESS_PATTERN; - static { - VALID_IP_ADDRESS_PATTERN = Pattern.compile(VALID_IP_ADDRESS_REGEX); - } - - public static final List<Cidr> PRIVATE_NETWORKS = Cidr.PRIVATE_NETWORKS_RFC_1918; - - public static InetAddress ANY_NIC = getInetAddressWithFixedName(0, 0, 0, 0); - public static InetAddress LOOPBACK = getInetAddressWithFixedName(127, 0, 0, 1); - - public static boolean isPortAvailable(int port) { - return isPortAvailable(ANY_NIC, port); - } - public static boolean isPortAvailable(InetAddress localAddress, int port) { - if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) { - throw new IllegalArgumentException("Invalid start port: " + port); - } - - Stopwatch watch = Stopwatch.createStarted(); - try { - //despite http://stackoverflow.com/questions/434718/sockets-discover-port-availability-using-java - //(recommending the following) it isn't 100% reliable (e.g. nginx will happily coexist with ss+ds) - // - //Svet - SO_REUSEADDR (enabled below) will allow one socket to listen on 0.0.0.0:X and another on - //192.168.0.1:X which explains the above comment (nginx sets SO_REUSEADDR as well). Moreover there - //is no TIME_WAIT for listening sockets without any connections so why enable it at all. - ServerSocket ss = null; - DatagramSocket ds = null; - try { - // Check TCP port - ss = new ServerSocket(); - ss.setSoTimeout(250); - ss.setReuseAddress(true); - ss.bind(new InetSocketAddress(localAddress, port)); - - // Check UDP port - ds = new DatagramSocket(null); - ds.setSoTimeout(250); - ds.setReuseAddress(true); - ds.bind(new InetSocketAddress(localAddress, port)); - } catch (IOException e) { - if (log.isTraceEnabled()) log.trace("Failed binding to " + localAddress + " : " + port, e); - return false; - } finally { - closeQuietly(ds); - closeQuietly(ss); - } - - if (localAddress==null || ANY_NIC.equals(localAddress)) { - // sometimes 0.0.0.0 can be bound to even if 127.0.0.1 has the port as in use; - // check all interfaces if 0.0.0.0 was requested - Enumeration<NetworkInterface> nis = null; - try { - nis = NetworkInterface.getNetworkInterfaces(); - } catch (SocketException e) { - throw Exceptions.propagate(e); - } - // When using a specific interface saw failures not caused by port already bound: - // * java.net.SocketException: No such device - // * java.net.BindException: Cannot assign requested address - // * probably many more - // Check if the address is still valid before marking the port as not available. - boolean foundAvailableInterface = false; - while (nis.hasMoreElements()) { - NetworkInterface ni = nis.nextElement(); - Enumeration<InetAddress> as = ni.getInetAddresses(); - while (as.hasMoreElements()) { - InetAddress a = as.nextElement(); - if (!isPortAvailable(a, port)) { - if (isAddressValid(a)) { - if (log.isTraceEnabled()) log.trace("Port {} : {} @ {} is taken and the address is valid", new Object[] {a, port, nis}); - return false; - } - } else { - foundAvailableInterface = true; - } - } - } - if (!foundAvailableInterface) { - //Aborting with an error, even nextAvailablePort won't be able to find a free port. - throw new RuntimeException("Unable to bind on any network interface, even when letting the OS pick a port. Possible causes include file handle exhaustion, port exhaustion. Failed on request for " + localAddress + ":" + port + "."); - } - } - - return true; - } finally { - // Until timeout was added, was taking 1min5secs for /fe80:0:0:0:1cc5:1ff:fe81:a61d%8 : 8081 - // Svet - Probably caused by the now gone new Socket().connect() call, SO_TIMEOUT doesn't - // influence bind(). Doesn't hurt having it though. - long elapsed = watch.elapsed(TimeUnit.SECONDS); - boolean isDelayed = (elapsed >= 1); - boolean isDelayedByMuch = (elapsed >= 30); - if (isDelayed || log.isTraceEnabled()) { - String msg = "Took {} to determine if port was available for {} : {}"; - Object[] args = new Object[] {Time.makeTimeString(watch.elapsed(TimeUnit.MILLISECONDS), true), localAddress, port}; - if (isDelayedByMuch) { - log.warn(msg, args); - } else if (isDelayed) { - log.debug(msg, args); - } else { - log.trace(msg, args); - } - } - } - } - - /** - * Bind to the specified IP, but let the OS pick a port. - * If the operation fails we know it's not because of - * non-available port, the interface could be down. - * - * If there's port exhaustion on a single interface we won't catch it - * and declare the port is free. Doesn't matter really because the - * subsequent bind of the caller will fail anyway and nextAvailablePort - * wouldn't be able to find a free one either. - */ - private static boolean isAddressValid(InetAddress addr) { - ServerSocket ss; - try { - ss = new ServerSocket(); - ss.setSoTimeout(250); - } catch (IOException e) { - throw Exceptions.propagate(e); - } - try { - ss.bind(new InetSocketAddress(addr, 0)); - return true; - } catch (IOException e) { - if (log.isTraceEnabled()) log.trace("Binding on {} failed, interface could be down, being reconfigured, file handle exhaustion, port exhaustion, etc.", addr); - return false; - } finally { - closeQuietly(ss); - } - } - - /** returns the first port available on the local machine >= the port supplied */ - public static int nextAvailablePort(int port) { - checkArgument(port >= MIN_PORT_NUMBER && port <= MAX_PORT_NUMBER, "requested port %s is outside the valid range of %s to %s", port, MIN_PORT_NUMBER, MAX_PORT_NUMBER); - int originalPort = port; - while (!isPortAvailable(port) && port < MAX_PORT_NUMBER) port++; - if (port >= MAX_PORT_NUMBER) - throw new RuntimeException("unable to find a free port at or above " + originalPort); - return port; - } - - public static boolean isPortValid(Integer port) { - return (port!=null && port>=Networking.MIN_PORT_NUMBER && port<=Networking.MAX_PORT_NUMBER); - } - public static int checkPortValid(Integer port, String errorMessage) { - if (!isPortValid(port)) { - throw new IllegalArgumentException("Invalid port value "+port+": "+errorMessage); - } - return port; - } - - public static void checkPortsValid(Map<?, ?> ports) { - for (Map.Entry<?,?> entry : ports.entrySet()) { - Object val = entry.getValue(); - if (val == null){ - throw new IllegalArgumentException("port for "+entry.getKey()+" is null"); - } else if (!(val instanceof Integer)) { - throw new IllegalArgumentException("port "+val+" for "+entry.getKey()+" is not an integer ("+val.getClass()+")"); - } - checkPortValid((Integer)val, ""+entry.getKey()); - } - } - - /** - * Check if this is a private address, not exposed on the public Internet. - * - * For IPV4 addresses this is an RFC1918 subnet (site local) address ({@code 10.0.0.0/8}, - * {@code 172.16.0.0/12} and {@code 192.168.0.0/16}), a link-local address - * ({@code 169.254.0.0/16}) or a loopback address ({@code 127.0.0.1/0}). - * <p> - * For IPV6 addresses this is the RFC3514 link local block ({@code fe80::/10}) - * and site local block ({@code feco::/10}) or the loopback block - * ({@code ::1/128}). - * - * @return true if the address is private - */ - public static boolean isPrivateSubnet(InetAddress address) { - return address.isSiteLocalAddress() || address.isLoopbackAddress() || address.isLinkLocalAddress(); - } - - /** Check whether this address is definitely not going to be usable on any other machine; - * i.e. if it is a loopback address or a link-local (169.254) - */ - public static boolean isLocalOnly(InetAddress address) { - return address.isLoopbackAddress() || address.isLinkLocalAddress(); - } - - /** As {@link #isLocalOnly(InetAddress)} but taking a string; - * does not require the string to be resolvable, and generally treats non-resolvable hostnames as NOT local-only - * (although they are treated as private by {@link #isPrivateSubnet(String)}), - * although certain well-known hostnames are recognised as local-only - * <p> - * note however {@link InetAddress#getByName(String)} can ignore settings in /etc/hosts, on OS X at least, - * and give different values than the system */ - public static boolean isLocalOnly(String hostnameOrIp) { - Preconditions.checkNotNull(hostnameOrIp, "hostnameOrIp"); - if ("127.0.0.1".equals(hostnameOrIp)) return true; - if ("localhost".equals(hostnameOrIp)) return true; - if ("localhost.localdomain".equals(hostnameOrIp)) return true; - try { - InetAddress ia = getInetAddressWithFixedName(hostnameOrIp); - return isLocalOnly(ia); - } catch (Exception e) { - log.debug("Networking cannot resolve "+hostnameOrIp+": assuming it is not a local-only address, but it is a private address"); - return false; - } - } - - /** As {@link #isPrivateSubnet(InetAddress)} but taking a string; sepcifically local-only address ARE treated as private. - * does not require the string to be resolvable, and things which aren't resolvable are treated as private - * unless they are known to be local-only */ - public static boolean isPrivateSubnet(String hostnameOrIp) { - Preconditions.checkNotNull(hostnameOrIp, "hostnameOrIp"); - try { - InetAddress ia = getInetAddressWithFixedName(hostnameOrIp); - return isPrivateSubnet(ia); - } catch (Exception e) { - log.debug("Networking cannot resolve "+hostnameOrIp+": assuming it IS a private address"); - return true; - } - } - - private static boolean triedUnresolvableHostname = false; - private static String cachedAddressOfUnresolvableHostname = null; - - /** returns null in a sane DNS environment, but if DNS provides a bogus address for made-up hostnames, this returns that address */ - public synchronized static String getAddressOfUnresolvableHostname() { - if (triedUnresolvableHostname) return cachedAddressOfUnresolvableHostname; - String h = "noexistent-machine-"+Identifiers.makeRandomBase64Id(8); - try { - cachedAddressOfUnresolvableHostname = InetAddress.getByName(h).getHostAddress(); - log.info("Networking detected "+cachedAddressOfUnresolvableHostname+" being returned by DNS for bogus hostnames ("+h+")"); - } catch (Exception e) { - log.debug("Networking detected failure on DNS resolution of unknown hostname ("+h+" throws "+e+")"); - cachedAddressOfUnresolvableHostname = null; - } - triedUnresolvableHostname = true; - return cachedAddressOfUnresolvableHostname; - } - - /** resolves the given hostname to an IP address, returning null if unresolvable or - * if the resolution is bogus (eg 169.* subnet or a "catch-all" IP resolution supplied by some miscreant DNS services) */ - public static InetAddress resolve(String hostname) { - try { - InetAddress a = InetAddress.getByName(hostname); - if (a==null) return null; - String ha = a.getHostAddress(); - if (log.isDebugEnabled()) log.debug("Networking resolved "+hostname+" as "+a); - if (ha.equals(getAddressOfUnresolvableHostname())) return null; - if (ha.startsWith("169.")) return null; - return a; - } catch (Exception e) { - if (log.isDebugEnabled()) log.debug("Networking failed to resolve "+hostname+", threw "+e); - return null; - } - } - - /** - * Gets an InetAddress using the given IP, and using that IP as the hostname (i.e. avoids any hostname resolution). - * <p> - * This is very useful if using the InetAddress for updating config files on remote machines, because then it will - * not be pickup a hostname from the local /etc/hosts file, which might not be known on the remote machine. - */ - public static InetAddress getInetAddressWithFixedName(byte[] ip) { - try { - StringBuilder name = new StringBuilder(); - for (byte part : ip) { - if (name.length() > 0) name.append("."); - name.append(part); - } - return InetAddress.getByAddress(name.toString(), ip); - } catch (UnknownHostException e) { - throw Throwables.propagate(e); - } - } - - public static InetAddress getInetAddressWithFixedName(int ip1, int ip2, int ip3, int ip4) { - return getInetAddressWithFixedName(asByteArray(ip1, ip2, ip3, ip4)); - } - - public static InetAddress getInetAddressWithFixedName(int ip1, int ip2, int ip3, int ip4, int ip5, int ip6) { - return getInetAddressWithFixedName(asByteArray(ip1, ip2, ip3, ip4, ip5, ip6)); - } - - /** creates a byte array given a var-arg number of (or bytes or longs); - * checks that all values are valid as _unsigned_ bytes (i.e. in [0,255] ) */ - public static byte[] asByteArray(long ...bytes) { - byte[] result = new byte[bytes.length]; - for (int i=0; i<bytes.length; i++) - result[i] = UnsignedBytes.checkedCast(bytes[i]); - return result; - } - - /** checks whether given string matches a valid numeric IP (v4) address, e.g. 127.0.0.1, - * but not localhost or 1.2.3.256 */ - public static boolean isValidIp4(String input) { - return VALID_IP_ADDRESS_PATTERN.matcher(input).matches(); - } - - /** - * Gets an InetAddress using the given hostname or IP. If it is an IPv4 address, then this is equivalent - * to {@link getInetAddressWithFixedName(byte[])}. If it is a hostname, then this hostname will be used - * in the returned InetAddress. - */ - public static InetAddress getInetAddressWithFixedName(String hostnameOrIp) { - try { - if (isValidIp4(hostnameOrIp)) { - byte[] ip = new byte[4]; - String[] parts = hostnameOrIp.split("\\."); - assert parts.length == 4 : "val="+hostnameOrIp+"; split="+Arrays.toString(parts)+"; length="+parts.length; - for (int i = 0; i < parts.length; i++) { - ip[i] = (byte)Integer.parseInt(parts[i]); - } - return InetAddress.getByAddress(hostnameOrIp, ip); - } else { - return InetAddress.getByName(hostnameOrIp); - } - } catch (UnknownHostException e) { - throw Throwables.propagate(e); - } - } - - /** returns local IP address, or 127.0.0.1 if it cannot be parsed */ - public static InetAddress getLocalHost() { - try { - return InetAddress.getLocalHost(); - } catch (UnknownHostException e) { - InetAddress result = null; - result = getInetAddressWithFixedName("127.0.0.1"); - log.warn("Localhost is not resolvable; using "+result); - return result; - } - } - - /** returns all local addresses */ - public static Map<String,InetAddress> getLocalAddresses() { - Map<String, InetAddress> result = new LinkedHashMap<String, InetAddress>(); - Enumeration<NetworkInterface> ne; - try { - ne = NetworkInterface.getNetworkInterfaces(); - } catch (SocketException e) { - log.warn("Local network interfaces are not resolvable: "+e); - ne = null; - } - while (ne != null && ne.hasMoreElements()) { - NetworkInterface nic = ne.nextElement(); - Enumeration<InetAddress> inets = nic.getInetAddresses(); - while (inets.hasMoreElements()) { - InetAddress inet = inets.nextElement(); - result.put(inet.getHostAddress(), inet); - } - } - if (result.isEmpty()) { - log.warn("No local network addresses found; assuming 127.0.0.1"); - InetAddress loop = Cidr.LOOPBACK.addressAtOffset(0); - result.put(loop.getHostAddress(), loop); - } - return result; - } - - /** returns a CIDR object for the given string, e.g. "10.0.0.0/8" */ - public static Cidr cidr(String cidr) { - return new Cidr(cidr); - } - - /** returns any well-known private network (e.g. 10.0.0.0/8 or 192.168.0.0/16) - * which the given IP is in, or the /32 of local address if none */ - public static Cidr getPrivateNetwork(String ip) { - Cidr me = new Cidr(ip+"/32"); - for (Cidr c: PRIVATE_NETWORKS) - if (c.contains(me)) - return c; - return me; - } - - public static Cidr getPrivateNetwork(InetAddress address) { - return getPrivateNetwork(address.getHostAddress()); - } - - /** returns whether the IP is _not_ in any private subnet */ - public static boolean isPublicIp(String ipAddress) { - Cidr me = new Cidr(ipAddress+"/32"); - for (Cidr c: Cidr.NON_PUBLIC_CIDRS) - if (c.contains(me)) return false; - return true; - } - - /** returns true if the supplied string matches any known IP (v4 or v6) for this machine, - * or if it can be resolved to any such address */ - public static boolean isLocalhost(String remoteAddress) { - Map<String, InetAddress> addresses = getLocalAddresses(); - if (addresses.containsKey(remoteAddress)) return true; - - if ("127.0.0.1".equals(remoteAddress)) return true; - - String modifiedIpV6Address = remoteAddress; - // IPv6 localhost "ip" strings may vary; - // comes back as 0:0:0:0:0:0:0:1%1 for me. - // following deals with the cases which seem likely. - // (svet suggests using InetAddress parsing but I -- Alex -- am not sure if that's going to have it's own bugs) - if (modifiedIpV6Address.contains("%")) { - // trim any description %dex - modifiedIpV6Address = modifiedIpV6Address.substring(0, modifiedIpV6Address.indexOf("%")); - } - if ("0:0:0:0:0:0:0:1".equals(modifiedIpV6Address)) return true; - if ("::1".equals(modifiedIpV6Address)) return true; - if (addresses.containsKey(remoteAddress) || addresses.containsKey(modifiedIpV6Address)) - return true; - - try { - InetAddress remote = InetAddress.getByName(remoteAddress); - if (addresses.values().contains(remote)) - return true; - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - log.debug("Error resolving address "+remoteAddress+" when checking if it is local (assuming not: "+e, e); - } - - return false; - } - - public static boolean isReachable(HostAndPort endpoint) { - try { - Socket s = new Socket(endpoint.getHostText(), endpoint.getPort()); - closeQuietly(s); - return true; - } catch (Exception e) { - if (log.isTraceEnabled()) log.trace("Error reaching "+endpoint+" during reachability check (return false)", e); - return false; - } - } - - public static void closeQuietly(Socket s) { - if (s != null) { - try { - s.close(); - } catch (IOException e) { - /* should not be thrown */ - } - } - } - - public static void closeQuietly(ServerSocket s) { - if (s != null) { - try { - s.close(); - } catch (IOException e) { - /* should not be thrown */ - } - } - } - - public static void closeQuietly(DatagramSocket s) { - if (s != null) { - s.close(); - } - } - - - // TODO go through nic's, looking for public, private, etc, on localhost - - /** - * force use of TLSv1, fixing: - * http://stackoverflow.com/questions/9828414/receiving-sslhandshakeexception-handshake-failure-despite-my-client-ignoring-al - */ - public static void installTlsOnlyForHttpsForcing() { - System.setProperty("https.protocols", "TLSv1"); - } - public static void installTlsForHttpsIfAppropriate() { - if (System.getProperty("https.protocols")==null && System.getProperty("brooklyn.https.protocols.leave_untouched")==null) { - installTlsOnlyForHttpsForcing(); - } - } - static { - installTlsForHttpsIfAppropriate(); - } - - /** does nothing, but forces the class to be loaded and do static initialization */ - public static void init() {} - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/net/Protocol.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/net/Protocol.java b/utils/common/src/main/java/brooklyn/util/net/Protocol.java deleted file mode 100644 index a91b1a3..0000000 --- a/utils/common/src/main/java/brooklyn/util/net/Protocol.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.net; - -public enum Protocol { - - TCP("tcp"), - UDP("udp"), - ICMP("icmp"), - ALL("all"); - - final String protocol; - - private Protocol(String protocol) { - this.protocol = protocol; - } - - @Override - public String toString() { - return protocol; - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/net/URLParamEncoder.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/net/URLParamEncoder.java b/utils/common/src/main/java/brooklyn/util/net/URLParamEncoder.java deleted file mode 100644 index 4ff3620..0000000 --- a/utils/common/src/main/java/brooklyn/util/net/URLParamEncoder.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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. - */ -package brooklyn.util.net; - -/** - * Encodes URLs, escaping as appropriate. - * - * Copied from fmucar's answer in http://stackoverflow.com/questions/724043/http-url-address-encoding-in-java - * - * TODO Want to use a library utility, but couldn't find this in guava and don't want to introduce - * dependency on commons-httpclient-3.1 to use URIUtil. - * - * @author aled - */ -public class URLParamEncoder { - - public static String encode(String input) { - StringBuilder resultStr = new StringBuilder(); - for (char ch : input.toCharArray()) { - if (isUnsafe(ch)) { - resultStr.append('%'); - resultStr.append(toHex(ch / 16)); - resultStr.append(toHex(ch % 16)); - } else { - resultStr.append(ch); - } - } - return resultStr.toString(); - } - - private static char toHex(int ch) { - return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10); - } - - private static boolean isUnsafe(char ch) { - if (ch > 128 || ch < 0) - return true; - return (" %$&+,/:;=?@<>#%" - // these are included in httpclient URI as "unwise", and have been found to be problematic - // * backslash in a query param breaks URI.create - + "\\" - ).indexOf(ch) >= 0; - } - -} \ No newline at end of file
