annis.libgui.IDGenerator.java Source code

Java tutorial

Introduction

Here is the source code for annis.libgui.IDGenerator.java

Source

/*
 * Copyright 2016 SFB 632.
 *
 * 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 annis.libgui;

import com.google.common.base.Preconditions;
import com.vaadin.ui.Component;
import com.vaadin.ui.HasComponents;
import com.vaadin.ui.UI;
import java.lang.reflect.Field;
import java.util.Iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Helper class to generate unique IDs for components.
 * 
 * Each component will have the ID of it's parent component as prefix in the ID.
 * Thus assigning an ID to an component will always assign an ID to all it's
 * ancestors as well. Additionally it is checked that the siblings of a
 * component don't have the same ID when it is assigned.
 * 
 * @author Thomas Krause <krauseto@hu-berlin.de>
 */
public class IDGenerator {
    private static Logger log = LoggerFactory.getLogger(IDGenerator.class);

    public static String assignID(Component c) {
        String fieldName = "c";
        if (c != null) {
            fieldName = c.getClass().getSimpleName();
        }
        return assignID(c, fieldName);
    }

    protected static String assignIDForField(HasComponents parent, Component c) {
        String fieldName = "c";
        if (parent != null && c != null) {
            // iterate over each field of the parent
            for (Field f : parent.getClass().getDeclaredFields()) {
                if (Component.class.isAssignableFrom(f.getType())) {
                    try {
                        f.setAccessible(true);
                        Component fieldComponent = (Component) f.get(parent);
                        if (fieldComponent == c) {
                            fieldName = f.getName();
                        }
                    } catch (IllegalArgumentException | IllegalAccessException | SecurityException ex) {
                        log.warn("Could not automatically get field name for assigning ID", ex);
                    }
                }
            }
        }
        return assignID(c, fieldName);
    }

    public static void assignIDForFields(HasComponents parent, Component... components) {
        for (Component c : components) {
            assignIDForField(parent, c);
        }
    }

    public static void assignIDForEachField(HasComponents parent) {
        if (parent != null) {
            Iterator<Component> itComponents = parent.iterator();
            while (itComponents.hasNext()) {
                Component c = itComponents.next();
                assignIDForField(parent, c);
            }
        }
    }

    public static String assignID(Component c, String fieldName) {
        String id = null;
        if (c != null && fieldName != null && !fieldName.isEmpty()) {
            Preconditions.checkArgument(c.isAttached(),
                    "Component " + c.getConnectorId() + " must be attached before it can get an automatic ID.");
            id = c.getId();
            if (id == null) {
                // try to get the parent ID
                HasComponents parent = c.getParent();
                if (parent == null || parent instanceof UI) {
                    // use class name as ID
                    id = fieldName;
                } else {
                    String parentID = parent.getId();
                    if (parentID == null) {
                        parentID = assignID(parent);
                    }
                    String idBase = parentID + ":" + fieldName;
                    // check that no other child has the same ID
                    int counter = 1;
                    id = idBase;
                    while (childHasID(parent, id)) {
                        id = idBase + "." + counter++;
                    }
                }
                c.setId(id);
            }
        }
        return id;
    }

    private static boolean childHasID(HasComponents parent, String id) {
        if (parent != null && id != null) {
            Iterator<Component> itChildren = parent.iterator();
            while (itChildren.hasNext()) {
                Component child = itChildren.next();
                if (id.equals(child.getId())) {
                    return true;
                }
            }
        }
        return false;
    }
}