com.evolveum.midpoint.web.util.WebMiscUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.evolveum.midpoint.web.util.WebMiscUtil.java

Source

/*
 * Copyright (c) 2010-2013 Evolveum
 *
 * 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 com.evolveum.midpoint.web.util;

import com.evolveum.midpoint.prism.PrismContainer;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.crypto.EncryptionException;
import com.evolveum.midpoint.prism.crypto.Protector;
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.delta.PropertyDelta;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.prism.query.ObjectPaging;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.schema.SchemaConstantsGenerated;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.DisplayableValue;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.security.api.Authorization;
import com.evolveum.midpoint.security.api.AuthorizationConstants;
import com.evolveum.midpoint.security.api.MidPointPrincipal;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.web.component.data.BaseSortableDataProvider;
import com.evolveum.midpoint.web.component.data.BoxedTablePanel;
import com.evolveum.midpoint.web.component.data.Table;
import com.evolveum.midpoint.web.component.data.TablePanel;
import com.evolveum.midpoint.web.component.input.DropDownChoicePanel;
import com.evolveum.midpoint.web.component.prism.ObjectWrapper;
import com.evolveum.midpoint.web.component.util.LoadableModel;
import com.evolveum.midpoint.web.component.util.Selectable;
import com.evolveum.midpoint.web.component.wf.processes.itemApproval.ItemApprovalPanel;
import com.evolveum.midpoint.web.page.PageBase;
import com.evolveum.midpoint.web.page.PageDialog;
import com.evolveum.midpoint.web.page.admin.configuration.component.EmptyOnBlurAjaxFormUpdatingBehaviour;
import com.evolveum.midpoint.web.page.admin.configuration.component.EmptyOnChangeAjaxFormUpdatingBehavior;
import com.evolveum.midpoint.web.page.admin.configuration.component.ObjectSelectionPanel;
import com.evolveum.midpoint.web.security.MidPointApplication;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;
import com.sun.management.OperatingSystemMXBean;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.wicket.*;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication;
import org.apache.wicket.authroles.authorization.strategies.role.Roles;
import org.apache.wicket.core.request.handler.RenderPageRequestHandler;
import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
import org.apache.wicket.feedback.IFeedback;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.util.visit.IVisit;
import org.apache.wicket.util.visit.IVisitor;

import javax.management.*;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.RuntimeMXBean;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/**
 * @author lazyman
 */
public final class WebMiscUtil {

    private static final Trace LOGGER = TraceManager.getTrace(WebMiscUtil.class);
    private static DatatypeFactory df = null;

    public static enum Channel {
        LIVE_SYNC("http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#liveSync"), RECONCILIATION(
                "http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#reconciliation"), DISCOVERY(
                        "http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#discovery"), IMPORT(
                                "http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#import"), USER(
                                        "http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#user"), WEB_SERVICE(
                                                "http://midpoint.evolveum.com/xml/ns/public/provisioning/channels-3#webService");

        private String channel;

        Channel(String channel) {
            this.channel = channel;
        }

        public String getChannel() {
            return channel;
        }
    }

    static {
        try {
            df = DatatypeFactory.newInstance();
        } catch (DatatypeConfigurationException dce) {
            throw new IllegalStateException("Exception while obtaining Datatype Factory instance", dce);
        }
    }

    private WebMiscUtil() {
    }

    public static boolean isAuthorized(String... action) {
        if (action == null || action.length == 0) {
            return true;
        }
        List<String> actions = Arrays.asList(action);
        return isAuthorized(actions);
    }

    public static boolean isAuthorized(Collection<String> actions) {
        if (actions == null || actions.isEmpty()) {
            return true;
        }
        Roles roles = new Roles(AuthorizationConstants.AUTZ_ALL_URL);
        roles.addAll(actions);
        if (((AuthenticatedWebApplication) AuthenticatedWebApplication.get()).hasAnyRole(roles)) {
            return true;
        }
        return false;
    }

    public static Integer safeLongToInteger(Long l) {
        if (l == null) {
            return null;
        }

        if (l > Integer.MAX_VALUE || l < Integer.MIN_VALUE) {
            throw new IllegalArgumentException("Couldn't transform long '" + l + "' to int, too big or too small.");
        }

        return (int) l.longValue();
    }

