All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.formkiq.server.service.FormServiceImpl Maven / Gradle / Ivy

The newest version!
package com.formkiq.server.service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.formkiq.server.dao.FormDao;
import com.formkiq.server.dao.UserDao;
import com.formkiq.server.domain.Asset;
import com.formkiq.server.domain.ClientForm;
import com.formkiq.server.domain.User;
import com.formkiq.server.domain.Workflow;
import com.formkiq.server.domain.type.ClientFormType;
import com.formkiq.server.domain.type.FormDTO;
import com.formkiq.server.domain.type.FormListDTO;
import com.formkiq.server.domain.type.SyncListDTO;
import com.formkiq.server.domain.type.UserPermission;
import com.formkiq.server.domain.type.UserRole;
import com.formkiq.server.domain.type.WorkflowListDTO;
import com.formkiq.server.service.dto.ArchiveDTO;

import javassist.bytecode.stackmap.TypeData.ClassName;

/**
 * FormService implementation.
 *
 */
@Service
public class FormServiceImpl implements FormService {

    /** Logger. */
    protected static final Logger LOG = Logger.getLogger(ClassName.class
            .getName());

    /** OAuthService. */
    @Autowired
    private OAuthService oauthservice;

    /** FormDao. */
	@Autowired
	private FormDao formDao;

    /** JSON Object Mapper. */
    @Autowired
    private Jackson2ObjectMapperBuilder jsonMapper;

	/** UserDao. */
	@Autowired
	private UserDao userDao;

    @Override
    public void deleteClientForm(final ClientFormType type, final String client,
            final String uuid) {

        if (!this.formDao.hasFormChildren(client, uuid)) {

            this.formDao.deleteForm(type, client, uuid);

        } else {
            throw new PreconditionFailedException(
                    "Child records need to be deleted first");
        }
    }

    /**
     * Extracts data from a byte[] zip file.
     * @param bytes bytes[]
     * @return {@link ArchiveDTO}
     */
    private ArchiveDTO extractJSONFromZipFile(final byte[] bytes) {

        ByteArrayInputStream is = new ByteArrayInputStream(bytes);
        ZipInputStream zipStream = new ZipInputStream(is);

        ArchiveDTO archive = new ArchiveDTO(this.jsonMapper);

        try {

            ZipEntry entry = null;
            while ((entry = zipStream.getNextEntry()) != null) {

                String filename = entry.getName();
                String data = IOUtils.toString(zipStream);

                if (filename.endsWith(".form")) {

                    archive.addForm(data);

                } else if (filename.endsWith(".workflow")) {

                    archive.addWorkflow(data);
                }
            }

        } catch (IOException e) {
            LOG.log(Level.WARNING, e.getMessage(), e);
            throw new InvalidRequestBodyException();

        } finally {

            IOUtils.closeQuietly(is);
            IOUtils.closeQuietly(zipStream);
        }

        return archive;
    }

    @Override
    public FormDTO findForm(final UserDetails ud, final String clientId,
            final String formId) {

        FormDTO dto = null;
        User user = (User) ud;

        ClientForm form = this.formDao.findForm(user, clientId, formId);

        if (form != null) {

            dto = new FormDTO();
            byte[] data = this.formDao.findAssetData(form.getAssetid());
            dto.setData(data);
            dto.setSha1hash(form.getSha1hash());
            dto.setPermission(getUserPermission(user));
        }

        if (dto == null) {
            throw new FormNotFoundException("form " + formId + " not found");
        }

        return dto;
    }

    @Override
    public byte[] findFormData(final String client, final String uuid)
            throws IOException {

        Map map = new HashMap();

        Object[] obj = findFormDataInternal(client, uuid);
        byte[] data = (byte[]) obj[0];
        map.put(uuid, data);

        ClientForm clientForm = (ClientForm) obj[1];

        if (ClientFormType.WORKFLOW.equals(clientForm.getType())) {

            Workflow workflow = this.jsonMapper.build()
                    .readValue(clientForm.getData(), Workflow.class);

            for (String formUUID : workflow.getSteps()) {

                obj = findFormDataInternal(client, formUUID);
                byte[] formdata = (byte[]) obj[0];
                map.put(formUUID, formdata);
            }
        }

        if (map.size() > 1) {
            return zipFile(map);
        }

        return map.values().iterator().next();
    }

    /**
     * Finds Form Data.
     * @param client {@link String}
     * @param uuid {@link String}
     * @return Object[]
     * @throws IOException IOException
     */
    private Object[] findFormDataInternal(final String client,
            final String uuid) throws IOException {

        ClientForm clientForm = this.formDao.findForm(client, uuid);

        if (clientForm != null) {
            byte[] data = this.formDao.findAssetData(clientForm.getAssetid());
            return new Object[] { data, clientForm };
        }

        throw new FormNotFoundException("form " + uuid + " not found");
    }

    @Override
    public FormListDTO findForms(final String client, final String token) {
        return this.formDao.findForms(ClientFormType.FORM, client, token);
    }

    @Override
    public FormListDTO findForms(final String client,
            final String form, final String token) {
        return this.formDao.findForms(ClientFormType.FORM, client, form, token);
    }

    @Override
    public FormDTO findWorkflow(final UserDetails ud, final String client,
            final String workflow) {
        FormDTO dto = null;
        User user = (User) ud;

        ClientForm wf = this.formDao.findForm(user, client,
                workflow);

        if (wf != null) {

            dto = new FormDTO();
            byte[] data = this.formDao.findAssetData(wf.getAssetid());
            dto.setData(data);
            dto.setSha1hash(wf.getSha1hash());
            dto.setPermission(getUserPermission(user));
        }

        if (dto == null) {
            throw new FormNotFoundException("form " + workflow + " not found");
        }

        return dto;
    }

