001package ball.beans;
002/*-
003 * ##########################################################################
004 * Utilities
005 * %%
006 * Copyright (C) 2008 - 2022 Allen D. Ball
007 * %%
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *      http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 * ##########################################################################
020 */
021import ball.swing.table.ArrayListTableModel;
022import java.beans.BeanInfo;
023import java.beans.IndexedPropertyDescriptor;
024import java.beans.PropertyDescriptor;
025import java.lang.reflect.Method;
026import java.lang.reflect.Type;
027import java.util.Arrays;
028import lombok.ToString;
029
030import static org.apache.commons.lang3.StringUtils.EMPTY;
031
032/**
033 * {@code BeanInfo} {@link PropertyDescriptor properties}
034 * {@link javax.swing.table.TableModel} implementation.
035 *
036 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
037 */
038@ToString
039public class PropertyDescriptorsTableModel extends ArrayListTableModel<PropertyDescriptor> {
040    private static final long serialVersionUID = -4799510974827528198L;
041
042    private static final String R = "R";
043    private static final String W = "W";
044
045    /**
046     * Sole constructor.
047     *
048     * @param   rows            The {@link PropertyDescriptor}s.
049     */
050    public PropertyDescriptorsTableModel(PropertyDescriptor[] rows) {
051        super(Arrays.asList(rows),
052              "Name", "Mode", "Type", "isHidden", "isBound", "isConstrained");
053    }
054
055    @Override
056    protected Object getValueAt(PropertyDescriptor row, int x) {
057        Object value = null;
058
059        switch (x) {
060        case 0:
061        default:
062            value = row.getName();
063            break;
064
065        case 1:
066            value = getMode(row);
067            break;
068
069        case 2:
070            value = getPropertyType(row);
071            break;
072
073        case 3:
074            value = row.isHidden();
075            break;
076
077        case 4:
078            value = row.isBound();
079            break;
080
081        case 5:
082            value = row.isConstrained();
083            break;
084        }
085
086        return value;
087    }
088
089    private String getMode(PropertyDescriptor descriptor) {
090        String mode = getMode(descriptor.getReadMethod(), descriptor.getWriteMethod());
091
092        if (descriptor instanceof IndexedPropertyDescriptor) {
093            mode += "[";
094            mode += getMode((IndexedPropertyDescriptor) descriptor);
095            mode += "]";
096        }
097
098        return mode;
099    }
100
101    private String getMode(IndexedPropertyDescriptor descriptor) {
102        return getMode(descriptor.getIndexedReadMethod(), descriptor.getIndexedWriteMethod());
103    }
104
105    private String getMode(Method read, Method write) {
106        return ((read != null) ? R : EMPTY) + ((write != null) ? W : EMPTY);
107    }
108
109    private Type getPropertyType(PropertyDescriptor descriptor) {
110        Type type = null;
111
112        if (descriptor instanceof IndexedPropertyDescriptor) {
113            type = getPropertyType((IndexedPropertyDescriptor) descriptor);
114        } else if (descriptor.getReadMethod() != null) {
115            type = descriptor.getReadMethod().getGenericReturnType();
116        } else if (descriptor.getWriteMethod() != null) {
117            type = descriptor.getWriteMethod().getGenericParameterTypes()[0];
118        } else {
119            type = descriptor.getPropertyType();
120        }
121
122        return type;
123    }
124
125    private Type getPropertyType(IndexedPropertyDescriptor descriptor) {
126        Type type = null;
127
128        if (descriptor.getIndexedReadMethod() != null) {
129            type = descriptor.getIndexedReadMethod().getGenericReturnType();
130        } else if (descriptor.getIndexedWriteMethod() != null) {
131            type = descriptor.getIndexedWriteMethod().getGenericParameterTypes()[1];
132        } else {
133            type = descriptor.getIndexedPropertyType();
134        }
135
136        return type;
137    }
138}