/* * 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 org.apache.catalina.tribes.util; import java.util.ArrayList; import java.util.List; import org.apache.catalina.tribes.ChannelMessage; import org.apache.catalina.tribes.Member; import org.apache.catalina.tribes.UniqueId; import org.apache.catalina.tribes.group.AbsoluteOrder; import org.apache.catalina.tribes.membership.MemberImpl; import org.apache.catalina.tribes.membership.Membership; import java.io.UnsupportedEncodingException; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import java.util.StringTokenizer; /** * @author Filip Hanik * @version 1.0 */ public class Arrays { protected static Log log = LogFactory.getLog(Arrays.class); public static boolean contains(byte[] source, int srcoffset, byte[] key, int keyoffset, int length) { if ( srcoffset < 0 || srcoffset >= source.length) throw new ArrayIndexOutOfBoundsException("srcoffset is out of bounds."); if ( keyoffset < 0 || keyoffset >= key.length) throw new ArrayIndexOutOfBoundsException("keyoffset is out of bounds."); if ( length > (key.length-keyoffset) ) throw new ArrayIndexOutOfBoundsException("not enough data elements in the key, length is out of bounds."); //we don't have enough data to validate it if ( length > (source.length-srcoffset) ) return false; boolean match = true; int pos = keyoffset; for ( int i=srcoffset; match && i<length; i++ ) { match = (source[i] == key[pos++]); } return match; } public static String toString(byte[] data) { return toString(data,0,data!=null?data.length:0); } public static String toString(byte[] data, int offset, int length) { return toString(data,offset,length,false); } public static String toString(byte[] data, int offset, int length, boolean unsigned) { StringBuffer buf = new StringBuffer("{"); if ( data != null && length > 0 ) { int i = offset; if (unsigned) { buf.append(data[i++] & 0xff); for (; i < length; i++) { buf.append(", ").append(data[i] & 0xff); } } else { buf.append(data[i++]); for (; i < length; i++) { buf.append(", ").append(data[i]); } } } buf.append("}"); return buf.toString(); } public static String toString(Object[] data) { return toString(data,0,data!=null?data.length:0); } public static String toString(Object[] data, int offset, int length) { StringBuffer buf = new StringBuffer("{"); if ( data != null && length > 0 ) { buf.append(data[offset++]); for (int i = offset; i < length; i++) { buf.append(", ").append(data[i]); } } buf.append("}"); return buf.toString(); } public static String toNameString(Member[] data) { return toNameString(data,0,data!=null?data.length:0); } public static String toNameString(Member[] data, int offset, int length) { StringBuffer buf = new StringBuffer("{"); if ( data != null && length > 0 ) { buf.append(data[offset++].getName()); for (int i = offset; i < length; i++) { buf.append(", ").append(data[i].getName()); } } buf.append("}"); return buf.toString(); } public static int add(int[] data) { int result = 0; for (int i=0;i<data.length; i++ ) result += data[i]; return result; } public static UniqueId getUniqudId(ChannelMessage msg) { return new UniqueId(msg.getUniqueId()); } public static UniqueId getUniqudId(byte[] data) { return new UniqueId(data); } public static boolean equals(byte[] o1, byte[] o2) { return java.util.Arrays.equals(o1,o2); } public static boolean equals(Object[] o1, Object[] o2) { boolean result = o1.length == o2.length; if ( result ) for (int i=0; i<o1.length && result; i++ ) result = o1[i].equals(o2[i]); return result; } public static boolean sameMembers(Member[] m1, Member[] m2) { AbsoluteOrder.absoluteOrder(m1); AbsoluteOrder.absoluteOrder(m2); return equals(m1,m2); } public static Member[] merge(Member[] m1, Member[] m2) { AbsoluteOrder.absoluteOrder(m1); AbsoluteOrder.absoluteOrder(m2); ArrayList list = new ArrayList(java.util.Arrays.asList(m1)); for (int i=0; i<m2.length; i++) if ( !list.contains(m2[i]) ) list.add(m2[i]); Member[] result = new Member[list.size()]; list.toArray(result); AbsoluteOrder.absoluteOrder(result); return result; } public static void fill(Membership mbrship, Member[] m) { for (int i=0; i<m.length; i++ ) mbrship.addMember((MemberImpl)m[i]); } public static Member[] diff(Membership complete, Membership local, MemberImpl ignore) { ArrayList result = new ArrayList(); MemberImpl[] comp = complete.getMembers(); for ( int i=0; i<comp.length; i++ ) { if ( ignore!=null && ignore.equals(comp[i]) ) continue; if ( local.getMember(comp[i]) == null ) result.add(comp[i]); } return (MemberImpl[])result.toArray(new MemberImpl[result.size()]); } public static Member[] remove(Member[] all, Member remove) { return extract(all,new Member[] {remove}); } public static Member[] extract(Member[] all, Member[] remove) { List alist = java.util.Arrays.asList(all); ArrayList list = new ArrayList(alist); for (int i=0; i<remove.length; i++ ) list.remove(remove[i]); return (Member[])list.toArray(new Member[list.size()]); } public static int indexOf(Member member, Member[] members) { int result = -1; for (int i=0; (result==-1) && (i<members.length); i++ ) if ( member.equals(members[i]) ) result = i; return result; } public static int nextIndex(Member member, Member[] members) { int idx = indexOf(member,members)+1; if (idx >= members.length ) idx = ((members.length>0)?0:-1); //System.out.println("Next index:"+idx); //System.out.println("Member:"+member.getName()); //System.out.println("Members:"+toNameString(members)); return idx; } public static int hashCode(byte a[]) { if (a == null) return 0; int result = 1; for (int i=0; i<a.length; i++) { byte element = a[i]; result = 31 * result + element; } return result; } public static byte[] fromString(String value) { if ( value == null ) return null; if ( !value.startsWith("{") ) throw new RuntimeException("byte arrays must be represented as {1,3,4,5,6}"); StringTokenizer t = new StringTokenizer(value,"{,}",false); byte[] result = new byte[t.countTokens()]; for (int i=0; i<result.length; i++ ) result[i] = Byte.parseByte(t.nextToken()); return result; } public static byte[] convert(String s) { try { return s.getBytes("ISO-8859-1"); }catch (UnsupportedEncodingException ux ) { log.error("Unable to convert ["+s+"] into a byte[] using ISO-8859-1 encoding, falling back to default encoding."); return s.getBytes(); } } }