    @Override
    public WorkflowListDTO findWorkflows(final String client,
            final String token) {
        FormListDTO dto = this.formDao.findForms(ClientFormType.WORKFLOW,
                client, token);
        WorkflowListDTO wdto = new WorkflowListDTO();
        wdto.setNexttoken(dto.getNexttoken());
        wdto.setPrevtoken(dto.getPrevtoken());
        wdto.setWorkflows(dto.getForms());
        return wdto;
    }

    @Override
    public WorkflowListDTO findWorkflows(final String client,
            final String workflow, final String token) {
        FormListDTO dto = this.formDao.findForms(ClientFormType.WORKFLOW,
                client, workflow, token);
        WorkflowListDTO wdto = new WorkflowListDTO();
        wdto.setNexttoken(dto.getNexttoken());
        wdto.setPrevtoken(dto.getPrevtoken());
        wdto.setWorkflows(dto.getForms());
        return wdto;
    }

    @Override
    public SyncListDTO getSyncList(final UserDetails ud, final String client,
            final String nextToken) {

        SyncListDTO dto = this.formDao.findFormSyncList(ClientFormType.FORM,
                client, nextToken);

        return dto;
    }

    @Override
    public SyncListDTO getSyncWorkflowList(final UserDetails user,
            final String client, final String nextToken) {
        SyncListDTO dto = this.formDao.findFormSyncList(ClientFormType.WORKFLOW,
                client, nextToken);
        return dto;
    }

    /**
     * @param user User
     * @return UserPermission
     */
    private UserPermission getUserPermission(final User user) {
        return UserRole.ROLE_ADMIN.equals(user.getRole())
                ? UserPermission.ROLE_WRITE : UserPermission.ROLE_READ;
    }

    /**
     * Saves Client Form.
     * @param ud {@link UserDetails}
     * @param type {@link ClientFormType}
     * @param client {@link String}
     * @param bytes byte[]
     * @return {@link String}
     */
    private String saveClientForm(final UserDetails ud,
            final ClientFormType type, final String client,
            final byte[] bytes) {

        User user = (User) ud;

        UserPermission permission = getUserPermission(user);

        if (UserPermission.ROLE_WRITE.equals(permission)) {

            ArchiveDTO archive = extractJSONFromZipFile(bytes);

            Date insertedDate = ClientFormType.FORM.equals(type)
                    ? archive.getForm().getInsertedDate()
                    : archive.getWorkflow().getInsertedDate();

            Date updatedDate = ClientFormType.FORM.equals(type)
                    ? archive.getForm().getUpdatedDate()
                    : archive.getWorkflow().getUpdatedDate();

            String uuid = ClientFormType.FORM.equals(type)
                    ? archive.getForm().getUUID()
                    : archive.getWorkflow().getUUID();

            String parentuuid = ClientFormType.FORM.equals(type)
                    ? archive.getForm().getParentUUID()
                    : archive.getWorkflow().getParentUUID();

            String data = ClientFormType.FORM.equals(type)
                    ? archive.getFormJSON() : archive.getWorkflowJSON();

            ClientForm clientForm = this.formDao.findForm(user, client, uuid);
            if (clientForm == null) {

                if (!this.oauthservice.isValidClient(client)) {
                    throw new FormAccessDeniedException();
                }

                if (!StringUtils.isEmpty(parentuuid)) {

                    if (this.formDao.findForm(user, client,
                            parentuuid) == null) {
                        throw new FormNotFoundException(
                                "form " + parentuuid + " not found");
                    }
                }

                clientForm = new ClientForm();
            }

            clientForm.setType(type);
            clientForm.setClientid(client);
            clientForm.setUUID(uuid);
            clientForm.setData(data);

            clientForm.setInsertedDate(insertedDate);
            clientForm.setUpdatedDate(updatedDate);
            clientForm.setParentUUID(parentuuid);

            updateAsset(clientForm, bytes);
            this.formDao.saveForm(clientForm);

            return clientForm.getSha1hash();
        }

        throw new FormAccessDeniedException();
	}

    @Override
    public String saveForm(final UserDetails ud, final String client,
            final byte[] bytes) {
        return saveClientForm(ud, ClientFormType.FORM, client, bytes);
    }

    @Override
    public String saveWorkflow(final UserDetails ud, final String client,
            final byte[] bytes) {
        return saveClientForm(ud, ClientFormType.WORKFLOW, client, bytes);
    }

    /**
     * Update Asset on ClientForm.
     * @param form {@link ClientForm}
     * @param bytes byte[]
     */
    private void updateAsset(final ClientForm form, final byte[] bytes) {

        Asset asset = null;
        String assetid = form.getAssetid();

        if (!StringUtils.isEmpty(assetid)) {

            asset = this.formDao.findAsset(assetid);
        }

        if (asset == null) {
            asset = new Asset();
        }

        asset.setData(this.userDao.convertToBlob(bytes));
        asset = this.formDao.saveAsset(asset);

        form.setAssetid(asset.getAssetId());
        form.setSha1hash(DigestUtils.sha1Hex(bytes));
    }

    /**
     * Create Zip file.
     * @param map {@link Map}
     * @return byte[] zip file
     * @throws IOException IOException
     */
    private byte[] zipFile(final Map map) throws IOException {

        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(bs);

        for (Map.Entry e : map.entrySet()) {

            String name = e.getKey();
            byte[] data = e.getValue();

            ZipEntry ze = new ZipEntry(name + ".zip");
            zip.putNextEntry(ze);

            zip.write(data, 0, data.length);
            zip.closeEntry();
        }

        byte[] bytes = bs.toByteArray();

        IOUtils.closeQuietly(bs);
        IOUtils.closeQuietly(zip);

        return bytes;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy