HSAdmin Backend Domains, E-Mail, Datenbanken
Peter Hormanns
2011-03-21 c00b2ef3c47164503387487a14bc1acbd2cbd42b
Refactorings
13 files added
1 files deleted
11 files modified
1513 ■■■■■ changed files
hsarweb/src/de/hsadmin/web/AbstractModule.java 134 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/DeleteAble.java 9 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/DomainModule.java 21 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/EMailAddressModule.java 37 ●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/EMailAliasModule.java 13 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/GenericModule.java 492 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/InsertAble.java 9 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/MainApplication.java 14 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/Module.java 17 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/QueueTaskModule.java 6 ●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/SearchAble.java 6 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/UnixUserModule.java 22 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/UpdateAble.java 9 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/config/ComponentFactory.java 11 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/config/ModuleConfig.java 46 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/config/PropertyConfig.java 38 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/config/PropertyFieldFactory.java 19 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/config/PropertyFormField.java 10 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/vaadin/DefaultPropertyFieldFactory.java 51 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/vaadin/GenericForm.java 102 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/vaadin/PasswordPropertyFieldFactory.java 79 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/vaadin/SelectPropertyFieldFactory.java 64 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/vaadin/TableComponentFactory.java 296 ●●●●● patch | view | raw | blame | history
hsarweb/src/texts/user.properties 3 ●●●● patch | view | raw | blame | history
hsarweb/src/texts/user_de.properties 5 ●●●●● patch | view | raw | blame | history
hsarweb/src/de/hsadmin/web/AbstractModule.java
New file
@@ -0,0 +1,134 @@
package de.hsadmin.web;
import java.util.HashMap;
import java.util.Map;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.terminal.Sizeable;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Link;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;
import de.hsadmin.web.config.ComponentFactory;
import de.hsadmin.web.config.LocaleConfig;
import de.hsadmin.web.config.ModuleConfig;
import de.hsadmin.web.vaadin.GenericForm;
import de.hsadmin.web.vaadin.TableComponentFactory;
public abstract class AbstractModule implements Module {
    private MainApplication application;
    private VerticalLayout layout;
    private Component component;
    private ComponentFactory componentFactory;
    public Component getComponent() {
        return layout;
    }
    public void reload() throws HsarwebException {
        componentFactory.loadData();
    }
    private void initLayout() {
        layout = new VerticalLayout();
        layout.setSizeFull();
        final Module thisModule = this;
        final ModuleConfig moduleConfig = getModuleConfig();
        final LocaleConfig localeConfig = application.getLocaleConfig();
        if (this instanceof SearchAble || this instanceof InsertAble) {
            HorizontalLayout toolbar = new HorizontalLayout();
            if (this instanceof InsertAble) {
                Button btNew = new Button(moduleConfig.getLabel("new"));
                ThemeResource icon = new ThemeResource("../runo/icons/16/document-add.png");
                btNew.setIcon(icon);
                btNew.addListener(new Button.ClickListener() {
                    private static final long serialVersionUID = 1L;
                    private Window childWindow;
                    @Override
                    public void buttonClick(ClickEvent event) {
                        final GenericForm genericForm = new GenericForm(thisModule, null);
                        final Form form = genericForm.createAddForm();
                        childWindow = new Window(localeConfig.getText("new"));
                        childWindow.setWidth(640.0f, Sizeable.UNITS_PIXELS);
                        VerticalLayout vLayout = new VerticalLayout();
                        vLayout.setMargin(true);
                        vLayout.setSpacing(true);
                        vLayout.addComponent(form);
                        HorizontalLayout hLayout = new HorizontalLayout();
                        Button btSaveRow = new Button(localeConfig.getText("save"));
                        btSaveRow.addListener(new Button.ClickListener() {
                            private static final long serialVersionUID = 1L;
                            @Override
                            public void buttonClick(ClickEvent event) {
                                application.getMainWindow().removeWindow(childWindow);
                                try {
                                    Map<String, String> map = new HashMap<String, String>();
                                    genericForm.transferToHash(map, form);
                                    ((InsertAble) thisModule).insertRow(map);
                                    componentFactory.loadData();
                                } catch (HsarwebException e) {
                                    application.showUserException(e);
                                }
                            }
                        });
                        Button btAbort = new Button(localeConfig.getText("abort"));
                        btAbort.addListener(new Button.ClickListener() {
                            private static final long serialVersionUID = 1L;
                            @Override
                            public void buttonClick(ClickEvent event) {
                                application.getMainWindow().removeWindow(childWindow);
                            }
                        });
                        hLayout.addComponent(btSaveRow);
                        hLayout.addComponent(btAbort);
                        vLayout.addComponent(hLayout);
                        childWindow.setContent(vLayout);
                        childWindow.setModal(true);
                        application.getMainWindow().addWindow(childWindow);
                    }
                });
                toolbar.addComponent(btNew);
            }
//            if (this instanceof SearchAble) {
//                Button btSearch = new Button("search");
//                toolbar.addComponent(btSearch);
//            }
            layout.addComponent(toolbar);
        }
        layout.addComponent(component);
        layout.setExpandRatio(component, 1.0f);
        layout.addComponent(new Link(localeConfig.getText("impressum.label"), new ExternalResource(localeConfig.getText("impressum.link"))));
    }
    public void setApplication(MainApplication app) throws HsarwebException {
        application = app;
        initModule();
        if (componentFactory == null) {
            componentFactory = new TableComponentFactory(this);
        }
        component = (Component) componentFactory.initComponent();
        initLayout();
    }
    protected abstract void initModule();
    public MainApplication getApplication() {
        return application;
    }
    public void setComponentFactory(ComponentFactory componentFactory) {
        this.componentFactory = componentFactory;
    }
    @Override
    public abstract ModuleConfig getModuleConfig();
}
hsarweb/src/de/hsadmin/web/DeleteAble.java
New file
@@ -0,0 +1,9 @@
package de.hsadmin.web;
import java.util.Map;
public interface DeleteAble {
    public void deleteRow(Map<String, String> paramHash) throws HsarwebException;
}
hsarweb/src/de/hsadmin/web/DomainModule.java
@@ -10,9 +10,9 @@
import de.hsadmin.web.config.ModuleConfig;
import de.hsadmin.web.config.PropertyConfig;
import de.hsadmin.web.config.PropertyDefaultValue;
import de.hsadmin.web.config.PropertyFormField;
import de.hsadmin.web.config.PropertySelectValues;
import de.hsadmin.web.config.PropertyTableColumn;
import de.hsadmin.web.vaadin.SelectPropertyFieldFactory;
public class DomainModule extends GenericModule {
@@ -23,12 +23,13 @@
    @Override
    protected void initModule() {
        moduleConfig = new ModuleConfig("domain");
        moduleConfig.setUpdateAble(false);
        String login = getApplication().getLogin();
        final String pac = login.length() >= 5 ? login.substring(0, 5) : "";
        PropertyConfig idProp = new PropertyConfig(moduleConfig, "id", Long.class, PropertyTableColumn.INTERNAL_KEY, PropertyFormField.INTERNAL_KEY);
        PropertyConfig nameProp = new PropertyConfig(moduleConfig, "name", String.class, PropertyFormField.WRITEONCE);
        PropertyConfig userProp = new PropertyConfig(moduleConfig, "user", String.class, PropertyFormField.WRITEONCE);
        PropertyConfig idProp = new PropertyConfig(moduleConfig, "id", Long.class, PropertyTableColumn.INTERNAL_KEY);
        idProp.setReadOnly(true);
        PropertyConfig nameProp = new PropertyConfig(moduleConfig, "name", String.class);
        nameProp.setWriteOnce(true);
        PropertyConfig userProp = new PropertyConfig(moduleConfig, "user", String.class, new SelectPropertyFieldFactory());
        userProp.setDefaultValue(new PropertyDefaultValue() {
            @Override
            public String getDefaultValue() {
@@ -54,15 +55,19 @@
                return map;
            }
        });
        PropertyConfig pacProp = new PropertyConfig(moduleConfig, "pac", String.class, PropertyTableColumn.HIDDEN, PropertyFormField.READONLY);
        userProp.setWriteOnce(true);
        PropertyConfig pacProp = new PropertyConfig(moduleConfig, "pac", String.class, PropertyTableColumn.HIDDEN);
        pacProp.setDefaultValue(new PropertyDefaultValue() {
            @Override
            public String getDefaultValue() {
                return pac;
            }
        });
        PropertyConfig hiveProp = new PropertyConfig(moduleConfig, "hive", String.class, PropertyTableColumn.HIDDEN, PropertyFormField.NONE);
        PropertyConfig sinceProp = new PropertyConfig(moduleConfig, "since", Date.class, PropertyFormField.READONLY);
        pacProp.setReadOnly(true);
        PropertyConfig hiveProp = new PropertyConfig(moduleConfig, "hive", String.class, PropertyTableColumn.HIDDEN);
        hiveProp.setReadOnly(true);
        PropertyConfig sinceProp = new PropertyConfig(moduleConfig, "since", Date.class);
        sinceProp.setReadOnly(true);
        moduleConfig.addProperty(idProp);
        moduleConfig.addProperty(nameProp);
        moduleConfig.addProperty(userProp);
hsarweb/src/de/hsadmin/web/EMailAddressModule.java
@@ -9,9 +9,9 @@
import de.hsadmin.web.config.ModuleConfig;
import de.hsadmin.web.config.PropertyConfig;
import de.hsadmin.web.config.PropertyDefaultValue;
import de.hsadmin.web.config.PropertyFormField;
import de.hsadmin.web.config.PropertySelectValues;
import de.hsadmin.web.config.PropertyTableColumn;
import de.hsadmin.web.vaadin.SelectPropertyFieldFactory;
public class EMailAddressModule extends GenericModule {
@@ -24,12 +24,16 @@
        moduleConfig = new ModuleConfig("emailaddress");
        String login = getApplication().getLogin();
        final String pac = login.length() >= 5 ? login.substring(0, 5) : "";
        moduleConfig.addProperty(new PropertyConfig(moduleConfig, "id", Long.class, PropertyTableColumn.INTERNAL_KEY, PropertyFormField.INTERNAL_KEY));
        moduleConfig.addProperty(new PropertyConfig(moduleConfig, "emailaddress", String.class, PropertyFormField.NONE));
        moduleConfig.addProperty(new PropertyConfig(moduleConfig, "localpart", String.class, PropertyTableColumn.HIDDEN, PropertyFormField.WRITEONCE));
        moduleConfig.addProperty(new PropertyConfig(moduleConfig, "subdomain", String.class, PropertyTableColumn.HIDDEN, PropertyFormField.WRITEONCE));
        PropertyConfig DomainProp = new PropertyConfig(moduleConfig, "domain", String.class, PropertyTableColumn.HIDDEN, PropertyFormField.WRITEONCE);
        DomainProp.setSelectValues(new PropertySelectValues() {
        PropertyConfig idProp = new PropertyConfig(moduleConfig, "id", Long.class, PropertyTableColumn.INTERNAL_KEY);
        idProp.setReadOnly(true);
        PropertyConfig fullAddressProp = new PropertyConfig(moduleConfig, "emailaddress", String.class);
        fullAddressProp.setReadOnly(true);
        PropertyConfig localpartProp = new PropertyConfig(moduleConfig, "localpart", String.class, PropertyTableColumn.HIDDEN);
        localpartProp.setWriteOnce(true);
        PropertyConfig subdomainProp = new PropertyConfig(moduleConfig, "subdomain", String.class, PropertyTableColumn.HIDDEN);
        subdomainProp.setWriteOnce(true);
        PropertyConfig domainProp = new PropertyConfig(moduleConfig, "domain", String.class, PropertyTableColumn.HIDDEN, new SelectPropertyFieldFactory());
        domainProp.setSelectValues(new PropertySelectValues() {
            @Override
            public boolean newItemsAllowed() {
                return false;
@@ -48,7 +52,7 @@
                return map;
            }
        });
        moduleConfig.addProperty(DomainProp);
        domainProp.setWriteOnce(true);
        PropertyConfig targetProp = new PropertyConfig(moduleConfig, "target", String.class);
        targetProp.setDefaultValue(new PropertyDefaultValue() {
            @Override
@@ -56,10 +60,21 @@
                return pac + "-";
            }
        });
        PropertyConfig domAdminProp = new PropertyConfig(moduleConfig, "admin", String.class, PropertyTableColumn.HIDDEN);
        domAdminProp.setReadOnly(true);
        PropertyConfig pacProp = new PropertyConfig(moduleConfig, "pac", String.class, PropertyTableColumn.HIDDEN);
        pacProp.setReadOnly(true);
        PropertyConfig fulldomainProp = new PropertyConfig(moduleConfig, "fulldomain", String.class, PropertyTableColumn.HIDDEN);
        fulldomainProp.setReadOnly(true);
        moduleConfig.addProperty(idProp);
        moduleConfig.addProperty(fullAddressProp);
        moduleConfig.addProperty(localpartProp);
        moduleConfig.addProperty(subdomainProp);
        moduleConfig.addProperty(domainProp);
        moduleConfig.addProperty(targetProp);
        moduleConfig.addProperty(new PropertyConfig(moduleConfig, "admin", String.class, PropertyTableColumn.HIDDEN, PropertyFormField.NONE));
        moduleConfig.addProperty(new PropertyConfig(moduleConfig, "pac", String.class, PropertyTableColumn.HIDDEN, PropertyFormField.NONE));
        moduleConfig.addProperty(new PropertyConfig(moduleConfig, "fulldomain", String.class, PropertyTableColumn.HIDDEN, PropertyFormField.NONE));
        moduleConfig.addProperty(domAdminProp);
        moduleConfig.addProperty(pacProp);
        moduleConfig.addProperty(fulldomainProp);
    }
    
    @Override
hsarweb/src/de/hsadmin/web/EMailAliasModule.java
@@ -3,7 +3,6 @@
import de.hsadmin.web.config.ModuleConfig;
import de.hsadmin.web.config.PropertyConfig;
import de.hsadmin.web.config.PropertyDefaultValue;
import de.hsadmin.web.config.PropertyFormField;
import de.hsadmin.web.config.PropertyTableColumn;
public class EMailAliasModule extends GenericModule {
@@ -17,7 +16,8 @@
        moduleConfig = new ModuleConfig("emailalias");
        String login = getApplication().getLogin();
        final String pac = login.length() >= 5 ? login.substring(0, 5) : "";
        moduleConfig.addProperty(new PropertyConfig(moduleConfig, "id", Long.class, PropertyTableColumn.INTERNAL_KEY, PropertyFormField.INTERNAL_KEY));
        PropertyConfig idProp = new PropertyConfig(moduleConfig, "id", Long.class, PropertyTableColumn.INTERNAL_KEY);
        idProp.setReadOnly(true);
        PropertyConfig nameProp = new PropertyConfig(moduleConfig, "name", String.class);
        nameProp.setDefaultValue(new PropertyDefaultValue() {
            @Override
@@ -28,7 +28,7 @@
                return "";
            }
        });
        moduleConfig.addProperty(nameProp);
        nameProp.setWriteOnce(true);
        PropertyConfig targetProp = new PropertyConfig(moduleConfig, "target", String.class);
        targetProp.setDefaultValue(new PropertyDefaultValue() {
            @Override
@@ -39,14 +39,17 @@
                return "";
            }
        });
        moduleConfig.addProperty(targetProp);
        PropertyConfig pacProp = new PropertyConfig(moduleConfig, "pac", String.class, PropertyTableColumn.HIDDEN, PropertyFormField.READONLY);
        PropertyConfig pacProp = new PropertyConfig(moduleConfig, "pac", String.class, PropertyTableColumn.HIDDEN);
        pacProp.setDefaultValue(new PropertyDefaultValue() {
            @Override
            public String getDefaultValue() {
                return pac;
            }
        });
        pacProp.setReadOnly(true);
        moduleConfig.addProperty(idProp);
        moduleConfig.addProperty(nameProp);
        moduleConfig.addProperty(targetProp);
        moduleConfig.addProperty(pacProp);
    }
    
hsarweb/src/de/hsadmin/web/GenericModule.java
@@ -1,302 +1,29 @@
package de.hsadmin.web;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.vaadin.data.Property;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.terminal.Sizeable;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.AbstractTextField;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Layout;
import com.vaadin.ui.Link;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.Select;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.themes.BaseTheme;
import de.hsadmin.web.config.LocaleConfig;
import de.hsadmin.web.config.ModuleConfig;
import de.hsadmin.web.config.PropertyConfig;
import de.hsadmin.web.config.PropertyFormField;
import de.hsadmin.web.config.PropertyTableColumn;
public abstract class GenericModule implements Serializable {
public abstract class GenericModule extends AbstractModule implements InsertAble, UpdateAble, DeleteAble {
    private static final long serialVersionUID = 1L;
    private static final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
    private VerticalLayout layout;
    private Table table;
    private MainApplication application;
    public void insertRow(Map<String, String> paramHash) throws HsarwebException {
        getApplication().getRemote().callAdd(getModuleConfig().getName(), paramHash);
    }
    public void setApplication(MainApplication app) throws HsarwebException {
        application = app;
        initModule();
        initTable();
        initLayout();
    public void deleteRow(Map<String, String> paramHash) throws HsarwebException {
        getApplication().getRemote().callDelete(getModuleConfig().getName(), paramHash);
    }
    
    public MainApplication getApplication() {
        return application;
    }
    public abstract ModuleConfig getModuleConfig();
    protected abstract void initModule();
    public Component getComponent() {
        return layout;
    }
    public void reload() throws HsarwebException {
        loadTable();
    }
    private void initLayout() {
        layout = new VerticalLayout();
        layout.setSizeFull();
        final ModuleConfig moduleConfig = getModuleConfig();
        final LocaleConfig localeConfig = application.getLocaleConfig();
        if (moduleConfig.isSearchAble() || moduleConfig.isAddAble()) {
            HorizontalLayout toolbar = new HorizontalLayout();
            if (moduleConfig.isAddAble()) {
                Button btNew = new Button(moduleConfig.getLabel("new"));
                ThemeResource icon = new ThemeResource("../runo/icons/16/document-add.png");
                btNew.setIcon(icon);
                btNew.addListener(new Button.ClickListener() {
                    private static final long serialVersionUID = 1L;
                    private Window childWindow;
                    @Override
                    public void buttonClick(ClickEvent event) {
                        final Form form = createForm();
                        childWindow = new Window(localeConfig.getText("new"));
                        childWindow.setWidth(640.0f, Sizeable.UNITS_PIXELS);
                        VerticalLayout vLayout = new VerticalLayout();
                        vLayout.setMargin(true);
                        vLayout.setSpacing(true);
                        vLayout.addComponent(form);
                        HorizontalLayout hLayout = new HorizontalLayout();
                        Button btSaveRow = new Button(localeConfig.getText("save"));
                        btSaveRow.addListener(new Button.ClickListener() {
                            private static final long serialVersionUID = 1L;
                            @Override
                            public void buttonClick(ClickEvent event) {
                                application.getMainWindow().removeWindow(childWindow);
                                try {
                                    insertRow(form);
                                } catch (HsarwebException e) {
                                    application.showUserException(e);
                                }
                            }
                        });
                        Button btAbort = new Button(localeConfig.getText("abort"));
                        btAbort.addListener(new Button.ClickListener() {
                            private static final long serialVersionUID = 1L;
                            @Override
                            public void buttonClick(ClickEvent event) {
                                application.getMainWindow().removeWindow(childWindow);
                            }
                        });
                        hLayout.addComponent(btSaveRow);
                        hLayout.addComponent(btAbort);
                        vLayout.addComponent(hLayout);
                        childWindow.setContent(vLayout);
                        childWindow.setModal(true);
                        application.getMainWindow().addWindow(childWindow);
                    }
                });
                toolbar.addComponent(btNew);
            }
//            if (moduleConfig.isSearchAble()) {
//                Button btSearch = new Button("search");
//                toolbar.addComponent(btSearch);
//            }
            layout.addComponent(toolbar);
        }
        layout.addComponent(table);
        layout.setExpandRatio(table, 1.0f);
        layout.addComponent(new Link(localeConfig.getText("impressum.label"), new ExternalResource(localeConfig.getText("impressum.link"))));
    }
    private void initTable() throws HsarwebException {
        table = new Table() {
            private static final long serialVersionUID = 35127658139420917L;
            @Override
            protected String formatPropertyValue(Object rowId, Object colId,
                    Property property) {
                if (Date.class == property.getType()) {
                    try {
                        return df.format(property.getValue());
                    } catch (IllegalArgumentException e) {
                        return "---";
                    }
                }
                return super.formatPropertyValue(rowId, colId, property);
            }
        };
        try {
            table.setWidth(100.0f, Sizeable.UNITS_PERCENTAGE);
            table.setHeight(100.0f, Sizeable.UNITS_PERCENTAGE);
            table.setSelectable(false);
            table.setImmediate(true);
            table.setColumnCollapsingAllowed(true);
            table.setColumnReorderingAllowed(true);
            for (PropertyConfig prop : getModuleConfig().getPropertyList()) {
                PropertyTableColumn propTableColumn = prop.getPropTableColumn();
                if (propTableColumn != PropertyTableColumn.NONE) {
                    table.addContainerProperty(prop.getId(), prop.getType(), prop.getDefaultValue());
                    table.setColumnHeader(prop.getId(), prop.getLabel());
                    if (propTableColumn == PropertyTableColumn.HIDDEN) {
                        table.setColumnCollapsed(prop.getId(), true);
                    }
                    if (propTableColumn == PropertyTableColumn.INTERNAL_KEY) {
                        table.setColumnCollapsed(prop.getId(), true);
                    }
                }
            }
            if (getModuleConfig().isUpdateAble()) {
                table.addContainerProperty("edit", Button.class, null);
                table.setColumnWidth("edit", 16);
                table.setColumnHeader("edit", "");
            }
            if (getModuleConfig().isDeleteAble()) {
                table.addContainerProperty("del", Button.class, null);
                table.setColumnWidth("del", 16);
                table.setColumnHeader("del", "");
            }
        } catch (Exception e) {
            throw new HsarwebException(e);
        }
    }
    private void loadTable() throws HsarwebException {
        table.removeAllItems();
        try {
            ModuleConfig moduleConfig = getModuleConfig();
            Object callSearch = application.getRemote().callSearch(moduleConfig.getName(), new HashMap<String, String>());
            List<PropertyConfig> propertyList = moduleConfig.getPropertyList();
            if (callSearch instanceof Object[]) {
                for (Object row : ((Object[])callSearch)) {
                    long oid = -1L;
                    if (row instanceof Map<?, ?>) {
                        int numOfcolumns = propertyList.size();
                        if (moduleConfig.isUpdateAble()) {
                            numOfcolumns++;
                        }
                        if (moduleConfig.isDeleteAble()) {
                            numOfcolumns++;
                        }
                        numOfcolumns = moduleConfig.getNumOfColumns();
                        Object[] itemData = new Object[numOfcolumns];
                        int idx = 0;
                        for (PropertyConfig prop : propertyList) {
                            PropertyTableColumn propTableColumn = prop.getPropTableColumn();
                            if (propTableColumn != PropertyTableColumn.NONE) {
                                Object valueObject = ((Map<?, ?>) row).get(prop.getId());
                                if (valueObject != null && valueObject instanceof String) {
                                    if (Long.class.equals(prop.getType())) {
                                        itemData[idx] = Long.parseLong((String) valueObject);
                                    }
                                    if (Date.class.equals(prop.getType())) {
                                        try {
                                            itemData[idx] = df.parse((String) valueObject);
                                        } catch (ParseException e) {
                                            Calendar cal = Calendar.getInstance();
                                            cal.clear();
                                            itemData[idx] = cal.getTime();
                                        }
                                    }
                                    if (String.class.equals(prop.getType())) {
                                        itemData[idx] = (String) valueObject;
                                    }
                                    if (propTableColumn == PropertyTableColumn.INTERNAL_KEY && Long.class.equals(prop.getType())) {
                                        if (valueObject instanceof String) {
                                            oid = Long.parseLong((String) valueObject);
                                        }
                                    }
                                }
                                idx++;
                            }
                        }
                        if (moduleConfig.isUpdateAble()) {
                            itemData[idx] = createEditButton(oid);
                            idx++;
                        }
                        if (moduleConfig.isDeleteAble()) {
                            itemData[idx] = createDeleteButton(oid);
                            idx++;
                        }
                        table.addItem(itemData, oid);
                    }
                }
                table.sort();
            }
        } catch (UnsupportedOperationException e) {
            throw new HsarwebException(e);
        }
    }
    private void deleteRow(long id) throws HsarwebException {
        Map<String, String> paramHash = new HashMap<String, String>();
        paramHash.put(findIdKey(), Long.toString(id));
        application.getRemote().callDelete(getModuleConfig().getName(), paramHash);
        loadTable();
    }
    private void updateRow(Form form) throws HsarwebException {
    public void updateRow(Map<String, String> paramHash) throws HsarwebException {
        Map<String, String> whereHash = new HashMap<String, String>();
        whereHash.put(findIdKey(), ((Long) form.getData()).toString());
        Map<String, String> setHash = new HashMap<String, String>();
        Iterator<Component> componentIterator = form.getLayout().getComponentIterator();
        while (componentIterator.hasNext()) {
            Component c = componentIterator.next();
            transferToHash(setHash, c);
        }
        application.getRemote().callUpdate(getModuleConfig().getName(), setHash, whereHash);
        loadTable();
    }
    private void insertRow(Form form) throws HsarwebException {
        Map<String, String> setHash = new HashMap<String, String>();
        Iterator<Component> componentIterator = form.getLayout().getComponentIterator();
        while (componentIterator.hasNext()) {
            Component c = componentIterator.next();
            transferToHash(setHash, c);
        }
        application.getRemote().callAdd(getModuleConfig().getName(), setHash);
        loadTable();
    }
    private void transferToHash(Map<String, String> setHash, Component c) {
        if (c instanceof AbstractTextField) {
            AbstractTextField tf = (AbstractTextField) c;
            Object data = tf.getData();
            Object value = tf.getValue();
            setHash.put((String) data, (String) value);
        }
        if (c instanceof Select) {
            Select sel = (Select) c;
            Object data = sel.getData();
            Object value = sel.getValue();
            setHash.put((String) data, (String) value);
        }
        String idKey = findIdKey();
        whereHash.put(idKey, paramHash.get(idKey));
        getApplication().getRemote().callUpdate(getModuleConfig().getName(), paramHash, whereHash);
    }
    private String findIdKey() {
@@ -310,205 +37,6 @@
            }
        }
        return idKey;
    }
    private Button createEditButton(long id) {
        ThemeResource icon = new ThemeResource("../runo/icons/16/document-txt.png");
        final Button button = new Button();
        button.setIcon(icon);
        button.setData(id);
        button.setStyleName(BaseTheme.BUTTON_LINK);
        button.addListener(new Button.ClickListener() {
            private static final long serialVersionUID = 1L;
            private Window childWindow;
            @Override
            public void buttonClick(ClickEvent event) {
                final Form form = createForm((Long) button.getData());
                LocaleConfig localeConfig = application.getLocaleConfig();
                childWindow = new Window(getModuleConfig().getLabel("moduletitle") + " " + localeConfig.getText("update"));
                childWindow.setWidth(640.0f, Sizeable.UNITS_PIXELS);
                VerticalLayout vLayout = new VerticalLayout();
                vLayout.setMargin(true);
                vLayout.setSpacing(true);
                vLayout.addComponent(form);
                HorizontalLayout hLayout = new HorizontalLayout();
                Button btSaveRow = new Button(localeConfig.getText("save"));
                btSaveRow.addListener(new Button.ClickListener() {
                    private static final long serialVersionUID = 1L;
                    @Override
                    public void buttonClick(ClickEvent event) {
                        application.getMainWindow().removeWindow(childWindow);
                        try {
                            updateRow(form);
                        } catch (HsarwebException e) {
                            application.showUserException(e);
                        }
                    }
                });
                Button btAbort = new Button(localeConfig.getText("abort"));
                btAbort.addListener(new Button.ClickListener() {
                    private static final long serialVersionUID = 1L;
                    @Override
                    public void buttonClick(ClickEvent event) {
                        application.getMainWindow().removeWindow(childWindow);
                    }
                });
                hLayout.addComponent(btSaveRow);
                hLayout.addComponent(btAbort);
                vLayout.addComponent(hLayout);
                childWindow.setContent(vLayout);
                childWindow.setModal(true);
                application.getMainWindow().addWindow(childWindow);
            }
        });
        return button;
    }
    private Button createDeleteButton(long id) {
        ThemeResource icon = new ThemeResource("../runo/icons/16/document-delete.png");
        final Button button = new Button();
        button.setIcon(icon);
        button.setData(id);
        button.setStyleName(BaseTheme.BUTTON_LINK);
        button.addListener(new Button.ClickListener() {
            private static final long serialVersionUID = 1L;
            private Window childWindow;
            @Override
            public void buttonClick(ClickEvent event) {
                LocaleConfig localeConfig = application.getLocaleConfig();
                childWindow = new Window(getModuleConfig().getLabel("moduletitle") + " " + localeConfig.getText("delete"));
                childWindow.setWidth(320.0f, Sizeable.UNITS_PIXELS);
                VerticalLayout vLayout = new VerticalLayout();
                vLayout.setMargin(true);
                vLayout.setSpacing(true);
                vLayout.addComponent(new Label(localeConfig.getText("confirmdelete")));
                HorizontalLayout hLayout = new HorizontalLayout();
                Button btDeleteRow = new Button(localeConfig.getText("delete"));
                btDeleteRow.addListener(new Button.ClickListener() {
                    private static final long serialVersionUID = 1L;
                    @Override
                    public void buttonClick(ClickEvent event) {
                        application.getMainWindow().removeWindow(childWindow);
                        try {
                            deleteRow((Long) button.getData());
                        } catch (HsarwebException e) {
                            application.showUserException(e);
                        }
                    }
                });
                Button btAbort = new Button(localeConfig.getText("abort"));
                btAbort.addListener(new Button.ClickListener() {
                    private static final long serialVersionUID = 1L;
                    @Override
                    public void buttonClick(ClickEvent event) {
                        application.getMainWindow().removeWindow(childWindow);
                    }
                });
                hLayout.addComponent(btDeleteRow);
                hLayout.addComponent(btAbort);
                vLayout.addComponent(hLayout);
                childWindow.setContent(vLayout);
                childWindow.setModal(true);
                application.getMainWindow().addWindow(childWindow);
            }
        });
        return button;
    }
    private Form createForm(Long key) {
        try {
            Map<String, String> where = new HashMap<String, String>();
            where.put(findIdKey(), key.toString());
            Object searchResult = application.getRemote().callSearch(getModuleConfig().getName(), where);
            if (searchResult instanceof Object[]) {
                Map<?, ?> row = (Map<?, ?>) (((Object[]) searchResult)[0]);
                Form f = new Form();
                f.setCaption(getModuleConfig().getLabel("update"));
                f.setData(key);
                Layout layout = f.getLayout();
                for (PropertyConfig prop : getModuleConfig().getPropertyList()) {
                    PropertyFormField propFormField = prop.getPropFormField();
                    if (propFormField != PropertyFormField.INTERNAL_KEY && propFormField != PropertyFormField.NONE) {
                        if (prop.hasSelectList()) {
                            Select sel = new Select(prop.getLabel());
                            sel.setData(prop.getId());
                            sel.setNullSelectionAllowed(false);
                            sel.setNewItemsAllowed(prop.newItemsAllowed());
                            Map<String, String> selectValues = prop.getSelectValues();
                            for (Object skey : selectValues.keySet()) {
                                sel.addItem(skey);
                                sel.setItemCaption(skey, selectValues.get(skey));
                            }
                            sel.setWidth(480.0f, Sizeable.UNITS_PIXELS);
                            Object value = row.get(prop.getId());
                            sel.setValue(value != null ? value : prop.getDefaultValue());
                            sel.setReadOnly(PropertyFormField.READONLY == propFormField || PropertyFormField.WRITEONCE == propFormField);
                            layout.addComponent(sel);
                        } else {
                            if (propFormField != PropertyFormField.PASSWORD) {
                                TextField tf = new TextField(prop.getLabel());
                                tf.setData(prop.getId());
                                tf.setWidth(480.0f, Sizeable.UNITS_PIXELS);
                                Object value = row.get(prop.getId());
                                tf.setValue(value != null ? value : prop.getDefaultValue());
                                tf.setReadOnly(PropertyFormField.READONLY == propFormField || PropertyFormField.WRITEONCE == propFormField);
                                layout.addComponent(tf);
                            }
                        }
                    }
                }
                return f;
            }
        } catch (HsarwebException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    private Form createForm() {
        Form f = new Form();
        f.setCaption(getModuleConfig().getLabel("new"));
        Layout layout = f.getLayout();
        for (PropertyConfig prop : getModuleConfig().getPropertyList()) {
            PropertyFormField propFormField = prop.getPropFormField();
            if (PropertyFormField.READWRITE == propFormField || PropertyFormField.WRITEONCE == propFormField || PropertyFormField.PASSWORD == propFormField) {
                if (prop.hasSelectList()) {
                    Select sel = new Select(prop.getLabel());
                    sel.setData(prop.getId());
                    sel.setNullSelectionAllowed(false);
                    sel.setNewItemsAllowed(prop.newItemsAllowed());
                    Map<String, String> selectValues = prop.getSelectValues();
                    for (Object key : selectValues.keySet()) {
                        sel.addItem(key);
                        sel.setItemCaption(key, selectValues.get(key));
                    }
                    sel.setWidth(480.0f, Sizeable.UNITS_PIXELS);
                    sel.setValue(prop.getDefaultValue());
                    layout.addComponent(sel);
                } else {
                    if (PropertyFormField.PASSWORD == propFormField) {
                        PasswordField tf1 = new PasswordField(getModuleConfig().getLabel(prop.getId() + "1"));
                        tf1.setData(prop.getId());
                        tf1.setWidth(480.0f, Sizeable.UNITS_PIXELS);
                        tf1.setValue(prop.getDefaultValue());
                        layout.addComponent(tf1);
                        PasswordField tf2 = new PasswordField(getModuleConfig().getLabel(prop.getId() + "2"));
                        tf2.setData(prop.getId());
                        tf2.setWidth(480.0f, Sizeable.UNITS_PIXELS);
                        tf2.setValue(prop.getDefaultValue());
                        layout.addComponent(tf2);
                    } else {
                        TextField tf = new TextField(prop.getLabel());
                        tf.setData(prop.getId());
                        tf.setWidth(480.0f, Sizeable.UNITS_PIXELS);
                        tf.setValue(prop.getDefaultValue());
                        layout.addComponent(tf);
                    }
                }
            }
        }
        return f;
    }
    
}
hsarweb/src/de/hsadmin/web/InsertAble.java
New file
@@ -0,0 +1,9 @@
package de.hsadmin.web;
import java.util.Map;
public interface InsertAble {
    public void insertRow(Map<String, String> paramHash) throws HsarwebException;
}
hsarweb/src/de/hsadmin/web/MainApplication.java
@@ -37,7 +37,7 @@
    private AttributePrincipal userPrincipal;
    private LocaleConfig localeConfig;
    private Remote remote;
    private Map<String, GenericModule> modules;
    private Map<String, Module> modules;
    @Override
@@ -49,14 +49,12 @@
        verticalLayout.setSizeFull();
        TabSheet tabs = new TabSheet();
        tabs.setSizeFull();
//        tabs.setWidth(95.0f, Sizeable.UNITS_PERCENTAGE);
//        tabs.setHeight(95.0f, Sizeable.UNITS_PERCENTAGE);
        String modulesParamString = getContextParam("hsarmodules");
        modules = new HashMap<String, GenericModule>();
        GenericModule firstModule = null;
        modules = new HashMap<String, Module>();
        Module firstModule = null;
        for (String className : modulesParamString.split(",")) {
            try {
                GenericModule module = (GenericModule) Class.forName(className).newInstance();
                Module module = (Module) Class.forName(className).newInstance();
                module.setApplication(this);
                if (firstModule == null) {
                    firstModule = module;
@@ -64,7 +62,7 @@
                ModuleConfig moduleConfig = module.getModuleConfig();
                String label = moduleConfig.getLabel("moduletitle");
                modules.put(label, module);
                tabs.addTab(module.getComponent(), label, new ThemeResource(moduleConfig.getLabel("moduleicon")));
                tabs.addTab((Component) module.getComponent(), label, new ThemeResource(moduleConfig.getLabel("moduleicon")));
            } catch (Exception e) {
                showSystemException(e);
            }
@@ -126,7 +124,7 @@
        TabSheet tabSheet = event.getTabSheet();
        Component selectedTab = tabSheet.getSelectedTab();
        Tab tab = tabSheet.getTab(selectedTab);
        GenericModule module = modules.get(tab.getCaption());
        Module module = modules.get(tab.getCaption());
        try {
            module.reload();
        } catch (HsarwebException e) {
hsarweb/src/de/hsadmin/web/Module.java
New file
@@ -0,0 +1,17 @@
package de.hsadmin.web;
import de.hsadmin.web.config.ModuleConfig;
public interface Module {
    public abstract MainApplication getApplication();
    public abstract ModuleConfig getModuleConfig();
    public abstract void reload() throws HsarwebException;
    public abstract void setApplication(MainApplication mainApplication) throws HsarwebException;
    public abstract Object getComponent();
}
hsarweb/src/de/hsadmin/web/QueueTaskModule.java
@@ -6,7 +6,7 @@
import de.hsadmin.web.config.PropertyConfig;
import de.hsadmin.web.config.PropertyTableColumn;
public class QueueTaskModule extends GenericModule {
public class QueueTaskModule extends AbstractModule {
    private static final long serialVersionUID = 1L;
    
@@ -15,10 +15,6 @@
    @Override
    protected void initModule() {
        moduleConfig = new ModuleConfig("q");
        moduleConfig.setUpdateAble(false);
        moduleConfig.setDeleteAble(false);
        moduleConfig.setAddAble(false);
        moduleConfig.setSearchAble(false);
        moduleConfig.addProperty(new PropertyConfig(moduleConfig, "id", Long.class, PropertyTableColumn.INTERNAL_KEY));
        moduleConfig.addProperty(new PropertyConfig(moduleConfig, "title", String.class));
        moduleConfig.addProperty(new PropertyConfig(moduleConfig, "status", String.class));
hsarweb/src/de/hsadmin/web/SearchAble.java
New file
@@ -0,0 +1,6 @@
package de.hsadmin.web;
public interface SearchAble {
}
hsarweb/src/de/hsadmin/web/UnixUserModule.java
@@ -6,9 +6,10 @@
import de.hsadmin.web.config.ModuleConfig;
import de.hsadmin.web.config.PropertyConfig;
import de.hsadmin.web.config.PropertyDefaultValue;
import de.hsadmin.web.config.PropertyFormField;
import de.hsadmin.web.config.PropertySelectValues;
import de.hsadmin.web.config.PropertyTableColumn;
import de.hsadmin.web.vaadin.PasswordPropertyFieldFactory;
import de.hsadmin.web.vaadin.SelectPropertyFieldFactory;
public class UnixUserModule extends GenericModule {
@@ -21,9 +22,12 @@
        moduleConfig = new ModuleConfig("user");
        String login = getApplication().getLogin();
        final String pac = login.length() >= 5 ? login.substring(0, 5) : "";
        PropertyConfig useridProp = new PropertyConfig(moduleConfig, "userid", Long.class, PropertyTableColumn.HIDDEN, PropertyFormField.READONLY);
        PropertyConfig idProp = new PropertyConfig(moduleConfig, "id", Long.class, PropertyTableColumn.INTERNAL_KEY, PropertyFormField.INTERNAL_KEY);
        PropertyConfig nameProp = new PropertyConfig(moduleConfig, "name", String.class, PropertyFormField.WRITEONCE);
        PropertyConfig idProp = new PropertyConfig(moduleConfig, "id", Long.class, PropertyTableColumn.INTERNAL_KEY);
        idProp.setReadOnly(true);
        PropertyConfig useridProp = new PropertyConfig(moduleConfig, "userid", Long.class, PropertyTableColumn.HIDDEN);
        useridProp.setReadOnly(true);
        PropertyConfig nameProp = new PropertyConfig(moduleConfig, "name", String.class);
        nameProp.setWriteOnce(true);
        nameProp.setDefaultValue(new PropertyDefaultValue() {
            @Override
            public String getDefaultValue() {
@@ -33,9 +37,9 @@
                return "";
            }
        });
        PropertyConfig passwordProp = new PropertyConfig(moduleConfig, "password", String.class, PropertyTableColumn.NONE, PropertyFormField.PASSWORD);
        PropertyConfig passwordProp = new PropertyConfig(moduleConfig, "password", String.class, PropertyTableColumn.NONE, new PasswordPropertyFieldFactory(this));
        PropertyConfig commentProp = new PropertyConfig(moduleConfig, "comment", String.class);
        PropertyConfig shellProp = new PropertyConfig(moduleConfig, "shell", String.class);
        PropertyConfig shellProp = new PropertyConfig(moduleConfig, "shell", String.class, new SelectPropertyFieldFactory());
        shellProp.setDefaultValue(new PropertyDefaultValue() {
            @Override
            public String getDefaultValue() {
@@ -65,8 +69,10 @@
                return true;
            }
        });
        PropertyConfig homedirProp = new PropertyConfig(moduleConfig, "homedir", String.class, PropertyTableColumn.HIDDEN, PropertyFormField.READONLY);
        PropertyConfig pacProp = new PropertyConfig(moduleConfig, "pac", String.class, PropertyTableColumn.HIDDEN, PropertyFormField.READONLY);
        PropertyConfig homedirProp = new PropertyConfig(moduleConfig, "homedir", String.class, PropertyTableColumn.HIDDEN);
        homedirProp.setReadOnly(true);
        PropertyConfig pacProp = new PropertyConfig(moduleConfig, "pac", String.class, PropertyTableColumn.HIDDEN);
        pacProp.setReadOnly(true);
        pacProp.setDefaultValue(new PropertyDefaultValue() {
            @Override
            public String getDefaultValue() {
hsarweb/src/de/hsadmin/web/UpdateAble.java
New file
@@ -0,0 +1,9 @@
package de.hsadmin.web;
import java.util.Map;
public interface UpdateAble {
    public void updateRow(Map<String, String> paramHash) throws HsarwebException;
}
hsarweb/src/de/hsadmin/web/config/ComponentFactory.java
New file
@@ -0,0 +1,11 @@
package de.hsadmin.web.config;
import de.hsadmin.web.HsarwebException;
public interface ComponentFactory {
    public Object initComponent() throws HsarwebException;
    public void loadData() throws HsarwebException;
}
hsarweb/src/de/hsadmin/web/config/ModuleConfig.java
@@ -15,20 +15,12 @@
    private List<PropertyConfig> propertyList;
    private Map<String, PropertyConfig> propertyMap;
    private LocaleConfig localeConfig;
    private boolean deleteAble;
    private boolean updateAble;
    private boolean addAble;
    private boolean searchAble;
    public ModuleConfig(String name) {
        this.name = name;
        propertyList = new ArrayList<PropertyConfig>();
        propertyMap = new HashMap<String, PropertyConfig>();
        localeConfig = new LocaleConfig(Locale.getDefault(), name);
        addAble = true;
        updateAble = true;
        deleteAble = true;
        searchAble = true;
    }
    
    public String getName() {
@@ -52,50 +44,12 @@
        return localeConfig.getText(key);
    }
    public boolean isDeleteAble() {
        return deleteAble;
    }
    public boolean isUpdateAble() {
        return updateAble;
    }
    public boolean isAddAble() {
        return addAble;
    }
    public boolean isSearchAble() {
        return searchAble;
    }
    public void setDeleteAble(boolean deleteAble) {
        this.deleteAble = deleteAble;
    }
    public void setUpdateAble(boolean updateAble) {
        this.updateAble = updateAble;
    }
    public void setAddAble(boolean addAble) {
        this.addAble = addAble;
    }
    public void setSearchAble(boolean searchAble) {
        this.searchAble = searchAble;
    }
    public int getNumOfColumns() {
        int numOfCols = 0;
        for (PropertyConfig prop : propertyList) {
            if (prop.getPropTableColumn() != PropertyTableColumn.NONE) {
                numOfCols++;
            }
        }
        if (isUpdateAble()) {
            numOfCols++;
        }
        if (isDeleteAble()) {
            numOfCols++;
        }
        return numOfCols;
    }
hsarweb/src/de/hsadmin/web/config/PropertyConfig.java
@@ -4,6 +4,8 @@
import java.util.HashMap;
import java.util.Map;
import de.hsadmin.web.vaadin.DefaultPropertyFieldFactory;
public class PropertyConfig implements Serializable, PropertyDefaultValue, PropertySelectValues {
    private static final long serialVersionUID = 1L;
@@ -12,7 +14,7 @@
    private String id;
    private Class<?> type;
    private PropertyTableColumn propTableColumn;
    private PropertyFormField propFormField;
    private PropertyFieldFactory propFieldFactory;
    private PropertyDefaultValue defaultValue;
    private PropertySelectValues selectValues;
    
@@ -21,17 +23,17 @@
        this.id = id;
        this.type = clasz;
        this.propTableColumn = PropertyTableColumn.DISPLAY;
        this.propFormField = PropertyFormField.READWRITE;
        this.setPropFieldFactory(new DefaultPropertyFieldFactory());
        this.defaultValue = null;
        this.selectValues = null;
    }
    public PropertyConfig(ModuleConfig moduleConfig, String id, Class<?> clasz, PropertyFormField formField) {
    public PropertyConfig(ModuleConfig moduleConfig, String id, Class<?> clasz, PropertyFieldFactory fieldFactory) {
        this.moduleConfig = moduleConfig;
        this.id = id;
        this.type = clasz;
        this.propTableColumn = PropertyTableColumn.DISPLAY;
        this.propFormField = formField;
        this.setPropFieldFactory(fieldFactory);
        this.defaultValue = null;
        this.selectValues = null;
    }
@@ -41,17 +43,17 @@
        this.id = id;
        this.type = clasz;
        this.propTableColumn = tablecolumn;
        this.propFormField = PropertyFormField.READWRITE;
        this.setPropFieldFactory(new DefaultPropertyFieldFactory());
        this.defaultValue = null;
        this.selectValues = null;
    }
    public PropertyConfig(ModuleConfig moduleConfig, String id, Class<?> clasz, PropertyTableColumn tablecolumn, PropertyFormField formField) {
    public PropertyConfig(ModuleConfig moduleConfig, String id, Class<?> clasz, PropertyTableColumn tablecolumn, PropertyFieldFactory fieldFactory) {
        this.moduleConfig = moduleConfig;
        this.id = id;
        this.type = clasz;
        this.propTableColumn = tablecolumn;
        this.propFormField = formField;
        this.setPropFieldFactory(fieldFactory);
        this.defaultValue = null;
        this.selectValues = null;
    }
@@ -70,10 +72,6 @@
    public PropertyTableColumn getPropTableColumn() {
        return propTableColumn;
    }
    public PropertyFormField getPropFormField() {
        return propFormField;
    }
    public void setDefaultValue(PropertyDefaultValue defaultValue) {
@@ -102,7 +100,7 @@
        if (selectValues != null) {
            return selectValues.newItemsAllowed();
        }
        return propFormField == PropertyFormField.READWRITE || propFormField == PropertyFormField.WRITEONCE;
        return true;
    }
    @Override
@@ -112,5 +110,21 @@
        }
        return false;
    }
    public void setPropFieldFactory(PropertyFieldFactory propFieldFactory) {
        this.propFieldFactory = propFieldFactory;
    }
    public PropertyFieldFactory getPropFieldFactory() {
        return propFieldFactory;
    }
    public void setReadOnly(boolean readOnly) {
        propFieldFactory.setReadOnly(readOnly);
    }
    public void setWriteOnce(boolean writeOnce) {
        propFieldFactory.setWriteOnce(writeOnce);
    }
    
}
hsarweb/src/de/hsadmin/web/config/PropertyFieldFactory.java
New file
@@ -0,0 +1,19 @@
package de.hsadmin.web.config;
import de.hsadmin.web.HsarwebException;
public interface PropertyFieldFactory {
    public Object createFieldComponent(PropertyConfig prop, Object value);
    public String getValue(PropertyConfig prop, Object component) throws HsarwebException;
    public void setReadOnly(boolean readOnly);
    public boolean isReadOnly();
    public void setWriteOnce(boolean writeOnce);
    public boolean isWriteOnce();
}
hsarweb/src/de/hsadmin/web/config/PropertyFormField.java
File was deleted
hsarweb/src/de/hsadmin/web/vaadin/DefaultPropertyFieldFactory.java
New file
@@ -0,0 +1,51 @@
package de.hsadmin.web.vaadin;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.TextField;
import de.hsadmin.web.config.PropertyConfig;
import de.hsadmin.web.config.PropertyFieldFactory;
public class DefaultPropertyFieldFactory implements PropertyFieldFactory {
    private boolean readOnly = false;
    private boolean writeOnce;
    @Override
    public Object createFieldComponent(PropertyConfig prop, Object value) {
        TextField tf = new TextField(prop.getLabel());
        tf.setData(prop.getId());
        tf.setWidth(480.0f, Sizeable.UNITS_PIXELS);
        tf.setValue(value != null ? value : prop.getDefaultValue());
        tf.setReadOnly(isReadOnly());
        return tf;
    }
    @Override
    public String getValue(PropertyConfig prop, Object component) {
        if (component instanceof TextField) {
            return (String) ((TextField) component).getValue();
        }
        return null;
    }
    @Override
    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }
    public boolean isReadOnly() {
        return readOnly;
    }
    @Override
    public void setWriteOnce(boolean writeOnce) {
        this.writeOnce = writeOnce;
    }
    @Override
    public boolean isWriteOnce() {
        return writeOnce;
    }
}
hsarweb/src/de/hsadmin/web/vaadin/GenericForm.java
New file
@@ -0,0 +1,102 @@
package de.hsadmin.web.vaadin;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Component;
import com.vaadin.ui.Form;
import com.vaadin.ui.Layout;
import de.hsadmin.web.HsarwebException;
import de.hsadmin.web.MainApplication;
import de.hsadmin.web.Module;
import de.hsadmin.web.config.ModuleConfig;
import de.hsadmin.web.config.PropertyConfig;
import de.hsadmin.web.config.PropertyFieldFactory;
import de.hsadmin.web.config.PropertyTableColumn;
public class GenericForm {
    private Module module;
    private Long entityId;
    public GenericForm(Module module, Long entityId) {
        this.module = module;
        this.entityId = entityId;
    }
    public Form createAddForm() {
        Form f = new Form();
        ModuleConfig config = module.getModuleConfig();
        f.setCaption(config.getLabel("new"));
        Layout layout = f.getLayout();
        for (PropertyConfig prop : config.getPropertyList()) {
            PropertyFieldFactory propFieldFactory = prop.getPropFieldFactory();
            if (!propFieldFactory.isReadOnly()) {
                layout.addComponent((Component) propFieldFactory.createFieldComponent(prop, null));
            }
        }
        return f;
    }
    public Form createUpdateForm() {
        try {
            MainApplication application = module.getApplication();
            ModuleConfig config = module.getModuleConfig();
            Map<String, String> where = new HashMap<String, String>();
            where.put(findIdKey(), entityId.toString());
            Object searchResult = application.getRemote().callSearch(config.getName(), where);
            if (searchResult instanceof Object[]) {
                Map<?, ?> row = (Map<?, ?>) (((Object[]) searchResult)[0]);
                Form f = new Form();
                f.setCaption(config.getLabel("update"));
                f.setData(entityId);
                Layout layout = f.getLayout();
                for (PropertyConfig prop : config.getPropertyList()) {
                    PropertyFieldFactory propFieldFactory = prop.getPropFieldFactory();
                    Object value = row.get(prop.getId());
                    Component component = (Component) propFieldFactory.createFieldComponent(prop, value);
                    if (propFieldFactory.isWriteOnce()) {
                        component.setReadOnly(true);
                    }
                    layout.addComponent(component);
                }
                return f;
            }
        } catch (HsarwebException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    private String findIdKey() {
        List<PropertyConfig> propertyList = module.getModuleConfig().getPropertyList();
        String idKey = null;
        for (PropertyConfig propConf : propertyList) {
            PropertyTableColumn propTableColumn = propConf.getPropTableColumn();
            if (PropertyTableColumn.INTERNAL_KEY == propTableColumn) {
                idKey = propConf.getId();
                return idKey;
            }
        }
        return idKey;
    }
    public void transferToHash(Map<String, String> map, Form form) throws HsarwebException {
        Iterator<Component> iterator = form.getLayout().getComponentIterator();
        while (iterator.hasNext()) {
            Component component = (Component) iterator.next();
            if (component instanceof AbstractComponent) {
                Object data = ((AbstractComponent) component).getData();
                String propName = (String) data;
                PropertyConfig property = module.getModuleConfig().getProperty(propName);
                map.put(propName, property.getPropFieldFactory().getValue(property, component));
            }
        }
    }
}
hsarweb/src/de/hsadmin/web/vaadin/PasswordPropertyFieldFactory.java
New file
@@ -0,0 +1,79 @@
package de.hsadmin.web.vaadin;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.VerticalLayout;
import de.hsadmin.web.HsarwebException;
import de.hsadmin.web.Module;
import de.hsadmin.web.config.ModuleConfig;
import de.hsadmin.web.config.PropertyConfig;
import de.hsadmin.web.config.PropertyFieldFactory;
public class PasswordPropertyFieldFactory implements PropertyFieldFactory {
    private Module module;
    private boolean readOnly;
    private boolean writeOnce;
    public PasswordPropertyFieldFactory(Module module) {
        this.module = module;
    }
    @Override
    public Object createFieldComponent(PropertyConfig prop, Object value) {
        ModuleConfig config = module.getModuleConfig();
        VerticalLayout layout = new VerticalLayout();
        layout.setCaption(prop.getLabel());
        layout.setData(prop.getId());
        PasswordField tf1 = new PasswordField(config.getLabel(prop.getId() + "1"));
        tf1.setData(prop.getId());
        tf1.setWidth(480.0f, Sizeable.UNITS_PIXELS);
        tf1.setValue(value != null ? value : prop.getDefaultValue());
        tf1.setReadOnly(readOnly);
        layout.addComponent(tf1);
        PasswordField tf2 = new PasswordField(config.getLabel(prop.getId() + "2"));
        tf2.setData(prop.getId());
        tf2.setWidth(480.0f, Sizeable.UNITS_PIXELS);
        tf2.setValue(value != null ? value : prop.getDefaultValue());
        tf2.setReadOnly(readOnly);
        layout.addComponent(tf2);
        return layout;
    }
    @Override
    public String getValue(PropertyConfig prop, Object component) throws HsarwebException {
        if (component instanceof VerticalLayout) {
            VerticalLayout layout = (VerticalLayout) component;
            PasswordField pw1 = (PasswordField) layout.getComponent(0);
            PasswordField pw2 = (PasswordField) layout.getComponent(1);
            if (pw1.getValue().equals(pw2.getValue())) {
                return (String) pw1.getValue();
            } else {
                throw new HsarwebException("password mismatch");
            }
        }
        return null;
    }
    @Override
    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }
    @Override
    public boolean isReadOnly() {
        return readOnly;
    }
    @Override
    public void setWriteOnce(boolean writeOnce) {
        this.writeOnce = writeOnce;
    }
    @Override
    public boolean isWriteOnce() {
        return writeOnce;
    }
}
hsarweb/src/de/hsadmin/web/vaadin/SelectPropertyFieldFactory.java
New file
@@ -0,0 +1,64 @@
package de.hsadmin.web.vaadin;
import java.util.Map;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.Select;
import de.hsadmin.web.HsarwebException;
import de.hsadmin.web.config.PropertyConfig;
import de.hsadmin.web.config.PropertyFieldFactory;
public class SelectPropertyFieldFactory implements PropertyFieldFactory {
    private boolean readOnly;
    private boolean writeOnce;
    @Override
    public Object createFieldComponent(PropertyConfig prop, Object value) {
        Select sel = new Select(prop.getLabel());
        sel.setData(prop.getId());
        sel.setNullSelectionAllowed(false);
        sel.setNewItemsAllowed(prop.newItemsAllowed());
        Map<String, String> selectValues = prop.getSelectValues();
        for (Object key : selectValues.keySet()) {
            sel.addItem(key);
            sel.setItemCaption(key, selectValues.get(key));
        }
        sel.setWidth(480.0f, Sizeable.UNITS_PIXELS);
        sel.setValue(value != null ? value : prop.getDefaultValue());
        sel.setReadOnly(readOnly);
        sel.setInvalidAllowed(prop.newItemsAllowed());
        return sel;
    }
    @Override
    public String getValue(PropertyConfig prop, Object component)
            throws HsarwebException {
        if (component instanceof Select) {
            return (String) ((Select) component).getValue();
        }
        return null;
    }
    @Override
    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }
    @Override
    public boolean isReadOnly() {
        return readOnly;
    }
    @Override
    public void setWriteOnce(boolean writeOnce) {
        this.writeOnce = writeOnce;
    }
    @Override
    public boolean isWriteOnce() {
        return writeOnce;
    }
}
hsarweb/src/de/hsadmin/web/vaadin/TableComponentFactory.java
New file
@@ -0,0 +1,296 @@
package de.hsadmin.web.vaadin;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.vaadin.data.Property;
import com.vaadin.terminal.Sizeable;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.themes.BaseTheme;
import de.hsadmin.web.DeleteAble;
import de.hsadmin.web.HsarwebException;
import de.hsadmin.web.MainApplication;
import de.hsadmin.web.Module;
import de.hsadmin.web.UpdateAble;
import de.hsadmin.web.config.ComponentFactory;
import de.hsadmin.web.config.LocaleConfig;
import de.hsadmin.web.config.ModuleConfig;
import de.hsadmin.web.config.PropertyConfig;
import de.hsadmin.web.config.PropertyTableColumn;
public class TableComponentFactory implements ComponentFactory, Serializable {
    private static final long serialVersionUID = 1L;
    private static final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
    private Module module;
    private Table table;
    public TableComponentFactory(Module module) {
        this.module = module;
    }
    @Override
    public Object initComponent() throws HsarwebException {
        ModuleConfig config = module.getModuleConfig();
        table = new Table() {
            private static final long serialVersionUID = 1L;
            @Override
            protected String formatPropertyValue(Object rowId, Object colId,
                    Property property) {
                if (Date.class == property.getType()) {
                    try {
                        return df.format(property.getValue());
                    } catch (IllegalArgumentException e) {
                        return "---";
                    }
                }
                return super.formatPropertyValue(rowId, colId, property);
            }
        };
        try {
            table.setWidth(100.0f, Sizeable.UNITS_PERCENTAGE);
            table.setHeight(100.0f, Sizeable.UNITS_PERCENTAGE);
            table.setSelectable(false);
            table.setImmediate(true);
            table.setColumnCollapsingAllowed(true);
            table.setColumnReorderingAllowed(true);
            for (PropertyConfig prop : config.getPropertyList()) {
                PropertyTableColumn propTableColumn = prop.getPropTableColumn();
                if (propTableColumn != PropertyTableColumn.NONE) {
                    table.addContainerProperty(prop.getId(), prop.getType(), prop.getDefaultValue());
                    table.setColumnHeader(prop.getId(), prop.getLabel());
                    if (propTableColumn == PropertyTableColumn.HIDDEN) {
                        table.setColumnCollapsed(prop.getId(), true);
                    }
                    if (propTableColumn == PropertyTableColumn.INTERNAL_KEY) {
                        table.setColumnCollapsed(prop.getId(), true);
                    }
                }
            }
            if (module instanceof UpdateAble) {
                table.addContainerProperty("edit", Button.class, null);
                table.setColumnWidth("edit", 16);
                table.setColumnHeader("edit", "");
            }
            if (module instanceof DeleteAble) {
                table.addContainerProperty("del", Button.class, null);
                table.setColumnWidth("del", 16);
                table.setColumnHeader("del", "");
            }
        } catch (Exception e) {
            throw new HsarwebException(e);
        }
        return table;
    }
    @Override
    public void loadData() throws HsarwebException {
        table.removeAllItems();
        try {
            ModuleConfig moduleConfig = module.getModuleConfig();
            Object callSearch = module.getApplication().getRemote().callSearch(moduleConfig.getName(), new HashMap<String, String>());
            List<PropertyConfig> propertyList = moduleConfig.getPropertyList();
            if (callSearch instanceof Object[]) {
                for (Object row : ((Object[])callSearch)) {
                    long oid = -1L;
                    if (row instanceof Map<?, ?>) {
                        int numOfcolumns = moduleConfig.getNumOfColumns();
                        if (module instanceof UpdateAble) {
                            numOfcolumns++;
                        }
                        if (module instanceof DeleteAble) {
                            numOfcolumns++;
                        }
                        Object[] itemData = new Object[numOfcolumns];
                        int idx = 0;
                        for (PropertyConfig prop : propertyList) {
                            PropertyTableColumn propTableColumn = prop.getPropTableColumn();
                            if (propTableColumn != PropertyTableColumn.NONE) {
                                Object valueObject = ((Map<?, ?>) row).get(prop.getId());
                                if (valueObject != null && valueObject instanceof String) {
                                    if (Long.class.equals(prop.getType())) {
                                        itemData[idx] = Long.parseLong((String) valueObject);
                                    }
                                    if (Date.class.equals(prop.getType())) {
                                        try {
                                            itemData[idx] = df.parse((String) valueObject);
                                        } catch (ParseException e) {
                                            Calendar cal = Calendar.getInstance();
                                            cal.clear();
                                            itemData[idx] = cal.getTime();
                                        }
                                    }
                                    if (String.class.equals(prop.getType())) {
                                        itemData[idx] = (String) valueObject;
                                    }
                                    if (propTableColumn == PropertyTableColumn.INTERNAL_KEY && Long.class.equals(prop.getType())) {
                                        if (valueObject instanceof String) {
                                            oid = Long.parseLong((String) valueObject);
                                        }
                                    }
                                }
                                idx++;
                            }
                        }
                        if (module instanceof UpdateAble) {
                            itemData[idx] = createEditButton(oid);
                            idx++;
                        }
                        if (module instanceof DeleteAble) {
                            itemData[idx] = createDeleteButton(oid);
                            idx++;
                        }
                        table.addItem(itemData, oid);
                    }
                }
                table.sort();
            }
        } catch (UnsupportedOperationException e) {
            throw new HsarwebException(e);
        }
    }
    private Button createEditButton(long id) {
        ThemeResource icon = new ThemeResource("../runo/icons/16/document-txt.png");
        final Button button = new Button();
        final Module thisModule = module;
        button.setIcon(icon);
        button.setData(id);
        button.setStyleName(BaseTheme.BUTTON_LINK);
        button.addListener(new Button.ClickListener() {
            private static final long serialVersionUID = 1L;
            private Window childWindow;
            @Override
            public void buttonClick(ClickEvent event) {
                final GenericForm genericForm = new GenericForm(thisModule, (Long) button.getData());
                final Form form = genericForm.createUpdateForm();
                final MainApplication application = module.getApplication();
                LocaleConfig localeConfig = application.getLocaleConfig();
                childWindow = new Window(module.getModuleConfig().getLabel("moduletitle") + " " + localeConfig.getText("update"));
                childWindow.setWidth(640.0f, Sizeable.UNITS_PIXELS);
                VerticalLayout vLayout = new VerticalLayout();
                vLayout.setMargin(true);
                vLayout.setSpacing(true);
                vLayout.addComponent(form);
                HorizontalLayout hLayout = new HorizontalLayout();
                Button btSaveRow = new Button(localeConfig.getText("save"));
                btSaveRow.addListener(new Button.ClickListener() {
                    private static final long serialVersionUID = 1L;
                    @Override
                    public void buttonClick(ClickEvent event) {
                        application.getMainWindow().removeWindow(childWindow);
                        try {
                            Map<String, String> map = new HashMap<String, String>();
                            genericForm.transferToHash(map, form);
                            ((UpdateAble) module).updateRow(map);
                            loadData();
                        } catch (HsarwebException e) {
                            application.showUserException(e);
                        }
                    }
                });
                Button btAbort = new Button(localeConfig.getText("abort"));
                btAbort.addListener(new Button.ClickListener() {
                    private static final long serialVersionUID = 1L;
                    @Override
                    public void buttonClick(ClickEvent event) {
                        application.getMainWindow().removeWindow(childWindow);
                    }
                });
                hLayout.addComponent(btSaveRow);
                hLayout.addComponent(btAbort);
                vLayout.addComponent(hLayout);
                childWindow.setContent(vLayout);
                childWindow.setModal(true);
                application.getMainWindow().addWindow(childWindow);
            }
        });
        return button;
    }
    private Button createDeleteButton(long id) {
        ThemeResource icon = new ThemeResource("../runo/icons/16/document-delete.png");
        final Button button = new Button();
        button.setIcon(icon);
        button.setData(id);
        button.setStyleName(BaseTheme.BUTTON_LINK);
        button.addListener(new Button.ClickListener() {
            private static final long serialVersionUID = 1L;
            private Window childWindow;
            @Override
            public void buttonClick(ClickEvent event) {
                final MainApplication application = module.getApplication();
                LocaleConfig localeConfig = application.getLocaleConfig();
                childWindow = new Window(module.getModuleConfig().getLabel("moduletitle") + " " + localeConfig.getText("delete"));
                childWindow.setWidth(320.0f, Sizeable.UNITS_PIXELS);
                VerticalLayout vLayout = new VerticalLayout();
                vLayout.setMargin(true);
                vLayout.setSpacing(true);
                vLayout.addComponent(new Label(localeConfig.getText("confirmdelete")));
                HorizontalLayout hLayout = new HorizontalLayout();
                Button btDeleteRow = new Button(localeConfig.getText("delete"));
                btDeleteRow.addListener(new Button.ClickListener() {
                    private static final long serialVersionUID = 1L;
                    @Override
                    public void buttonClick(ClickEvent event) {
                        application.getMainWindow().removeWindow(childWindow);
                        try {
                            Map<String, String> map = new HashMap<String, String>();
                            map.put(findIdKey(), ((Long) button.getData()).toString());
                            ((DeleteAble) module).deleteRow(map);
                            loadData();
                        } catch (HsarwebException e) {
                            application.showUserException(e);
                        }
                    }
                });
                Button btAbort = new Button(localeConfig.getText("abort"));
                btAbort.addListener(new Button.ClickListener() {
                    private static final long serialVersionUID = 1L;
                    @Override
                    public void buttonClick(ClickEvent event) {
                        application.getMainWindow().removeWindow(childWindow);
                    }
                });
                hLayout.addComponent(btDeleteRow);
                hLayout.addComponent(btAbort);
                vLayout.addComponent(hLayout);
                childWindow.setContent(vLayout);
                childWindow.setModal(true);
                application.getMainWindow().addWindow(childWindow);
            }
        });
        return button;
    }
    private String findIdKey() {
        List<PropertyConfig> propertyList = module.getModuleConfig().getPropertyList();
        String idKey = null;
        for (PropertyConfig propConf : propertyList) {
            PropertyTableColumn propTableColumn = propConf.getPropTableColumn();
            if (PropertyTableColumn.INTERNAL_KEY == propTableColumn) {
                idKey = propConf.getId();
                return idKey;
            }
        }
        return idKey;
    }
}
hsarweb/src/texts/user.properties
@@ -1,6 +1,7 @@
id=identifier
name=username
password1=password
password=password
password1=new password
password2=repeat password
comment=comment
shell=shell
hsarweb/src/texts/user_de.properties
@@ -1,7 +1,8 @@
id=Schl├╝ssel
name=Benutzername
password1=Passwort
password2=Passwort (Wdhlg.)
password=Passwort
password1=neues Passwort
password2=Passwort-Wiederholung
comment=Kommentar
shell=Shell
userid=Benutzerkennung