com.clican.pluto.cms.core.service.impl.IssueServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.clican.pluto.cms.core.service.impl.IssueServiceImpl.java

Source

/**
 * The Clican-Pluto software suit is Copyright 2009, Clican Company
 * and individual contributors, and is licensed under the GNU LGPL.
 *
 * @author wezhang
 *
 */
package com.clican.pluto.cms.core.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.runtime.RuntimeSingleton;
import org.apache.velocity.runtime.parser.node.SimpleNode;
import org.springframework.transaction.annotation.Transactional;

import com.clican.pluto.cms.core.service.DataModelService;
import com.clican.pluto.cms.core.service.IssueService;
import com.clican.pluto.cms.core.service.SiteService;
import com.clican.pluto.cms.dao.DataModelDao;
import com.clican.pluto.cms.dao.SiteDao;
import com.clican.pluto.cms.dao.TemplateDao;
import com.clican.pluto.common.constant.Constants;
import com.clican.pluto.common.util.BeanUtils;
import com.clican.pluto.orm.annotation.DynamicModel;
import com.clican.pluto.orm.desc.ModelDescription;
import com.clican.pluto.orm.dynamic.inter.ClassLoaderUtil;
import com.clican.pluto.orm.dynamic.inter.IDataModel;
import com.clican.pluto.orm.dynamic.inter.IDirectory;
import com.clican.pluto.orm.dynamic.inter.ISite;
import com.clican.pluto.orm.dynamic.inter.ITemplate;
import com.clican.pluto.orm.dynamic.inter.ITemplateDirectorySiteRelation;
import com.clican.pluto.orm.dynamic.inter.ITemplateModelSiteRelation;
import com.clican.pluto.orm.dynamic.inter.ModelContainer;
import com.clican.pluto.orm.enumeration.IssueMode;
import com.clican.pluto.orm.enumeration.IssueStatus;
import com.clican.pluto.orm.model.IssueQueue;

public class IssueServiceImpl extends BaseService implements IssueService {

    private TemplateDao templateDao;

    private ModelContainer modelContainer;

    private ClassLoaderUtil classLoaderUtil;

    private DataModelService dataModelService;

    private SiteDao siteDao;

    private DataModelDao dataModelDao;

    private SiteService siteService;

    public void setTemplateDao(TemplateDao templateDao) {
        this.templateDao = templateDao;
    }

    public void setSiteDao(SiteDao siteDao) {
        this.siteDao = siteDao;
    }

    public void setDataModelDao(DataModelDao dataModelDao) {
        this.dataModelDao = dataModelDao;
    }

    public void setModelContainer(ModelContainer modelContainer) {
        this.modelContainer = modelContainer;
    }

    public void setClassLoaderUtil(ClassLoaderUtil classLoaderUtil) {
        this.classLoaderUtil = classLoaderUtil;
    }

    public void setDataModelService(DataModelService dataModelService) {
        this.dataModelService = dataModelService;
    }

    public void setSiteService(SiteService siteService) {
        this.siteService = siteService;
    }

    @Transactional(readOnly = true)
    public void issue(IDataModel dataModel) {
        List<IssueQueue> queue = new ArrayList<IssueQueue>();
        List<ITemplateModelSiteRelation> tmrList = templateDao.getTemplateModelSiteRelations(dataModel);
        for (ITemplateModelSiteRelation tmr : tmrList) {
            IssueQueue iq = convertToIssueQueue(tmr);
            queue.add(iq);
        }
        IDirectory directory = dataModel.getParent();
        while (directory != null) {
            List<ITemplateDirectorySiteRelation> tdrList = templateDao.getTemplateDirectorySiteRelations(directory);
            for (ITemplateDirectorySiteRelation tdr : tdrList) {
                IssueQueue iq = convertToIssueQueue(tdr, dataModel);
                queue.add(iq);
            }
            if (directory.getIssueMode() == IssueMode.EXTENDS.getMode()) {
                directory = directory.getParent();
            } else {
                break;
            }

        }
        this.addIntoIssueQueue(queue, true);
    }

    private IssueQueue convertToIssueQueue(ITemplateModelSiteRelation rel) {
        IssueQueue iq = new IssueQueue();
        iq.setDataModelId(rel.getDataModel().getId());
        iq.setDataModelName(rel.getDataModel().getClass().getAnnotation(DynamicModel.class).name());
        iq.setIssueStatus(IssueStatus.NOT_ISSUE);
        iq.setRelativePath(rel.getRelativePath());
        iq.setSiteId(rel.getSite().getId());
        iq.setTemplateId(rel.getTemplate().getId());
        return iq;
    }

    private IssueQueue convertToIssueQueue(ITemplateDirectorySiteRelation rel, IDataModel dataModel) {
        IssueQueue iq = new IssueQueue();
        iq.setDataModelId(dataModel.getId());
        iq.setDataModelName(dataModel.getClass().getAnnotation(DynamicModel.class).name());
        iq.setIssueStatus(IssueStatus.NOT_ISSUE);
        String path1 = rel.getDirectory().getPath();
        String path2 = dataModel.getParent().getPath();
        String diff = path2.replaceAll(path1, "");
        iq.setRelativePath(rel.getRelativePath() + diff);
        iq.setSiteId(rel.getSite().getId());
        iq.setTemplateId(rel.getTemplate().getId());
        return iq;
    }