    public static <T extends Enum> IModel<String> createLocalizedModelForEnum(T value, Component comp) {
        String key = value != null ? value.getClass().getSimpleName() + "." + value.name() : "";
        return new StringResourceModel(key, comp, null);
    }

    public static <T extends Enum> IModel<List<T>> createReadonlyModelFromEnum(final Class<T> type) {
        return new AbstractReadOnlyModel<List<T>>() {

            @Override
            public List<T> getObject() {
                List<T> list = new ArrayList<T>();
                Collections.addAll(list, type.getEnumConstants());

                return list;
            }
        };
    }

    public static ObjectReferenceType createObjectRef(String oid, String name, QName type) {
        ObjectReferenceType ort = new ObjectReferenceType();
        ort.setOid(oid);
        ort.setTargetName(createPolyFromOrigString(name));
        ort.setType(type);
        return ort;
    }

    //    public static DropDownChoicePanel createActivationStatusPanel(String id, final IModel<ActivationStatusType> model,
    //                                                                  final Component component) {
    //        return new DropDownChoicePanel(id, model,
    //                WebMiscUtil.createReadonlyModelFromEnum(ActivationStatusType.class),
    //                new IChoiceRenderer<ActivationStatusType>() {
    //
    //                    @Override
    //                    public Object getDisplayValue(ActivationStatusType object) {
    //                        return WebMiscUtil.createLocalizedModelForEnum(object, component).getObject();
    //                    }
    //
    //                    @Override
    //                    public String getIdValue(ActivationStatusType object, int index) {
    //                        return Integer.toString(index);
    //                    }
    //                }, true);
    //    }

    public static <E extends Enum> DropDownChoicePanel createEnumPanel(Class clazz, String id,
            final IModel<E> model, final Component component) {
        //        final Class clazz = model.getObject().getClass();
        final Object o = model.getObject();
        return new DropDownChoicePanel(id, model, WebMiscUtil.createReadonlyModelFromEnum(clazz),
                new IChoiceRenderer<E>() {

                    @Override
                    public Object getDisplayValue(E object) {
                        return WebMiscUtil.createLocalizedModelForEnum(object, component).getObject();
                    }

                    @Override
                    public String getIdValue(E object, int index) {
                        return Integer.toString(index);
                    }
                }, true);
    }

    public static DropDownChoicePanel createEnumPanel(final PrismPropertyDefinition def, String id,
            final IModel model, final Component component) {
        // final Class clazz = model.getObject().getClass();
        final Object o = model.getObject();

        final IModel<List<DisplayableValue>> enumModelValues = new AbstractReadOnlyModel<List<DisplayableValue>>() {
            @Override
            public List<DisplayableValue> getObject() {
                List<DisplayableValue> values = null;
                if (def.getAllowedValues() != null) {
                    values = new ArrayList<>(def.getAllowedValues().size());
                    for (Object v : def.getAllowedValues()) {
                        if (v instanceof DisplayableValue) {
                            values.add(((DisplayableValue) v));
                        }
                    }
                }
                return values;
            }

        };

        return new DropDownChoicePanel(id, model, enumModelValues, new IChoiceRenderer() {

            @Override
            public Object getDisplayValue(Object object) {
                if (object instanceof DisplayableValue) {
                    return ((DisplayableValue) object).getLabel();
                }
                for (DisplayableValue v : enumModelValues.getObject()) {
                    if (object.equals(v.getValue())) {
                        return v.getLabel();
                    }
                }
                return object;

            }

            @Override
            public String getIdValue(Object object, int index) {
                if (object instanceof DisplayableValue) {
                    return ((DisplayableValue) object).getValue().toString();
                }
                return object.toString();
                //                  for (DisplayableValue v : enumModelValues.getObject()){
                //                     if (object.equals(v.getValue())){
                //                        return v.getLabel();
                //                     }
                //                  }
                //                  return object.getValue().toString();//Integer.toString(index);
            }

        }, true);
    }

    public static <T> TextField<T> createAjaxTextField(String id, IModel<T> model) {
        TextField<T> textField = new TextField<T>(id, model);
        textField.add(new EmptyOnBlurAjaxFormUpdatingBehaviour());
        return textField;
    }

    public static CheckBox createAjaxCheckBox(String id, IModel<Boolean> model) {
        CheckBox checkBox = new CheckBox(id, model);
        checkBox.add(new EmptyOnChangeAjaxFormUpdatingBehavior());
        return checkBox;
    }

    public static String getName(ObjectType object) {
        if (object == null) {
            return null;
        }

        return getName(object.asPrismObject());
    }

    public static String getName(ObjectReferenceType ref) {
        if (ref == null) {
            return null;
        }

        if (ref.getTargetName() != null) {
            return getOrigStringFromPoly(ref.getTargetName());
        }
        return ref.getOid();
    }

    public static String getName(PrismObject object) {
        if (object == null) {
            return null;
        }
        PolyString name = getValue(object, ObjectType.F_NAME, PolyString.class);

        return name != null ? name.getOrig() : null;
    }

    public static String getIdentification(ObjectType object) {
        if (object == null) {
            return null;
        }
        return getName(object.asPrismObject()) + " (" + object.getOid() + ")";
    }

    public static PolyStringType createPolyFromOrigString(String str) {
        if (str == null) {
            return null;
        }

        PolyStringType poly = new PolyStringType();
        poly.setOrig(str);

        return poly;
    }

    public static String getOrigStringFromPoly(PolyString str) {
        return str != null ? str.getOrig() : null;
    }

    public static String getOrigStringFromPoly(PolyStringType str) {
        return str != null ? str.getOrig() : null;
    }

    public static <T> T getValue(PrismContainerValue object, QName propertyName, Class<T> type) {
        if (object == null) {
            return null;
        }

        PrismProperty property = object.findProperty(propertyName);
        if (property == null || property.isEmpty()) {
            return null;
        }

        return (T) property.getRealValue(type);
    }

    public static <T> T getContainerValue(PrismContainerValue object, QName containerName, Class<T> type) {
        if (object == null) {
            return null;
        }

        PrismContainer container = object.findContainer(containerName);
        if (container == null || container.isEmpty()) {
            return null;
        }

        PrismContainerValue containerValue = container.getValue();

        if (containerValue == null || containerValue.isEmpty()) {
            return null;
        }

        return (T) containerValue.getValue();
    }

    public static <T> T getValue(PrismContainer object, QName propertyName, Class<T> type) {
        if (object == null) {
            return null;
        }

        return getValue(object.getValue(), propertyName, type);
    }

    public static Locale getLocaleFromString(String localeString) {
        if (localeString == null) {
            return null;
        }
        localeString = localeString.trim();
        if (localeString.toLowerCase().equals("default")) {
            return Locale.getDefault();
        }

        // Extract language
        int languageIndex = localeString.indexOf('_');
        String language = null;
        if (languageIndex == -1) {
            // No further "_" so is "{language}" only
            return new Locale(localeString, "");
        } else {
            language = localeString.substring(0, languageIndex);
        }

        // Extract country
        int countryIndex = localeString.indexOf('_', languageIndex + 1);
        String country = null;
        if (countryIndex == -1) {
            // No further "_" so is "{language}_{country}"
            country = localeString.substring(languageIndex + 1);
            return new Locale(language, country);
        } else {
            // Assume all remaining is the variant so is "{language}_{country}_{variant}"
            country = localeString.substring(languageIndex + 1, countryIndex);
            String variant = localeString.substring(countryIndex + 1);
            return new Locale(language, country, variant);
        }
    }

    public static void encryptCredentials(ObjectDelta delta, boolean encrypt, MidPointApplication app) {
        if (delta == null || delta.isEmpty()) {
            return;
        }

        PropertyDelta propertyDelta = delta.findPropertyDelta(new ItemPath(SchemaConstantsGenerated.C_CREDENTIALS,
                CredentialsType.F_PASSWORD, PasswordType.F_VALUE));
        if (propertyDelta == null) {
            return;
        }

        Collection<PrismPropertyValue<ProtectedStringType>> values = propertyDelta
                .getValues(ProtectedStringType.class);
        for (PrismPropertyValue<ProtectedStringType> value : values) {
            ProtectedStringType string = value.getValue();
            encryptProtectedString(string, encrypt, app);
        }
    }

