001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *        http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 */
019
020package org.apache.isis.core.commons.lang;
021
022import java.util.ArrayList;
023import java.util.Arrays;
024import java.util.Collection;
025import java.util.Collections;
026import java.util.List;
027
028import com.google.common.collect.Collections2;
029import com.google.common.collect.Lists;
030
031public final class ListExtensions {
032    private static final String DEFAULT_DELIMITER = ",";
033
034    private ListExtensions() {
035    }
036
037    public static <T> List<T> combineWith(final List<T> extendee, final List<T> list2) {
038        final List<T> combinedList = Lists.newArrayList();
039        combinedList.addAll(extendee);
040        combinedList.addAll(list2);
041        return combinedList;
042    }
043
044    /**
045     * Returns list1 with everything in list2, ignoring duplicates.
046     */
047    public static <T> List<T> mergeWith(final List<T> extendee, final List<T> list2) {
048        for (final T obj : list2) {
049            if (!(extendee.contains(obj))) {
050                extendee.add(obj);
051            }
052        }
053        return extendee;
054    }
055
056
057    /**
058     * @see #listToString(List, String)
059     * @see #stringToList(String)
060     */
061    public static String listToString(final List<String> list) {
062        return listToString(list, DEFAULT_DELIMITER);
063    }
064
065    /**
066     * @see #listToString(List, String)
067     * @see #stringToList(String)
068     */
069    public static String listToString(final List<String> list, final String delimiter) {
070        if (list.size() == 0) {
071            return null;
072        }
073        final StringBuilder buf = new StringBuilder();
074        boolean first = true;
075        for (final String str : list) {
076            if (first) {
077                first = false;
078            } else {
079                buf.append(delimiter);
080            }
081            buf.append(str);
082        }
083        return buf.toString();
084    }
085
086    /**
087     * @see #stringToList(String, String)
088     * @see #listToString(List)
089     */
090    public static List<String> stringToList(final String commaSeparated) {
091        return appendDelimitedStringToList(commaSeparated, new ArrayList<String>());
092    }
093
094    /**
095     * @see #stringToList(String)
096     * @see #listToString(List, String)
097     */
098    public static List<String> stringToList(final String delimited, final String delimiter) {
099        return appendDelimitedStringToList(delimited, delimiter, new ArrayList<String>());
100    }
101
102    /**
103     * @see #appendDelimitedStringToList(String, String, List)
104     */
105    public static List<String> appendDelimitedStringToList(final String commaSeparated, final List<String> list) {
106        return appendDelimitedStringToList(commaSeparated, DEFAULT_DELIMITER, list);
107    }
108
109    public static List<String> appendDelimitedStringToList(final String delimited, final String delimiter, final List<String> list) {
110        if (delimited == null) {
111            return list;
112        }
113        final String[] optionValues = delimited.split(delimiter);
114        list.addAll(Arrays.asList(optionValues));
115        return list;
116    }
117    
118    // //////////////////////////////////////
119    
120    public static <T> List<T> mutableCopy(final List<T> input) {
121        return Lists.newArrayList(input != null? input: Collections.<T>emptyList());
122    }
123
124    public static <T> List<T> mutableCopy(T[] arr) {
125        return mutableCopy(arr != null? Arrays.asList(arr): Collections.<T>emptyList()) ;
126    }
127
128    public static <T> void insert(final List<T> list, final int insertionPoint, final T elementToInsert) {
129        extend(list, insertionPoint);
130        list.add(insertionPoint, elementToInsert);
131    }
132    
133    public static <T> void adjust(final List<T> list, final int requiredLength) {
134        extend(list, requiredLength);
135        if(list.size() > requiredLength) {
136            list.subList(requiredLength, list.size()).clear();;
137        }
138    }
139
140    private static <T> void extend(final List<T> list, final int requiredLength) {
141        for(int i=list.size(); i<requiredLength; i++) {
142            list.add(null);
143        }
144    }
145
146    public static <T> Collection<T> filtered(final List<Object> extendee, final Class<T> type) {
147        return Collections2.transform(
148                    Collections2.filter(extendee, ClassPredicates.isOfType(type)),
149                ClassFunctions.castTo(type));
150    }
151
152    
153
154
155}