001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.io.comparator; 018 019 import java.io.File; 020 import java.io.Serializable; 021 import java.util.ArrayList; 022 import java.util.Comparator; 023 import java.util.List; 024 025 /** 026 * Compare two files using a set of delegate file {@link Comparator}. 027 * <p> 028 * This comparator can be used to sort lists or arrays of files 029 * by combining a number other comparators. 030 * <p> 031 * Example of sorting a list of files by type (i.e. directory or file) 032 * and then by name: 033 * <pre> 034 * CompositeFileComparator comparator = 035 * new CompositeFileComparator( 036 * DirectoryFileComparator.DIRECTORY_COMPARATOR, 037 * NameFileComparator.NAME_COMPARATOR); 038 * List<File> list = ... 039 * comparator.sort(list); 040 * </pre> 041 * 042 * @version $Id: CompositeFileComparator.java 1304052 2012-03-22 20:55:29Z ggregory $ 043 * @since 2.0 044 */ 045 public class CompositeFileComparator extends AbstractFileComparator implements Serializable { 046 047 private static final Comparator<?>[] NO_COMPARATORS = {}; 048 private final Comparator<File>[] delegates; 049 050 /** 051 * Create a composite comparator for the set of delegate comparators. 052 * 053 * @param delegates The delegate file comparators 054 */ 055 @SuppressWarnings("unchecked") // casts 1 & 2 must be OK because types are already correct 056 public CompositeFileComparator(Comparator<File>... delegates) { 057 if (delegates == null) { 058 this.delegates = (Comparator<File>[]) NO_COMPARATORS;//1 059 } else { 060 this.delegates = (Comparator<File>[]) new Comparator<?>[delegates.length];//2 061 System.arraycopy(delegates, 0, this.delegates, 0, delegates.length); 062 } 063 } 064 065 /** 066 * Create a composite comparator for the set of delegate comparators. 067 * 068 * @param delegates The delegate file comparators 069 */ 070 @SuppressWarnings("unchecked") // casts 1 & 2 must be OK because types are already correct 071 public CompositeFileComparator(Iterable<Comparator<File>> delegates) { 072 if (delegates == null) { 073 this.delegates = (Comparator<File>[]) NO_COMPARATORS; //1 074 } else { 075 List<Comparator<File>> list = new ArrayList<Comparator<File>>(); 076 for (Comparator<File> comparator : delegates) { 077 list.add(comparator); 078 } 079 this.delegates = (Comparator<File>[]) list.toArray(new Comparator<?>[list.size()]); //2 080 } 081 } 082 083 /** 084 * Compare the two files using delegate comparators. 085 * 086 * @param file1 The first file to compare 087 * @param file2 The second file to compare 088 * @return the first non-zero result returned from 089 * the delegate comparators or zero. 090 */ 091 public int compare(File file1, File file2) { 092 int result = 0; 093 for (Comparator<File> delegate : delegates) { 094 result = delegate.compare(file1, file2); 095 if (result != 0) { 096 break; 097 } 098 } 099 return result; 100 } 101 102 /** 103 * String representation of this file comparator. 104 * 105 * @return String representation of this file comparator 106 */ 107 @Override 108 public String toString() { 109 StringBuilder builder = new StringBuilder(); 110 builder.append(super.toString()); 111 builder.append('{'); 112 for (int i = 0; i < delegates.length; i++) { 113 if (i > 0) { 114 builder.append(','); 115 } 116 builder.append(delegates[i]); 117 } 118 builder.append('}'); 119 return builder.toString(); 120 } 121 }