    @Transactional(readOnly = true)
    public void issue(List<IDataModel> dataModels, IDirectory parentDirectory) {
        List<IssueQueue> queue = new ArrayList<IssueQueue>();
        Map<ModelDescription, List<IDataModel>> dataModelMap = new HashMap<ModelDescription, List<IDataModel>>();
        for (IDataModel dataModel : dataModels) {
            ModelDescription md = modelContainer
                    .getModelDesc(classLoaderUtil.getClass(dataModel).getAnnotation(DynamicModel.class).name());
            if (!dataModelMap.containsKey(md)) {
                dataModelMap.put(md, new ArrayList<IDataModel>());
            }
            dataModelMap.get(md).add(dataModel);
        }
        for (ModelDescription md : dataModelMap.keySet()) {
            List<IDataModel> dataModelList = dataModelMap.get(md);
            for (int i = 0; i < dataModelList.size(); i = i + 1000) {
                int start = i;
                int end = i + 1000 > dataModelList.size() ? dataModelList.size() : i + 1000;
                List<ITemplateModelSiteRelation> tmrList = templateDao
                        .getTemplateModelSiteRelations(dataModelList.subList(start, end), md);
                for (ITemplateModelSiteRelation tmr : tmrList) {
                    IssueQueue iq = convertToIssueQueue(tmr);
                    queue.add(iq);
                }
            }
        }
        while (parentDirectory != null) {
            List<ITemplateDirectorySiteRelation> tdrList = templateDao
                    .getTemplateDirectorySiteRelations(parentDirectory);
            for (ITemplateDirectorySiteRelation tdr : tdrList) {
                for (IDataModel dataModel : dataModels) {
                    IssueQueue iq = convertToIssueQueue(tdr, dataModel);
                    queue.add(iq);
                }
            }
            if (parentDirectory.getIssueMode() == IssueMode.EXTENDS.getMode()) {
                parentDirectory = parentDirectory.getParent();
            } else {
                break;
            }

        }
        this.addIntoIssueQueue(queue, true);
    }

    @Transactional(readOnly = true)
    public void issue(IDirectory directory, boolean recursion) {
        List<IDataModel> dataModels = dataModelService.getDataModels(directory, null, null);
        issue(dataModels, directory);
        if (recursion) {
            for (IDirectory child : directory.getChildren()) {
                issue(child, recursion);
            }
        }
    }

    private void addIntoIssueQueue(List<IssueQueue> queue, boolean reverse) {
        Map<Long, ISite> siteMap = BeanUtils.convertToMap(siteDao.getAllSites(), "id");
        Map<Long, ITemplate> templateMap = BeanUtils.convertToMap(templateDao.getAllTemplates(), "id");
        if (reverse) {
            for (int i = queue.size() - 1; i >= 0; i--) {
                IssueQueue iq = queue.get(i);
                ISite site = siteMap.get(iq.getSiteId());
                ITemplate template = templateMap.get(iq.getTemplateId());
                IDataModel dataModel = dataModelDao.loadDataModel(
                        classLoaderUtil.getClass(Constants.DYNAMIC_MODEL_PACKAGE + "." + iq.getDataModelName()),
                        iq.getDataModelId());
                issue(site, template, dataModel, iq.getRelativePath(), null);
            }
        } else {
            for (int i = 0; i < queue.size(); i++) {
                IssueQueue iq = queue.get(i);
                ISite site = siteMap.get(iq.getSiteId());
                ITemplate template = templateMap.get(iq.getTemplateId());
                IDataModel dataModel = dataModelDao.loadDataModel(
                        classLoaderUtil.getClass(Constants.DYNAMIC_MODEL_PACKAGE + "." + iq.getDataModelName()),
                        iq.getDataModelId());
                issue(site, template, dataModel, iq.getRelativePath(), null);
            }
        }
    }

    private boolean issue(ISite site, ITemplate template, IDataModel dataModel, String relativePath,
            Map<ISite, FTPClient> ftpMap) {
        Template t = null;
        Writer w = null;
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("this", dataModel);
        FTPClient client = null;
        try {
            SimpleNode node = RuntimeSingleton.getRuntimeServices().parse(template.getContent(),
                    template.getName());
            t = new Template();
            t.setName(template.getName());
            t.setRuntimeServices(RuntimeSingleton.getRuntimeServices());
            t.setData(node);
            t.initDocument();
            OutputStream os = null;
            if (site.getUrl().startsWith("ftp://")) {
                client = null;
                if (ftpMap != null) {
                    client = ftpMap.get(site);
                }
                if (client == null) {
                    client = siteService.getFTPClient(site);
                }
                if (client == null) {
                    log.error("This site[" + site.getName() + "] is unavailable");
                    return false;
                }
                if (!relativePath.endsWith("/")) {
                    relativePath = relativePath + "/";
                }
                client.mkd(relativePath);
                os = client.appendFileStream(relativePath + dataModel.getName() + "." + template.getSuffix());
            } else if (site.getUrl().startsWith("file://")) {
                String filePath = site.getUrl().substring(7);
                File file = new File(filePath + relativePath);
                if (file.exists()) {
                    file.mkdirs();
                }
                os = new FileOutputStream(new File(file, dataModel.getName() + "." + template.getSuffix()));
            } else {
                throw new UnknownHostException(site.getUrl());
            }
            w = new OutputStreamWriter(os, "utf-8");
            t.merge(velocityContext, w);
            w.flush();
            return true;
        } catch (Exception e) {
            log.error("", e);
            return false;
        } finally {
            try {
                if (w != null) {
                    w.close();
                }
            } catch (Exception e) {
                log.error("", e);
            }
            try {
                if (ftpMap == null && client != null) {
                    client.logout();
                    client.disconnect();
                }
            } catch (Exception e) {
                log.error("", e);
            }
        }
    }
}

// $Id$