com.haulmont.cuba.core.jmx.PersistenceManager.java Source code

Java tutorial

Introduction

Here is the source code for com.haulmont.cuba.core.jmx.PersistenceManager.java

Source

/*
 * Copyright (c) 2008-2016 Haulmont.
 *
 * 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.haulmont.cuba.core.jmx;

import com.haulmont.chile.core.model.MetaClass;
import com.haulmont.cuba.core.*;
import com.haulmont.cuba.core.app.PersistenceConfig;
import com.haulmont.cuba.core.app.PersistenceManagerAPI;
import com.haulmont.cuba.core.app.ServerConfig;
import com.haulmont.cuba.core.entity.EntityStatistics;
import com.haulmont.cuba.core.global.Configuration;
import com.haulmont.cuba.core.global.Metadata;
import com.haulmont.cuba.core.global.QueryParser;
import com.haulmont.cuba.core.global.QueryTransformerFactory;
import com.haulmont.cuba.core.sys.DbInitializationException;
import com.haulmont.cuba.core.sys.DbUpdater;
import com.haulmont.cuba.core.sys.persistence.DbmsType;
import com.haulmont.cuba.security.app.Authenticated;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang.text.StrBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.inject.Inject;
import javax.persistence.Table;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

@Component("cuba_PersistenceManagerMBean")
public class PersistenceManager implements PersistenceManagerMBean {

    protected static final Logger log = LoggerFactory.getLogger(PersistenceManager.class);

    @Inject
    protected PersistenceManagerAPI persistenceManager;

    @Inject
    protected Persistence persistence;

    @Inject
    protected Metadata metadata;

    @Inject
    protected DbUpdater dbUpdater;

    @Inject
    protected PersistenceSecurity security;

    protected PersistenceConfig persistenceConfig;

    protected ServerConfig serverConfig;

    @Inject
    public void setConfiguration(Configuration configuration) {
        persistenceConfig = configuration.getConfig(PersistenceConfig.class);
        serverConfig = configuration.getConfig(ServerConfig.class);
    }

    @Override
    public String getDbmsType() {
        return DbmsType.getType();
    }

    @Override
    public String getDbmsVersion() {
        return DbmsType.getVersion();
    }

    @Override
    public int getDefaultLookupScreenThreshold() {
        return persistenceConfig.getDefaultLookupScreenThreshold();
    }

    @Authenticated
    @Override
    public void setDefaultLookupScreenThreshold(int value) {
        persistenceConfig.setDefaultLookupScreenThreshold(value);
    }

    @Override
    public int getDefaultLazyCollectionThreshold() {
        return persistenceConfig.getDefaultLazyCollectionThreshold();
    }

    @Authenticated
    @Override
    public void setDefaultLazyCollectionThreshold(int value) {
        persistenceConfig.setDefaultLazyCollectionThreshold(value);
    }

    @Override
    public int getDefaultFetchUI() {
        return persistenceConfig.getDefaultFetchUI();
    }

    @Authenticated
    @Override
    public void setDefaultFetchUI(int value) {
        persistenceConfig.setDefaultFetchUI(value);
    }

    @Override
    public int getDefaultMaxFetchUI() {
        return persistenceConfig.getDefaultMaxFetchUI();
    }

    @Authenticated
    @Override
    public void setDefaultMaxFetchUI(int value) {
        persistenceConfig.setDefaultMaxFetchUI(value);
    }

    @Override
    public String printViewRepositoryDump() {
        return new ViewRepositoryInfo(metadata).dump();
    }

    @Override
    public String printViewRepositoryDumpHtml() {
        return new ViewRepositoryInfo(metadata).dumpHtml();
    }

    @Authenticated
    @Override
    public String updateDatabase(String token) {
        if (!"update".equals(token))
            return "Pass 'update' in the method parameter if you really want to update database.";
        try {
            dbUpdater.updateDatabase();
            return "Updated";
        } catch (Throwable e) {
            return ExceptionUtils.getStackTrace(e);
        }
    }

    @Override
    public String findUpdateDatabaseScripts() {
        try {
            List<String> list = dbUpdater.findUpdateDatabaseScripts();
            if (!list.isEmpty()) {
                File dbDir = new File(serverConfig.getDbDir());

                String indent = "\t";
                StrBuilder sb = new StrBuilder();
                sb.append(dbDir.getPath().replace('\\', '/') + "/" + "\n");
                for (String path : list) {
                    sb.append(indent + path + "\n");
                }

                return sb.toString();
            } else
                return "No updates available";
        } catch (DbInitializationException e) {
            return e.getMessage();
        } catch (Throwable e) {
            return ExceptionUtils.getStackTrace(e);
        }
    }

    @Authenticated
    @Override
    public String jpqlLoadList(String queryString) {
        try {
            Transaction tx = persistence.createTransaction();
            try {
                EntityManager em = persistence.getEntityManager();
                Query query = em.createQuery(queryString);
                QueryParser parser = QueryTransformerFactory.createParser(queryString);
                Set<String> paramNames = parser.getParamNames();
                for (String paramName : paramNames) {
                    security.setQueryParam(query, paramName);
                }
                List resultList = query.getResultList();
                tx.commit();

                StrBuilder sb = new StrBuilder();
                for (Object element : resultList) {
                    if (element instanceof Object[]) {
                        sb.appendWithSeparators((Object[]) element, " | ");
                    } else {
                        sb.append(element);
                    }
                    sb.append("\n");
                }
                return sb.toString();
            } finally {
                tx.end();
            }
        } catch (Throwable e) {
            log.error("jpqlLoadList error", e);
            return ExceptionUtils.getStackTrace(e);
        }
    }

    @Authenticated
    @Override
    public String jpqlExecuteUpdate(String queryString, boolean softDeletion) {
        try {
            Transaction tx = persistence.createTransaction();
            try {
                EntityManager em = persistence.getEntityManager();
                em.setSoftDeletion(softDeletion);
                Query query = em.createQuery(queryString);
                int count = query.executeUpdate();
                tx.commit();

                return "Done: " + count + " entities affected, softDeletion=" + softDeletion;
            } finally {
                tx.end();
            }
        } catch (Throwable e) {
            log.error("jpqlExecuteUpdate error", e);
            return ExceptionUtils.getStackTrace(e);
        }
    }

    @Override
    public synchronized String flushStatisticsCache() {
        try {
            persistenceManager.flushStatisticsCache();
            return "Done";
        } catch (Exception e) {
            log.error("flushStatisticsCache error", e);
            return ExceptionUtils.getStackTrace(e);
        }
    }

    @Authenticated
    @Override
    public String refreshStatistics(String entityName) {
        if (StringUtils.isBlank(entityName))
            return "Pass an entity name (MetaClass name, e.g. sec$User) or 'all' to refresh statistics for all entities.\n"
                    + "Be careful, it can take very long time.";

        try {
            log.info("Refreshing statistics for " + entityName);

            Consumer<MetaClass> refreshStatisticsForEntity = mc -> {
                MetaClass originalMetaClass = metadata.getExtendedEntities().getOriginalOrThisMetaClass(mc);
                Class javaClass = originalMetaClass.getJavaClass();
                Table annotation = (Table) javaClass.getAnnotation(Table.class);
                if (annotation != null) {
                    persistenceManager.refreshStatisticsForEntity(originalMetaClass.getName());
                }
            };

            if ("all".equals(entityName)) {
                for (MetaClass metaClass : metadata.getSession().getClasses()) {
                    refreshStatisticsForEntity.accept(metaClass);
                }
            } else {
                MetaClass metaClass = metadata.getSession().getClass(entityName);
                if (metaClass == null)
                    return "MetaClass not found: " + entityName;
                refreshStatisticsForEntity.accept(metaClass);
            }
            return "Done";
        } catch (Exception e) {
            log.error("refreshStatistics error", e);
            return ExceptionUtils.getStackTrace(e);
        }
    }

    @Override
    public String showStatistics(String entityName) {
        try {
            Map<String, EntityStatistics> statistics = persistenceManager.getEntityStatistics();
            if (StringUtils.isBlank(entityName)) {
                StringBuilder sb = new StringBuilder();
                sb.append("Displaying statistics for all entities.\n");
                sb.append("To show a particular entity only, pass its name in the method parameter.\n\n");

                for (EntityStatistics stat : statistics.values()) {
                    sb.append(stat).append("\n");
                }

                return sb.toString();
            } else {
                EntityStatistics es = statistics.get(entityName);
                return es == null ? "No such entity" : es.toString();
            }
        } catch (Exception e) {
            log.error("showStatistics error", e);
            return ExceptionUtils.getStackTrace(e);
        }
    }

    @Authenticated
    @Override
    public synchronized String enterStatistics(String name, Long instanceCount, Integer fetchUI, Integer maxFetchUI,
            Integer lazyCollectionThreshold, Integer lookupScreenThreshold) {
        if (StringUtils.isBlank(name))
            return "Entity name is required";
        try {
            EntityStatistics es = persistenceManager.enterStatistics(name, instanceCount, fetchUI, maxFetchUI,
                    lazyCollectionThreshold, lookupScreenThreshold);

            StringBuilder sb = new StringBuilder("Statistics for ").append(name).append(" changed:\n");
            sb.append("instanceCount=").append(es.getInstanceCount()).append("\n");
            sb.append("fetchUI=").append(es.getFetchUI()).append("\n");
            sb.append("maxFetchUI=").append(es.getMaxFetchUI()).append("\n");
            sb.append("lazyCollectionThreshold=").append(es.getLazyCollectionThreshold()).append("\n");
            sb.append("lookupScreenThreshold=").append(es.getLookupScreenThreshold()).append("\n");
            return sb.toString();
        } catch (Exception e) {
            log.error("enterStatistics error", e);
            return ExceptionUtils.getStackTrace(e);
        }
    }

    @Authenticated
    @Override
    public String deleteStatistics(String name) {
        if (StringUtils.isBlank(name))
            return "Entity name is required";
        try {
            persistenceManager.deleteStatistics(name);
            return "Entity statistics for " + name + " has been deleted";
        } catch (Exception e) {
            log.error("deleteStatistics error", e);
            return ExceptionUtils.getStackTrace(e);
        }
    }
}