    public static void encryptCredentials(PrismObject object, boolean encrypt, MidPointApplication app) {
        PrismContainer password = object
                .findContainer(new ItemPath(SchemaConstantsGenerated.C_CREDENTIALS, CredentialsType.F_PASSWORD));
        if (password == null) {
            return;
        }
        PrismProperty protectedStringProperty = password.findProperty(PasswordType.F_VALUE);
        if (protectedStringProperty == null
                || protectedStringProperty.getRealValue(ProtectedStringType.class) == null) {
            return;
        }

        ProtectedStringType string = (ProtectedStringType) protectedStringProperty
                .getRealValue(ProtectedStringType.class);

        encryptProtectedString(string, encrypt, app);
    }

    public static void encryptProtectedString(ProtectedStringType string, boolean encrypt,
            MidPointApplication app) {
        if (string == null) {
            return;
        }
        Protector protector = app.getProtector();
        try {
            if (encrypt) {
                if (StringUtils.isEmpty(string.getClearValue())) {
                    return;
                }
                protector.encrypt(string);
            } else {
                if (string.getEncryptedDataType() == null) {
                    return;
                }
                protector.decrypt(string);
            }
        } catch (EncryptionException ex) {
            LoggingUtils.logException(LOGGER, "Couldn't encrypt protected string", ex);
        } catch (SchemaException e) {
            LoggingUtils.logException(LOGGER, "Couldn't encrypt/decrypt protected string", e);
        }
    }

    public static <T extends Selectable> List<T> getSelectedData(Table table) {
        DataTable dataTable = table.getDataTable();
        BaseSortableDataProvider<T> provider = (BaseSortableDataProvider<T>) dataTable.getDataProvider();

        List<T> selected = new ArrayList<T>();
        for (T bean : provider.getAvailableData()) {
            if (bean.isSelected()) {
                selected.add(bean);
            }
        }

        return selected;
    }

    public static Collection<ObjectDelta<? extends ObjectType>> createDeltaCollection(
            ObjectDelta<? extends ObjectType>... deltas) {
        Collection<ObjectDelta<? extends ObjectType>> collection = new ArrayList<ObjectDelta<? extends ObjectType>>();
        for (ObjectDelta delta : deltas) {
            collection.add(delta);
        }

        return collection;
    }

    public static boolean showResultInPage(OperationResult result) {
        if (result == null) {
            return false;
        }

        return !result.isSuccess() && !result.isHandledError() && !result.isInProgress();
    }

    public static String formatDate(XMLGregorianCalendar calendar) {
        if (calendar == null) {
            return null;
        }

        return formatDate(XmlTypeConverter.toDate(calendar));
    }

    public static String formatDate(Date date) {
        return formatDate(null, date);
    }

    public static String formatDate(String format, Date date) {
        if (date == null) {
            return null;
        }

        if (StringUtils.isEmpty(format)) {
            format = "EEEE, d. MMM yyyy HH:mm:ss";
        }
        Locale locale = Session.get().getLocale();
        if (locale == null) {
            locale = Locale.US;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(format, locale);
        return dateFormat.format(date);
    }

    public static boolean isActivationEnabled(PrismObject object) {
        Validate.notNull(object);

        PrismContainer activation = object.findContainer(UserType.F_ACTIVATION); //this is equal to account activation...
        if (activation == null) {
            return false;
        }

        ActivationStatusType status = (ActivationStatusType) activation
                .getPropertyRealValue(ActivationType.F_ADMINISTRATIVE_STATUS, ActivationStatusType.class);
        if (status == null) {
            return false;
        }

        //todo imrove with activation dates...
        return ActivationStatusType.ENABLED.equals(status);
    }

    public static boolean isSuccessOrHandledError(OperationResult result) {
        if (result == null) {
            return false;
        }

        return result.isSuccess() || result.isHandledError();
    }

    public static boolean isSuccessOrHandledErrorOrWarning(OperationResult result) {
        if (result == null) {
            return false;
        }

        return result.isSuccess() || result.isHandledError() || result.isWarning();
    }

    public static boolean isSuccessOrHandledErrorOrInProgress(OperationResult result) {
        if (result == null) {
            return false;
        }

        return result.isSuccess() || result.isHandledError() || result.isInProgress();
    }

    public static String createUserIcon(PrismObject<UserType> object) {
        UserType user = object.asObjectable();

        //if user has superuser role assigned, it's superuser
        for (AssignmentType assignment : user.getAssignment()) {
            ObjectReferenceType targetRef = assignment.getTargetRef();
            if (targetRef == null) {
                continue;
            }
            if (StringUtils.equals(targetRef.getOid(), SystemObjectsType.ROLE_SUPERUSER.value())) {
                return "fa fa-male text-danger";
            }
        }

        ActivationType activation = user.getActivation();
        if (activation != null && ActivationStatusType.DISABLED.equals(activation.getEffectiveStatus())) {
            return "fa fa-male text-muted";
        }

        return "fa fa-male";
    }

    public static String createUserIconTitle(PrismObject<UserType> object) {
        UserType user = object.asObjectable();

        //if user has superuser role assigned, it's superuser
        for (AssignmentType assignment : user.getAssignment()) {
            ObjectReferenceType targetRef = assignment.getTargetRef();
            if (targetRef == null) {
                continue;
            }
            if (StringUtils.equals(targetRef.getOid(), SystemObjectsType.ROLE_SUPERUSER.value())) {
                return "User.superuser";
            }
        }

        ActivationType activation = user.getActivation();
        if (activation != null && ActivationStatusType.DISABLED.equals(activation.getEffectiveStatus())) {
            return "User.disabled";
        }

        return null;
    }

    public static double getSystemLoad() {
        com.sun.management.OperatingSystemMXBean operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory
                .getOperatingSystemMXBean();
        RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
        int availableProcessors = operatingSystemMXBean.getAvailableProcessors();
        long prevUpTime = runtimeMXBean.getUptime();
        long prevProcessCpuTime = operatingSystemMXBean.getProcessCpuTime();

        try {
            Thread.sleep(150);
        } catch (Exception ignored) {
            //ignored
        }

        operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory
                .getOperatingSystemMXBean();
        long upTime = runtimeMXBean.getUptime();
        long processCpuTime = operatingSystemMXBean.getProcessCpuTime();
        long elapsedCpu = processCpuTime - prevProcessCpuTime;
        long elapsedTime = upTime - prevUpTime;

        double cpuUsage = Math.min(99F, elapsedCpu / (elapsedTime * 10000F * availableProcessors));

        return cpuUsage;
    }

    public static double getMaxRam() {
        int MB = 1024 * 1024;

        MemoryMXBean mBean = ManagementFactory.getMemoryMXBean();
        long maxHeap = mBean.getHeapMemoryUsage().getMax();
        long maxNonHeap = mBean.getNonHeapMemoryUsage().getMax();

        return (maxHeap + maxNonHeap) / MB;
    }

    public static double getRamUsage() {
        int MB = 1024 * 1024;

        MemoryMXBean mBean = ManagementFactory.getMemoryMXBean();
        long usedHead = mBean.getHeapMemoryUsage().getUsed();
        long usedNonHeap = mBean.getNonHeapMemoryUsage().getUsed();

        return (usedHead + usedNonHeap) / MB;
    }

    /**
     * Checks table if has any selected rows ({@link Selectable} interface dtos), adds "single"
     * parameter to selected items if it's not null. If table has no selected rows warn message
     * is added to feedback panel, and feedback is refreshed through {@link AjaxRequestTarget}
     *
     * @param target
     * @param single             this parameter is used for row actions when action must be done only on chosen row.
     * @param table
     * @param page
     * @param nothingWarnMessage
     * @param <T>
     * @return
     */
    public static <T extends Selectable> List<T> isAnythingSelected(AjaxRequestTarget target, T single, Table table,
            PageBase page, String nothingWarnMessage) {
        List<T> selected;
        if (single != null) {
            selected = new ArrayList<T>();
            selected.add(single);
        } else {
            selected = WebMiscUtil.getSelectedData(table);
            if (selected.isEmpty()) {
                page.warn(page.getString(nothingWarnMessage));
                target.add(page.getFeedbackPanel());
            }
        }

        return selected;
    }

    public static void refreshFeedbacks(MarkupContainer component, final AjaxRequestTarget target) {
        component.visitChildren(IFeedback.class, new IVisitor<Component, Void>() {

            @Override
            public void component(final Component component, final IVisit<Void> visit) {
                target.add(component);
            }
        });
    }

    /*
     *  Methods used for providing prismContext into various objects.
     */
    public static void revive(LoadableModel<?> loadableModel, PrismContext prismContext) throws SchemaException {
        if (loadableModel != null) {
            loadableModel.revive(prismContext);
        }
    }

    public static void revive(IModel<?> model, PrismContext prismContext) throws SchemaException {
        if (model != null && model.getObject() != null) {
            reviveObject(model.getObject(), prismContext);
        }
    }

    public static void reviveObject(Object object, PrismContext prismContext) throws SchemaException {
        if (object == null) {
            return;
        }
        if (object instanceof Collection) {
            for (Object item : (Collection) object) {
                reviveObject(item, prismContext);
            }
        } else if (object instanceof Revivable) {
            ((Revivable) object).revive(prismContext);
        }
    }

    // useful for components other than those inheriting from PageBase
    public static PrismContext getPrismContext(Component component) {
        return ((MidPointApplication) component.getApplication()).getPrismContext();
    }

    public static void reviveIfNeeded(ObjectType objectType, Component component) {
        if (objectType != null && objectType.asPrismObject().getPrismContext() == null) {
            try {
                objectType.asPrismObject().revive(getPrismContext(component));
            } catch (SchemaException e) {
                throw new SystemException("Couldn't revive " + objectType + " because of schema exception", e);
            }
        }
    }

    public static List<String> getChannelList() {
        List<String> channels = new ArrayList<>();

        for (Channel channel : Channel.values()) {
            channels.add(channel.getChannel());
        }

        return channels;
    }

    public static List<QName> getMatchingRuleList() {
        List<QName> list = new ArrayList<>();

        String NS_MATCHING_RULE = "http://prism.evolveum.com/xml/ns/public/matching-rule-3";

        list.add(new QName(NS_MATCHING_RULE, "default", "mr"));
        list.add(new QName(NS_MATCHING_RULE, "stringIgnoreCase", "mr"));
        list.add(new QName(NS_MATCHING_RULE, "polyStringStrict", "mr"));
        list.add(new QName(NS_MATCHING_RULE, "polyStringOrig", "mr"));
        list.add(new QName(NS_MATCHING_RULE, "polyStringNorm", "mr"));

        return list;
    }

    public static boolean isObjectOrgManager(PrismObject<? extends ObjectType> object) {
        if (object == null || object.asObjectable() == null) {
            return false;
        }

        ObjectType objectType = object.asObjectable();
        List<ObjectReferenceType> parentOrgRefs = objectType.getParentOrgRef();

        for (ObjectReferenceType ref : parentOrgRefs) {
            if (ref.getRelation() != null && ref.getRelation().equals(SchemaConstants.ORG_MANAGER)) {
                return true;
            }
        }

        return false;
    }

    public static String createHumanReadableByteCount(long bytes) {
        int unit = 1024;
        if (bytes < unit)
            return bytes + "B";
        int exp = (int) (Math.log(bytes) / Math.log(unit));
        char pre = "KMGTPE".charAt(exp - 1);
        return String.format("%.1f%sB", bytes / Math.pow(unit, exp), pre);
    }

    public static void setCurrentPage(Table table, ObjectPaging paging) {
        if (table == null) {
            return;
        }

        if (paging == null) {
            table.getDataTable().setCurrentPage(0);
            return;
        }

        long itemsPerPage = table.getDataTable().getItemsPerPage();
        long page = ((paging.getOffset() + itemsPerPage) / itemsPerPage) - 1;
        if (page < 0) {
            page = 0;
        }

        table.getDataTable().setCurrentPage(page);
    }

    public static PageBase getPageBase(Component component) {
        Page page = component.getPage();
        if (page instanceof PageBase) {
            return (PageBase) page;
        } else if (page instanceof PageDialog) {
            return ((PageDialog) page).getPageBase();
        } else {
            throw new IllegalStateException("Couldn't determine page base for " + page);
        }
    }

    public static <T extends Component> T theSameForPage(T object, PageReference containingPageReference) {
        Page containingPage = containingPageReference.getPage();
        if (containingPage == null) {
            return object;
        }
        String path = object.getPageRelativePath();
        T retval = (T) containingPage.get(path);
        if (retval == null) {
            return object;
            //            throw new IllegalStateException("There is no component like " + object + " (path '" + path + "') on " + containingPage);
        }
        return retval;
    }

    public static String debugHandler(IRequestHandler handler) {
        if (handler == null) {
            return null;
        }
        if (handler instanceof RenderPageRequestHandler) {
            return "RenderPageRequestHandler(" + ((RenderPageRequestHandler) handler).getPageClass().getName()
                    + ")";
        } else {
            return handler.toString();
        }
    }
}