# GeneralPane.java

    /*
     * Copyright (c) 2009, Tony Kohar. All Rights Reserved.
     *
     * Licensed  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.qi4j.envisage.detail;

    import java.awt.BorderLayout;
    import java.util.ArrayList;
    import java.util.ResourceBundle;
    import javax.swing.JComponent;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.TableColumnModel;
    import org.qi4j.api.composite.CompositeDescriptor;
    import org.qi4j.api.entity.EntityDescriptor;
    import org.qi4j.api.object.ObjectDescriptor;
    import org.qi4j.api.service.ServiceDescriptor;
    import org.qi4j.api.value.ValueDescriptor;
    import org.qi4j.envisage.util.TableRow;
    import org.qi4j.tools.model.descriptor.EntityDetailDescriptor;
    import org.qi4j.tools.model.descriptor.ImportedServiceCompositeDescriptor;
    import org.qi4j.tools.model.descriptor.ImportedServiceDetailDescriptor;
    import org.qi4j.tools.model.descriptor.ObjectDetailDescriptor;
    import org.qi4j.tools.model.descriptor.ServiceDetailDescriptor;
    import org.qi4j.tools.model.descriptor.TransientDetailDescriptor;
    import org.qi4j.tools.model.descriptor.ValueDetailDescriptor;

    import static org.qi4j.functional.Iterables.first;

    /**
     * Implementation of General DetailPane
     */
    /* package */ final class GeneralPane
        extends DetailPane
    {
        private static final ResourceBundle BUNDLE = ResourceBundle.getBundle( GeneralPane.class.getName() );

        private JPanel contentPane;
        private JTable table;
        private final GeneralTableModel tableModel;

        /* package */ GeneralPane( DetailModelPane detailModelPane )
        {
            super( detailModelPane );
            this.setLayout( new BorderLayout() );
            this.add( contentPane, BorderLayout.CENTER );

            tableModel = new GeneralTableModel();
            table.setModel( tableModel );

            TableColumnModel columnModel = table.getColumnModel();
            columnModel.getColumn( 0 ).setPreferredWidth( 90 );
            columnModel.getColumn( 1 ).setPreferredWidth( 550 );
        }

        private void clear()
        {
            tableModel.clear();
        }

        @Override
        protected void setDescriptor( Object objectDesciptor )
        {
            clear();
            tableModel.reload( objectDesciptor );
        }

        {
    // GUI initializer generated by IntelliJ IDEA GUI Designer
    // >>> IMPORTANT!! <<<
    // DO NOT EDIT OR ADD ANY CODE HERE!
            $$$setupUI$$$();
        }

        /**
         * Method generated by IntelliJ IDEA GUI Designer
         * >>> IMPORTANT!! <<<
         * DO NOT edit this method OR call it in your code!
         *
         */
        private void $$$setupUI$$$()
        {
            contentPane = new JPanel();
            contentPane.setLayout( new BorderLayout( 0, 0 ) );
            final JScrollPane scrollPane1 = new JScrollPane();
            contentPane.add( scrollPane1, BorderLayout.CENTER );
            table = new JTable();
            scrollPane1.setViewportView( table );
        }

        public JComponent $$$getRootComponent$$$()
        {
            return contentPane;
        }

        private static class GeneralTableModel
            extends AbstractTableModel
        {
            /**
             * the column names for this model
             */
            private static final String[] COLUMN_NAMES =
            {
                BUNDLE.getString( "Name.Column" ),
                BUNDLE.getString( "Value.Column" )
            };
            private final ArrayList<TableRow> rows;

            private final String nameRow = "name";
            private final String classRow = "class";
            private final String visibilityRow = "visibility";
            private final String moduleRow = "module";
            private final String layerRow = "layer";

            private GeneralTableModel()
            {
                rows = new ArrayList<>();
            }

            private void reload( Object objectDesciptor )
            {
                if( objectDesciptor instanceof ServiceDetailDescriptor )
                {
                    ServiceDescriptor descriptor = ( (ServiceDetailDescriptor) objectDesciptor ).descriptor();
                    Class<?> type = first( descriptor.types() );
                    rows.add( new TableRow( 2, nameRow, type.getSimpleName() ) );
                    rows.add( new TableRow( 2, classRow, type.getName() ) );
                    rows.add( new TableRow( 2, visibilityRow, descriptor.visibility().toString() ) );
                    rows.add( new TableRow( 2, moduleRow, ( (ServiceDetailDescriptor) objectDesciptor ).module() ) );
                    rows.add( new TableRow( 2, layerRow, ( (ServiceDetailDescriptor) objectDesciptor ).module().layer() ) );
                    rows.add( new TableRow( 2, "startup", ( (ServiceDetailDescriptor) objectDesciptor ).descriptor().isInstantiateOnStartup() ) );
                }
                else if( objectDesciptor instanceof ImportedServiceDetailDescriptor )
                {
                    ImportedServiceCompositeDescriptor descriptor = ( (ImportedServiceDetailDescriptor) objectDesciptor ).descriptor();
                    rows.add( new TableRow( 2, nameRow, descriptor.primaryType().getSimpleName() ) );
                    rows.add( new TableRow( 2, classRow, descriptor.primaryType().getName() ) );
                    rows.add( new TableRow( 2, visibilityRow, descriptor.visibility().toString() ) );
                    rows.add( new TableRow( 2, moduleRow, ( (ImportedServiceDetailDescriptor) objectDesciptor ).module() ) );
                    rows.add( new TableRow( 2, layerRow, ( (ImportedServiceDetailDescriptor) objectDesciptor ).module().layer() ) );
                }
                else if( objectDesciptor instanceof EntityDetailDescriptor )
                {
                    EntityDescriptor descriptor = ( (EntityDetailDescriptor) objectDesciptor ).descriptor();
                    Class<?> type = first( descriptor.types() );
                    rows.add( new TableRow( 2, nameRow, type.getSimpleName() ) );
                    rows.add( new TableRow( 2, classRow, type.getName() ) );
                    rows.add( new TableRow( 2, visibilityRow, descriptor.visibility().toString() ) );
                    rows.add( new TableRow( 2, moduleRow, ( (EntityDetailDescriptor) objectDesciptor ).module() ) );
                    rows.add( new TableRow( 2, layerRow, ( (EntityDetailDescriptor) objectDesciptor ).module().layer() ) );
                }
                else if( objectDesciptor instanceof ValueDetailDescriptor )
                {
                    ValueDescriptor descriptor = ( (ValueDetailDescriptor) objectDesciptor ).descriptor();
                    Class<?> type = first( descriptor.types() );
                    rows.add( new TableRow( 2, new Object[]
                    {
                        nameRow, type.getSimpleName()
                    } ) );
                    rows.add( new TableRow( 2, new Object[]
                    {
                        classRow, type.getName()
                    } ) );
                    rows.add( new TableRow( 2, new Object[]
                    {
                        visibilityRow, descriptor.visibility().toString()
                    } ) );
                    rows.add( new TableRow( 2, new Object[]
                    {
                        moduleRow, ( (ValueDetailDescriptor) objectDesciptor ).module()
                    } ) );
                    rows.add( new TableRow( 2, new Object[]
                    {
                        layerRow, ( (ValueDetailDescriptor) objectDesciptor ).module().layer()
                    } ) );
                }
                else if( objectDesciptor instanceof ObjectDetailDescriptor )
                {
                    ObjectDescriptor descriptor = ( (ObjectDetailDescriptor) objectDesciptor ).descriptor();
                    Class<?> type = first( descriptor.types() );
                    rows.add( new TableRow( 2, nameRow, type.getSimpleName() ) );
                    rows.add( new TableRow( 2, classRow, type.getName() ) );
                    rows.add( new TableRow( 2, visibilityRow, descriptor.visibility().toString() ) );
                    rows.add( new TableRow( 2, moduleRow, ( (ObjectDetailDescriptor) objectDesciptor ).module() ) );
                    rows.add( new TableRow( 2, layerRow, ( (ObjectDetailDescriptor) objectDesciptor ).module().layer() ) );
                }
                else if( objectDesciptor instanceof TransientDetailDescriptor )
                {
                    CompositeDescriptor descriptor = ( (TransientDetailDescriptor) objectDesciptor ).descriptor();
                    Class<?> type = first( descriptor.types() );
                    rows.add( new TableRow( 2, nameRow, type.getSimpleName() ) );
                    rows.add( new TableRow( 2, classRow, type.getName() ) );
                    rows.add( new TableRow( 2, visibilityRow, descriptor.visibility().toString() ) );
                    rows.add( new TableRow( 2, moduleRow, ( (TransientDetailDescriptor) objectDesciptor ).module() ) );
                    rows.add( new TableRow( 2, layerRow, ( (TransientDetailDescriptor) objectDesciptor ).module().layer() ) );
                }

                fireTableDataChanged();
            }

            @Override
            public Object getValueAt( int rowIndex, int columnIndex )
            {
                TableRow row = this.rows.get( rowIndex );
                return row.get( columnIndex );
            }

            private void clear()
            {
                rows.clear();
                fireTableDataChanged();
            }

            @Override
            public int getColumnCount()
            {
                return COLUMN_NAMES.length;
            }

            @Override
            public String getColumnName( int col )
            {
                return COLUMN_NAMES[ col];
            }

            @Override
            public int getRowCount()
            {
                return rows.size();
            }
        }

    }