/*
 * Copyright (C) 2005 - 2011 Jaspersoft Corporation. All rights reserved.
 * http://www.jaspersoft.com.
 *
 * Unless you have purchased  a commercial license agreement from Jaspersoft,
 * the following license terms  apply:
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License  as
 * published by the Free Software Foundation, either version 3 of  the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero  General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public  License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.jaspersoft.jasperserver.api.metadata.view.service.impl;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.security.Authentication;

import com.jaspersoft.jasperserver.api.common.domain.ExecutionContext;
import com.jaspersoft.jasperserver.api.common.domain.impl.ExecutionContextImpl;
import com.jaspersoft.jasperserver.api.metadata.common.domain.DataType;
import com.jaspersoft.jasperserver.api.metadata.common.domain.FileResource;
import com.jaspersoft.jasperserver.api.metadata.common.domain.Folder;
import com.jaspersoft.jasperserver.api.metadata.common.domain.InputControl;
import com.jaspersoft.jasperserver.api.metadata.common.domain.ListOfValues;
import com.jaspersoft.jasperserver.api.metadata.common.domain.ListOfValuesItem;
import com.jaspersoft.jasperserver.api.metadata.common.domain.Query;
import com.jaspersoft.jasperserver.api.metadata.common.domain.Resource;
import com.jaspersoft.jasperserver.api.metadata.common.domain.ResourceLookup;
import com.jaspersoft.jasperserver.api.metadata.common.domain.ResourceReference;
import com.jaspersoft.jasperserver.api.metadata.common.domain.client.DataTypeImpl;
import com.jaspersoft.jasperserver.api.metadata.common.domain.client.FolderImpl;
import com.jaspersoft.jasperserver.api.metadata.common.domain.client.ListOfValuesItemImpl;
import com.jaspersoft.jasperserver.api.metadata.common.service.RepositoryService;
import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.BeanReportDataSource;
import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.JdbcReportDataSource;
import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.JndiJdbcReportDataSource;
import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.ReportDataSource;
import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.ReportUnit;
import com.jaspersoft.jasperserver.api.metadata.security.JasperServerAclEntry;
import com.jaspersoft.jasperserver.api.metadata.user.domain.Role;
import com.jaspersoft.jasperserver.api.metadata.user.domain.User;
import com.jaspersoft.jasperserver.api.metadata.view.domain.FilterCriteria;
import com.jaspersoft.jasperserver.api.metadata.view.domain.FilterElementDisjunction;
import com.jaspersoft.jasperserver.api.metadata.view.domain.FilterElementOr;
import com.jaspersoft.jasperserver.api.search.SearchFilter;
import com.jaspersoft.jasperserver.api.search.TransformerFactory;
import com.jaspersoft.jasperserver.search.filter.FolderFilter;
import com.jaspersoft.jasperserver.search.transformer.BasicTransformerFactory;
import com.jaspersoft.jasperserver.util.test.BaseJasperServerTest;

/**
 * @author Lucian Chirita (lucianc@users.sourceforge.net)
 * @version $Id: HibernateRepositoryTest.java 20088 2011-02-01 21:06:36Z andy21ca $
 */
public class HibernateRepositoryTest extends BaseJasperServerTest {

	User user;
	Role role;
	Authentication auth;
	
	public HibernateRepositoryTest(String name) {
        super(name);
		setAutowireMode(AUTOWIRE_BY_NAME);
    }

    public void testDeleteFolder() {
        RepositoryService repositoryService = getUnsecureRepositoryService();
        assertNotNull("Repository service should not be null", repositoryService);

        Folder tmpFolder = new FolderImpl();
        setCommon(tmpFolder, "tmp_foo");
        repositoryService.saveFolder(null, tmpFolder);

        Folder subtmpFolder = new FolderImpl();
        setCommon(subtmpFolder, "sub");
        subtmpFolder.setParentFolder(tmpFolder);
        repositoryService.saveFolder(null, subtmpFolder);

        JndiJdbcReportDataSource ds = (JndiJdbcReportDataSource) repositoryService.newResource(null,
            JndiJdbcReportDataSource.class);
        setCommon(ds, "dummyDS");
        ds.setJndiName("foo");
        ds.setParentFolder(tmpFolder);
        repositoryService.saveResource(null, ds);

        JndiJdbcReportDataSource subds = (JndiJdbcReportDataSource) repositoryService.newResource(null,
            JndiJdbcReportDataSource.class);
        setCommon(subds, "subDS");
        subds.setJndiName("subfoo");
        subds.setParentFolder(subtmpFolder);
        repositoryService.saveResource(null, subds);

        Resource dsResource = repositoryService.getResource(null, "/tmp_foo/dummyDS");
        assertNotNull(dsResource);
        assertTrue(dsResource instanceof JndiJdbcReportDataSource);
        ds = (JndiJdbcReportDataSource) dsResource;
        assertEquals("foo", ds.getJndiName());

        Resource subdsResource = repositoryService.getResource(null, "/tmp_foo/sub/subDS");
        assertNotNull(subdsResource);
        assertTrue(subdsResource instanceof JndiJdbcReportDataSource);
        subds = (JndiJdbcReportDataSource) subdsResource;
        assertEquals("subfoo", subds.getJndiName());

        /* Testing target method. */
        repositoryService.deleteFolder(null, "/tmp_foo");

        List folders = repositoryService.getSubFolders(null, "/");
        for (Iterator it = folders.iterator(); it.hasNext();) {
            Folder folder = (Folder) it.next();
            assertFalse("tmp_foo".equals(folder.getName()));
        }

        dsResource = repositoryService.getResource(null, "/tmp_foo/dummyDS");
        assertNull(dsResource);

        subdsResource = repositoryService.getResource(null, "/tmp_foo/dummyDS");
        assertNull(subdsResource);
    }

    public void testDeleteRollback() {
        RepositoryService repositoryService = getUnsecureRepositoryService();
        assertNotNull("Repository service should not be null", repositoryService);

        Folder tmp1 = new FolderImpl();
        setCommon(tmp1, "tmp1");
        repositoryService.saveFolder(null, tmp1);

        Folder tmp2 = new FolderImpl();
        setCommon(tmp2, "tmp2");
        repositoryService.saveFolder(null, tmp2);

        tmp1 = repositoryService.getFolder(null, "/tmp1");
        assertNotNull(tmp1);
        assertEquals("tmp1", tmp1.getName());

        tmp2 = repositoryService.getFolder(null, "/tmp2");
        assertNotNull(tmp2);
        assertEquals("tmp2", tmp2.getName());

        /* Stub for execution context. */
        ExecutionContext executionContext = new ExecutionContextImpl();

        /* Testing target method. */
        repositoryService.deleteFolder(executionContext, "/tmp1");
        repositoryService.deleteFolder(executionContext, "/tmp2");

        tmp1 = repositoryService.getFolder(null, "/tmp1");
        assertNull(tmp1);

        tmp2 = repositoryService.getFolder(null, "/tmp2");
        assertNull(tmp2);
    }

    public void testFolderUpdate() {
        assertNotNull("Repo not null", getUnsecureRepositoryService());

        // need to authenticate the user, even though we are using the unsecureRepositoryService
        // the optimisticLocking() method gets exception if not authenticated
        user = findOrCreateUser(BaseJasperServerTest.USER_JASPERADMIN);
		auth = setAuthenticatedUser(BaseJasperServerTest.USER_JASPERADMIN);
        
        Folder folder = new FolderImpl();
        setCommon(folder, "test_update");
        getUnsecureRepositoryService().saveFolder(null, folder);

        JndiJdbcReportDataSource ds = (JndiJdbcReportDataSource) getUnsecureRepositoryService().newResource(null, JndiJdbcReportDataSource.class);
        setCommon(ds, "fooDS");
        ds.setJndiName("foo");
        ds.setParentFolder(folder);
        getUnsecureRepositoryService().saveResource(null, ds);

        folder = getUnsecureRepositoryService().getFolder(null, "/test_update");
        assertNotNull(folder);
        assertEquals("test_update", folder.getName());
        assertEquals("test_update_label", folder.getLabel());

        folder.setLabel("updated");
        getUnsecureRepositoryService().saveFolder(null, folder);

        folder = getUnsecureRepositoryService().getFolder(null, "/test_update");
        assertNotNull(folder);
        assertEquals("test_update", folder.getName());
        assertEquals("updated", folder.getLabel());

        Resource resource = getUnsecureRepositoryService().getResource(null, "/test_update/fooDS");
        assertNotNull(resource);
        assertTrue(resource instanceof JndiJdbcReportDataSource);
        ds = (JndiJdbcReportDataSource) resource;
        assertEquals("fooDS", ds.getName());
        assertEquals("foo", ds.getJndiName());

        getUnsecureRepositoryService().deleteFolder(null, "/test_update");
        folder = getUnsecureRepositoryService().getFolder(null, "/test_update");
        assertNull(folder);
    }

    public void testRepo() throws Exception {
        assertNotNull("Repo not null", getUnsecureRepositoryService());
        
        write();

        read();

        readFolders();

        update();

        optimisticLocking();

        list();

        resources();
        
        setupExecuteOnlyPerms();

        // TODO disabled to allow build to run
        //deleteRollback();
    }

    private void deleteRollback() {
        boolean exception = false;
        try {
            getUnsecureRepositoryService().delete(null, new String[]{"/datasources/JServerJdbcDS"}, null);
        } catch (Exception e) {
            exception = true;
        }
        assertTrue(exception);

        Resource resource = getUnsecureRepositoryService().getResource(null, "/datasources/JServerJdbcDS");
        assertNotNull(resource);
        assertTrue(resource instanceof JdbcReportDataSource);
    }

    private void write() throws Exception {
        Folder dsFolder = new FolderImpl();
        dsFolder.setName("datasources");
        dsFolder.setLabel("Data Sources");
        dsFolder.setDescription("Data Sources used by reports");
        getUnsecureRepositoryService().saveFolder(null, dsFolder);

        createJndiDS();
        createRepoDS();
        createJdbcDS();
        createBeanDS();
        createTableModelDS();

        Folder reportsFolder = new FolderImpl();
        reportsFolder.setName("reports");
        reportsFolder.setLabel("Reports");
        reportsFolder.setDescription("Reports");
        getUnsecureRepositoryService().saveFolder(null, reportsFolder);

        // bug #22094. ROLE_USER should have write access to the /reports folder.
        Role userRole = getOrCreateRole(userRoleName);
        createObjectPermission("/reports", userRole, JasperServerAclEntry.READ_WRITE_CREATE_DELETE);

        Folder samplesFolder = new FolderImpl();
        samplesFolder.setName("samples");
        samplesFolder.setLabel("Samples");
        samplesFolder.setDescription("Samples");
        samplesFolder.setParentFolder(reportsFolder);
        getUnsecureRepositoryService().saveFolder(null, samplesFolder);

        createAllAccounts(samplesFolder);
        createSalesByMonth(samplesFolder);
        createCustomDSReportFileResource(samplesFolder);
        createCustomDSReport(samplesFolder);
        createTableModelDSReport(samplesFolder);
        createEmployeeAccounts(samplesFolder);
        createEmployees(samplesFolder);
        createParamMany(samplesFolder);
        createAllCharts(samplesFolder);
        createAllCascading(samplesFolder);
        createOFCReport(samplesFolder);

        createImage();

        Folder olapFolder = new FolderImpl();
        olapFolder.setName("analysis");
        olapFolder.setLabel("Analysis Components");
        olapFolder.setDescription("Analysis Components");
        getUnsecureRepositoryService().saveFolder(null, olapFolder);

        Folder connectionsFolder = new FolderImpl();
        connectionsFolder.setName("connections");
        connectionsFolder.setLabel("Analysis Connections");
        connectionsFolder.setDescription("Connections used by Analysis");
        connectionsFolder.setParentFolder(olapFolder);
        getUnsecureRepositoryService().saveFolder(null, connectionsFolder);

        Folder schemasFolder = new FolderImpl();
        schemasFolder.setName("schemas");
        schemasFolder.setLabel("Analysis Schemas");
        schemasFolder.setDescription("Schemas used by Analysis");
        schemasFolder.setParentFolder(olapFolder);
        getUnsecureRepositoryService().saveFolder(null, schemasFolder);

        Folder olapDsFolder = new FolderImpl();
        olapDsFolder.setName("datasources");
        olapDsFolder.setLabel("Analysis Data Sources");
        olapDsFolder.setDescription("Data sources used by Analysis");
        olapDsFolder.setParentFolder(olapFolder);
        getUnsecureRepositoryService().saveFolder(null, olapDsFolder);

        Folder olapViewsFolder = new FolderImpl();
        olapViewsFolder.setName("views");
        olapViewsFolder.setLabel("Analysis Views");
        olapViewsFolder.setDescription("Analysis Views");
        olapViewsFolder.setParentFolder(olapFolder);
        getUnsecureRepositoryService().saveFolder(null, olapViewsFolder);
    }

    private void createImage() {
        Folder folder = new FolderImpl();
        folder.setName("images");
        folder.setLabel("Images");
        folder.setDescription("Folder containing reusable images");
        getUnsecureRepositoryService().saveFolder(null, folder);

        FileResource image = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        image.setFileType(FileResource.TYPE_IMAGE);
        image.readData(getClass().getResourceAsStream("/images/jasperreports.png"));
        image.setName("JRLogo");
        image.setLabel("JR logo");
        image.setDescription("JR logo");
        image.setParentFolder(folder);

        getUnsecureRepositoryService().saveResource(null, image);
    }

    private void createJndiDS() throws Exception {
        JndiJdbcReportDataSource datasource = (JndiJdbcReportDataSource) getUnsecureRepositoryService().newResource(null, JndiJdbcReportDataSource.class);
        datasource.setName("JServerJNDIDS");
        datasource.setLabel("JServer JNDI Data Source");
        datasource.setDescription("JServer JNDI Data Source");
        datasource.setJndiName(getJdbcProps().getProperty("test.jndi"));
        datasource.setParentFolder("/datasources");

        getUnsecureRepositoryService().saveResource(null, datasource);
    }

    private void createRepoDS() throws Exception {
        JndiJdbcReportDataSource datasource = (JndiJdbcReportDataSource) getUnsecureRepositoryService().newResource(null, JndiJdbcReportDataSource.class);
        datasource.setName("repositoryDS");
        datasource.setLabel("Jasperserver Repository SQL data source");
        datasource.setDescription("Jasperserver Repository SQL data source for reporting");
        datasource.setJndiName(getJdbcProps().getProperty("metadata.jndi"));
        datasource.setParentFolder("/datasources");

        getUnsecureRepositoryService().saveResource(null, datasource);
    }

    private void createJdbcDS() throws Exception {
        JdbcReportDataSource datasource = (JdbcReportDataSource) getUnsecureRepositoryService().newResource(null, JdbcReportDataSource.class);
        datasource.setName("JServerJdbcDS");
        datasource.setLabel("JServer Jdbc Data Source");
        datasource.setDescription("JServer Jdbc Data Source");
        datasource.setParentFolder("/datasources");

        datasource.setDriverClass(getJdbcProps().getProperty("test.jdbc.driverClassName"));
        datasource.setConnectionUrl(getJdbcProps().getProperty("test.jdbc.url"));
        datasource.setUsername(getJdbcProps().getProperty("test.jdbc.username"));
        datasource.setPassword(getJdbcProps().getProperty("test.jdbc.password"));

        getUnsecureRepositoryService().saveResource(null, datasource);
    }

    private void createBeanDS() {
        BeanReportDataSource datasource = (BeanReportDataSource) getUnsecureRepositoryService().newResource(null, BeanReportDataSource.class);
        datasource.setName("CustomDSFromBean");
        datasource.setLabel("Custom data source from a bean");
        datasource.setDescription("A custom data source through a bean");
        datasource.setParentFolder("/datasources");

        datasource.setBeanName("customTestDataSourceService");

        getUnsecureRepositoryService().saveResource(null, datasource);
    }

    private void createTableModelDS() {
        BeanReportDataSource datasource = (BeanReportDataSource) getUnsecureRepositoryService().newResource(null, BeanReportDataSource.class);
        datasource.setName("CustomTableModelDS");
        datasource.setLabel("Custom data source from a table model");
        datasource.setDescription("A custom data source through a table model");
        datasource.setParentFolder("/datasources");

        datasource.setBeanName("customTestDataSourceServiceFactory");
        datasource.setBeanMethod("tableModelDataSource");

        getUnsecureRepositoryService().saveResource(null, datasource);
    }

    private void createSalesByMonth(Folder folder) {
        FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        reportRes.setFileType(FileResource.TYPE_JRXML);
        reportRes.setName("SalesByMonthReport");
        reportRes.setLabel("Sales By Month Jasper Report");
        reportRes.setDescription("Sales By Month Jasper Report");

        InputStream jrxml = getClass().getResourceAsStream("/reports/jasper/SalesByMonth.jrxml");
        reportRes.readData(jrxml);

        ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
        unit.setName("SalesByMonth");
        unit.setLabel("Sales By Month Report");
        unit.setDescription("Sales By Month Report");
        unit.setParentFolder(folder);

        unit.setDataSourceReference("/datasources/JServerJNDIDS");
        unit.setMainReport(reportRes);

        FileResource jar = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        jar.setFileType(FileResource.TYPE_JAR);
        jar.readData(getClass().getResourceAsStream("/jars/scriptlet.jar"));
        setCommon(jar, "Scriptlet");
        unit.addResource(jar);

        FileResource img = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        img.setFileType(FileResource.TYPE_IMAGE);
        img.readData(getClass().getResourceAsStream("/images/jasperreports.png"));
        setCommon(img, "Logo");
        unit.addResource(img);

        FileResource subrep = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        subrep.setFileType(FileResource.TYPE_JRXML);
        subrep.readData(getClass().getResourceAsStream("/reports/jasper/SalesByMonthDetail.jrxml"));
        setCommon(subrep, "SalesByMonthDetail");
        unit.addResource(subrep);

        FileResource resBdl = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        resBdl.setFileType(FileResource.TYPE_RESOURCE_BUNDLE);
        resBdl.readData(getClass().getResourceAsStream("/resource_bundles/sales.properties"));
        setCommon(resBdl, "sales.properties");
        unit.addResource(resBdl);

        FileResource resBdl_ro = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        resBdl_ro.setFileType(FileResource.TYPE_RESOURCE_BUNDLE);
        resBdl_ro.readData(getClass().getResourceAsStream("/resource_bundles/sales_ro.properties"));
        setCommon(resBdl_ro, "sales_ro.properties");
        unit.addResource(resBdl_ro);

        InputControl textInputCtrl = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
        setCommon(textInputCtrl, "TextInputControl");
        textInputCtrl.setType(InputControl.TYPE_SINGLE_VALUE);
        textInputCtrl.setMandatory(false);
        textInputCtrl.setReadOnly(false);
        textInputCtrl.setVisible(true);
        //FIXME textInputCtrl.setSize(new Integer(30));
        textInputCtrl.setLabel("Text Input Control");
        textInputCtrl.setName("TextInput");
        DataType dataType = new DataTypeImpl();
        dataType.setName("test");
        dataType.setLabel("test");
        dataType.setType(DataType.TYPE_NUMBER);
        textInputCtrl.setDataType(dataType);
        unit.addInputControl(textInputCtrl);

        InputControl checkboxInputControl = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
        setCommon(checkboxInputControl, "CheckboxInputControl");
        checkboxInputControl.setType(InputControl.TYPE_BOOLEAN);
        checkboxInputControl.setMandatory(true);
        checkboxInputControl.setReadOnly(false);
        checkboxInputControl.setVisible(true);
        checkboxInputControl.setLabel("Checkbox Input Control");
        checkboxInputControl.setName("CheckboxInput");
        unit.addInputControl(checkboxInputControl);

        InputControl listInputControl = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
        setCommon(listInputControl, "ListInputControl");
        listInputControl.setType(InputControl.TYPE_SINGLE_SELECT_LIST_OF_VALUES);
        listInputControl.setMandatory(true);
        listInputControl.setReadOnly(false);
        listInputControl.setVisible(true);
        listInputControl.setLabel("List Input Control");
        listInputControl.setName("ListInput");

        ListOfValues values = (ListOfValues) getUnsecureRepositoryService().newResource(null, ListOfValues.class);
        values.setName("List_of_values");
        values.setLabel("List of values label");
        values.setDescription("List of values description");
        ListOfValuesItem item = new ListOfValuesItemImpl();
        item.setLabel("An item");
        item.setValue("1");
        values.addValue(item);
        item = new ListOfValuesItemImpl();
        item.setLabel("Another item");
        item.setValue("2");
        values.addValue(item);
        item = new ListOfValuesItemImpl();
        item.setLabel("Yet another item");
        item.setValue("3");
        values.addValue(item);
        listInputControl.setListOfValues(values);

        dataType = new DataTypeImpl();
        dataType.setName("test");
        dataType.setLabel("test");
        dataType.setType(DataType.TYPE_TEXT);
        listInputControl.setDataType(dataType);

        unit.addInputControl(listInputControl);

        createDateDatatype();

        InputControl dateInputCtrl = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
        setCommon(dateInputCtrl, "DateInput");
        dateInputCtrl.setType(InputControl.TYPE_SINGLE_VALUE);
        dateInputCtrl.setMandatory(false);
        dateInputCtrl.setReadOnly(false);
        dateInputCtrl.setVisible(true);
        dateInputCtrl.setDataTypeReference("/datatypes/date");
        unit.addInputControl(dateInputCtrl);

        InputControl queryInputCtrl = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
        setCommon(queryInputCtrl, "QueryInput");
        queryInputCtrl.setType(InputControl.TYPE_SINGLE_SELECT_QUERY);
        queryInputCtrl.setMandatory(false);
        queryInputCtrl.setReadOnly(false);
        queryInputCtrl.setVisible(true);
        queryInputCtrl.setQueryValueColumn("user_name");
        queryInputCtrl.addQueryVisibleColumn("first_name");
        queryInputCtrl.addQueryVisibleColumn("last_name");
        Query query = (Query) getUnsecureRepositoryService().newResource(null, Query.class);
        setCommon(query, "testQuery");
        query.setLanguage("sql");
        query.setSql("select user_name, first_name, last_name from users");
        queryInputCtrl.setQuery(query);
        unit.addInputControl(queryInputCtrl);

        unit.setAlwaysPromptControls(false);

        getUnsecureRepositoryService().saveResource(null, unit);
    }

    private void createEmployees(Folder folder) {
        FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        reportRes.setFileType(FileResource.TYPE_JRXML);
        setCommon(reportRes, "EmployeesJRXML");

        InputStream jrxml = getClass().getResourceAsStream("/reports/jasper/Employees.jrxml");
        reportRes.readData(jrxml);

        ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
        unit.setName("Employees");
        unit.setLabel("Employee List");
        unit.setDescription("Employee List");
        unit.setParentFolder(folder);

        unit.setDataSourceReference("/datasources/JServerJNDIDS");
        unit.setMainReport(reportRes);

        getUnsecureRepositoryService().saveResource(null, unit);
    }

    private void createEmployeeAccounts(Folder folder) {
        FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        reportRes.setFileType(FileResource.TYPE_JRXML);
        setCommon(reportRes, "EmployeeAccountsJRXML");

        InputStream jrxml = getClass().getResourceAsStream("/reports/jasper/EmployeeAccounts.jrxml");
        reportRes.readData(jrxml);

        ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
        unit.setName("EmployeeAccounts");
        unit.setLabel("Employee Accounts");
        unit.setDescription("List of Accounts per Employee");
        unit.setParentFolder(folder);

        unit.setDataSourceReference("/datasources/JServerJNDIDS");
        unit.setMainReport(reportRes);

        InputControl empIC = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
        empIC.setName("EmployeeID");
        empIC.setLabel("Employee");
        empIC.setMandatory(true);

        Query empQuery = (Query) getUnsecureRepositoryService().newResource(null, Query.class);
        empQuery.setName("EmployeeQuery");
        empQuery.setLabel("Employee Query");
        empQuery.setLanguage("sql");
        empQuery.setSql("SELECT id, user_name FROM users WHERE employee_status = 'Active'");

        empIC.setType(InputControl.TYPE_SINGLE_SELECT_QUERY);
        empIC.setQuery(empQuery);
        empIC.setQueryValueColumn("id");
        empIC.addQueryVisibleColumn("user_name");

        unit.addInputControl(empIC);
        unit.setAlwaysPromptControls(false);

        getUnsecureRepositoryService().saveResource(null, unit);
    }

    private void createParamMany(Folder folder) {
        FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        reportRes.setFileType(FileResource.TYPE_JRXML);
        setCommon(reportRes, "ParametersJRXML");

        InputStream jrxml = getClass().getResourceAsStream("/reports/jasper/ParamMany.jrxml");
        reportRes.readData(jrxml);

        ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
        unit.setName("Freight");
        unit.setLabel("Freight Report");
        unit.setDescription("Freight Report with Saved Parameters");
        unit.setParentFolder(folder);

        unit.setDataSourceReference("/datasources/JServerJNDIDS");
        unit.setMainReport(reportRes);

        // Country
        InputControl countryIC = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
        countryIC.setName("Country");
        countryIC.setLabel("Country");
        countryIC.setDescription("Country");
        countryIC.setMandatory(true);
        countryIC.setType(InputControl.TYPE_SINGLE_SELECT_QUERY);

        Query countryQ = (Query) getUnsecureRepositoryService().newResource(null, Query.class);
        countryQ.setName("CountryQuery");
        countryQ.setLabel("CountryQuery");
        countryQ.setLanguage("sql");
        countryQ.setDataSourceReference("/datasources/JServerJNDIDS");
        countryQ.setSql("select distinct SHIPCOUNTRY from ORDERS");
        countryIC.setQuery(countryQ);

        countryIC.setQueryValueColumn("SHIPCOUNTRY");
        countryIC.addQueryVisibleColumn("SHIPCOUNTRY");

        unit.addInputControl(countryIC);

        // Request Date
        InputControl requestDateIC = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
        requestDateIC.setName("RequestDate");
        requestDateIC.setLabel("RequestDate");
        requestDateIC.setDescription("RequestDate");
        requestDateIC.setMandatory(false);
        requestDateIC.setType(InputControl.TYPE_SINGLE_VALUE);

        DataType dateDT = (DataType) getUnsecureRepositoryService().newResource(null, DataType.class);
        setCommon(dateDT, "Date");
        dateDT.setType(DataType.TYPE_DATE);
        requestDateIC.setDataType(dateDT);

        unit.addInputControl(requestDateIC);

        // Order Id
        InputControl orderIdIC = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
        orderIdIC.setName("OrderId");
        orderIdIC.setLabel("OrderId");
        orderIdIC.setDescription("OrderId");
        orderIdIC.setMandatory(false);
        orderIdIC.setType(InputControl.TYPE_SINGLE_VALUE);

        DataType numberDT = (DataType) getUnsecureRepositoryService().newResource(null, DataType.class);
        setCommon(numberDT, "Number");
        numberDT.setType(DataType.TYPE_NUMBER);
        orderIdIC.setDataType(numberDT);

        unit.addInputControl(orderIdIC);
        unit.setAlwaysPromptControls(false);

        getUnsecureRepositoryService().saveResource(null, unit);
    }

    protected void createDateDatatype() {
        Folder folder = new FolderImpl();
        folder.setName("datatypes");
        folder.setLabel("Input data types");
        getUnsecureRepositoryService().saveFolder(null, folder);

        DataType dateDataType = new DataTypeImpl();
        setCommon(dateDataType, "date");
        dateDataType.setType(DataType.TYPE_DATE);
        dateDataType.setParentFolder(folder);
        getUnsecureRepositoryService().saveResource(null, dateDataType);
    }

    private void setCommon(Resource res, String id) {
        res.setName(id);
        res.setLabel(id + "_label");
        res.setDescription(id + " description");
    }

    private void createAllAccounts(Folder folder) {
        FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        reportRes.setFileType(FileResource.TYPE_JRXML);
        reportRes.setName("AllAccountsReport");
        reportRes.setLabel("All Accounts Jasper Report");
        reportRes.setDescription("All Accounts Jasper Report");
        reportRes.setParentFolder(folder);

        InputStream jrxml = getClass().getResourceAsStream(
                "/reports/jasper/AllAccounts.jrxml");
        reportRes.readData(jrxml);

        ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
        unit.setName("AllAccounts");
        unit.setLabel("All Accounts Report");
        unit.setDescription("All Accounts Report");
        unit.setParentFolder(folder);

        unit.setDataSourceReference("/datasources/JServerJNDIDS");
        unit.setMainReport(reportRes);

        FileResource res1 = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        res1.setFileType(FileResource.TYPE_IMAGE);
        res1.readData(getClass().getResourceAsStream("/images/jasperreports.png"));
        res1.setName("AllAccounts_Res1");
        res1.setLabel("AllAccounts_Res1");
        res1.setDescription("AllAccounts_Res1");
        unit.addResource(res1);

        FileResource res2 = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        res2.setFileType(FileResource.TYPE_IMAGE);
        res2.readData(getClass().getResourceAsStream("/images/logo.jpg"));
        res2.setName("AllAccounts_Res2");
        res2.setLabel("AllAccounts_Res2");
        res2.setDescription("AllAccounts_Res2");
        unit.addResource(res2);

        getUnsecureRepositoryService().saveResource(null, unit);
    }


    private void createAllCharts(Folder folder) 
    {
    	{
            FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
            reportRes.setFileType(FileResource.TYPE_JRXML);
            reportRes.setName("StandardChartsReport");
            reportRes.setLabel("Standard Charts Report");
            reportRes.setDescription("Standard Charts Report");
            reportRes.setParentFolder(folder);

            InputStream jrxml = getClass().getResourceAsStream(
                    "/reports/jasper/StandardChartsReport.jrxml");
            reportRes.readData(jrxml);

            ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
            unit.setName("StandardChartsReport");
            unit.setLabel("Standard Charts Report");
            unit.setDescription("Standard Charts Report");
            unit.setParentFolder(folder);

            unit.setDataSourceReference("/datasources/JServerJNDIDS");
            unit.setMainReport(reportRes);

            FileResource resBdl = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
            resBdl.setFileType(FileResource.TYPE_RESOURCE_BUNDLE);
            resBdl.readData(getClass().getResourceAsStream("/resource_bundles/standardCharts.properties"));
            setCommon(resBdl, "standardCharts.properties");
            unit.addResource(resBdl);

            FileResource resBdl_ro = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
            resBdl_ro.setFileType(FileResource.TYPE_RESOURCE_BUNDLE);
            resBdl_ro.readData(getClass().getResourceAsStream("/resource_bundles/standardCharts_ro.properties"));
            setCommon(resBdl_ro, "standardCharts_ro.properties");
            unit.addResource(resBdl_ro);
            
            getUnsecureRepositoryService().saveResource(null, unit);
    	}


    	{
            FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
            reportRes.setFileType(FileResource.TYPE_JRXML);
            reportRes.setName("StandardChartsAegeanReport");
            reportRes.setLabel("Standard Charts Aegean Report");
            reportRes.setDescription("Standard Charts Aegean Report");
            reportRes.setParentFolder(folder);

            InputStream jrxml = getClass().getResourceAsStream(
                    "/reports/jasper/StandardChartsAegeanReport.jrxml");
            reportRes.readData(jrxml);

            ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
            unit.setName("StandardChartsAegeanReport");
            unit.setLabel("Standard Charts Aegean Report");
            unit.setDescription("Standard Charts Aegean Report");
            unit.setParentFolder(folder);

            unit.setDataSourceReference("/datasources/JServerJNDIDS");
            unit.setMainReport(reportRes);

            FileResource resBdl = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
            resBdl.setFileType(FileResource.TYPE_RESOURCE_BUNDLE);
            resBdl.readData(getClass().getResourceAsStream("/resource_bundles/standardCharts.properties"));
            setCommon(resBdl, "standardCharts.properties");
            unit.addResource(resBdl);

            FileResource resBdl_ro = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
            resBdl_ro.setFileType(FileResource.TYPE_RESOURCE_BUNDLE);
            resBdl_ro.readData(getClass().getResourceAsStream("/resource_bundles/standardCharts_ro.properties"));
            setCommon(resBdl_ro, "standardCharts_ro.properties");
            unit.addResource(resBdl_ro);
            
            getUnsecureRepositoryService().saveResource(null, unit);
    	}

    	{
            FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
            reportRes.setFileType(FileResource.TYPE_JRXML);
            reportRes.setName("StandardChartsEyeCandyReport");
            reportRes.setLabel("Standard Charts Eye Candy Report");
            reportRes.setDescription("Standard Charts Eye Candy Report");
            reportRes.setParentFolder(folder);

            InputStream jrxml = getClass().getResourceAsStream(
                    "/reports/jasper/StandardChartsEyeCandyReport.jrxml");
            reportRes.readData(jrxml);

            ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
            unit.setName("StandardChartsEyeCandyReport");
            unit.setLabel("Standard Charts Eye Candy Report");
            unit.setDescription("Standard Charts Eye Candy Report");
            unit.setParentFolder(folder);

            unit.setDataSourceReference("/datasources/JServerJNDIDS");
            unit.setMainReport(reportRes);

            FileResource resBdl = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
            resBdl.setFileType(FileResource.TYPE_RESOURCE_BUNDLE);
            resBdl.readData(getClass().getResourceAsStream("/resource_bundles/standardCharts.properties"));
            setCommon(resBdl, "standardCharts.properties");
            unit.addResource(resBdl);

            FileResource resBdl_ro = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
            resBdl_ro.setFileType(FileResource.TYPE_RESOURCE_BUNDLE);
            resBdl_ro.readData(getClass().getResourceAsStream("/resource_bundles/standardCharts_ro.properties"));
            setCommon(resBdl_ro, "standardCharts_ro.properties");
            unit.addResource(resBdl_ro);
            
            getUnsecureRepositoryService().saveResource(null, unit);
    	}
    }



    private void createAllCascading(Folder folder) throws Exception
    {
    	{
            FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
            reportRes.setFileType(FileResource.TYPE_JRXML);
            reportRes.setName("Cascading_multi_select_report");
            reportRes.setLabel("Cascading multi select example report");
            reportRes.setDescription("Shows cascading input controls. Multi-select and single select queries");
            reportRes.setParentFolder(folder);

            InputStream jrxml = getClass().getResourceAsStream(
                    "/reports/jasper/CascadingMultiSelectReport.jrxml");
            reportRes.readData(jrxml);

            ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
            unit.setName("Cascading_multi_select_report");
            unit.setLabel("Cascading multi select example report");
            unit.setDescription("Example report with Cascading multi select input controls");
            unit.setParentFolder(folder);

            unit.setDataSourceReference("/datasources/JServerJNDIDS");
            unit.setMainReport(reportRes);

            // Country IC
            InputControl countryIC = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
            countryIC.setName("Country_multi_select");
            countryIC.setLabel("Country multi select");
            countryIC.setDescription("Country multi select");
            countryIC.setMandatory(true);
            countryIC.setType(InputControl.TYPE_MULTI_SELECT_QUERY);

            Query countryQ = (Query) getUnsecureRepositoryService().newResource(null, Query.class);
            countryQ.setName("country_query");
            countryQ.setLabel("Country Query");
            countryQ.setLanguage("sql");
            countryQ.setDataSourceReference("/datasources/JServerJNDIDS");
            countryQ.setSql("select distinct billing_address_country from accounts order by billing_address_country");
            countryIC.setQuery(countryQ);

            countryIC.setQueryValueColumn("billing_address_country");
            countryIC.addQueryVisibleColumn("billing_address_country");

            unit.addInputControl(countryIC);


            // State IC
            InputControl stateIC = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
            stateIC.setName("Cascading_state_multi_select");
            stateIC.setLabel("Cascading state multi select control");
            stateIC.setDescription("Cascading state multi select control");
            stateIC.setMandatory(true);
            stateIC.setType(InputControl.TYPE_MULTI_SELECT_QUERY);

            Query stateQ = (Query) getUnsecureRepositoryService().newResource(null, Query.class);
            stateQ.setName("Cascading_state_query");
            stateQ.setLabel("Cascading state query");
            stateQ.setLanguage("sql");
            stateQ.setDataSourceReference("/datasources/JServerJNDIDS");
            stateQ.setSql("select distinct billing_address_state, billing_address_country from accounts where $X{IN, billing_address_country, Country_multi_select} order by billing_address_country, billing_address_state");
            stateIC.setQuery(stateQ);

            stateIC.setQueryValueColumn("billing_address_state");
            stateIC.addQueryVisibleColumn("billing_address_country");
            stateIC.addQueryVisibleColumn("billing_address_state");

            unit.addInputControl(stateIC);

            // Name IC
            InputControl nameIC = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
            nameIC.setName("Cascading_name_single_select");
            nameIC.setLabel("Cascading name single select");
            nameIC.setDescription("Cascading name single select");
            nameIC.setMandatory(true);
            nameIC.setType(InputControl.TYPE_SINGLE_SELECT_QUERY);

            Query nameQ = (Query) getUnsecureRepositoryService().newResource(null, Query.class);
            nameQ.setName("country_state_to_name");
            nameQ.setLabel("Country State to Name");
            nameQ.setLanguage("sql");
            nameQ.setDataSourceReference("/datasources/JServerJNDIDS");
            nameQ.setSql("select name from accounts where $X{IN, billing_address_country, Country_multi_select} and $X{IN, billing_address_state, Cascading_state_multi_select} order by name");
            nameIC.setQuery(nameQ);

            nameIC.setQueryValueColumn("name");
            nameIC.addQueryVisibleColumn("name");

            unit.addInputControl(nameIC);
            unit.setAlwaysPromptControls(true);

            getUnsecureRepositoryService().saveResource(null, unit);
    	}

        {
            FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
            reportRes.setFileType(FileResource.TYPE_JRXML);
            reportRes.setName("PermissionsOfUsersWithARoleSharedByLoggedIn");
            reportRes.setLabel("Permissions Of Users with a role shared by LoggedIn");
            reportRes.setDescription("Input control controlled by user profile");
            reportRes.setParentFolder(folder);

            InputStream jrxml;
            String dbName = getJdbcProps().getProperty("test.databaseFlavor");
            if (dbName != null && (dbName.startsWith("postgre"))) {                             // using || for string concatenation
                jrxml = getClass().getResourceAsStream(
                        "/reports/jasper/PermissionsOfUsersWithARoleSharedByLoggedIn_postgres.jrxml");
            } else if (dbName != null && dbName.startsWith("db2")) {                            // using || for string concatenation and 'cast(null as varchar(1))' for null column
                jrxml = getClass().getResourceAsStream(
                        "/reports/jasper/PermissionsOfUsersWithARoleSharedByLoggedIn_db2.jrxml");
            } else if (dbName != null && dbName.startsWith("sqlserver")) {                      // using + for string concatenation
                jrxml = getClass().getResourceAsStream(
                        "/reports/jasper/PermissionsOfUsersWithARoleSharedByLoggedIn_mssql.jrxml");
            } else {
                jrxml = getClass().getResourceAsStream(                                         // using 'concat' function for string concatenation
                        "/reports/jasper/PermissionsOfUsersWithARoleSharedByLoggedIn.jrxml");
            }
            reportRes.readData(jrxml);

            ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
            unit.setName("PermissionsOfUsersWithARoleSharedByLoggedIn");
            unit.setLabel("Permissions Of Users with a role shared by LoggedIn");
            unit.setDescription("Input control controlled by user profile");
            unit.setParentFolder(folder);

            unit.setDataSourceReference("/datasources/repositoryDS");
            unit.setMainReport(reportRes);

            // RolesOfLoggedInUser IC
            InputControl rolesIC = (InputControl) getUnsecureRepositoryService().newResource(null, InputControl.class);
            rolesIC.setName("RolesOfLoggedInUser");
            rolesIC.setLabel("Roles of LoggedIn User");
            rolesIC.setDescription("Roles of LoggedIn User");
            rolesIC.setMandatory(true);
            rolesIC.setType(InputControl.TYPE_MULTI_SELECT_QUERY);

            Query rolesQ = (Query) getUnsecureRepositoryService().newResource(null, Query.class);
            rolesQ.setName("RolesOfUserQuery");
            rolesQ.setLabel("RolesOfUserQuery");
            rolesQ.setLanguage("sql");
            rolesQ.setDataSourceReference("/datasources/repositoryDS");
            rolesQ.setSql("select rolename from JIRole where $X{IN, rolename, LoggedInUserRoles}");
            rolesIC.setQuery(rolesQ);

            rolesIC.setQueryValueColumn("rolename");
            rolesIC.addQueryVisibleColumn("rolename");

            unit.addInputControl(rolesIC);
            unit.setAlwaysPromptControls(true);

            getUnsecureRepositoryService().saveResource(null, unit);
        }

    }


    private void createOFCReport(Folder folder) {
        FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        reportRes.setFileType(FileResource.TYPE_JRXML);
        reportRes.setName("OpenFlashChartsJRXML");
        reportRes.setLabel("Open Flash Charts JRXML");
        reportRes.setDescription("JRXML that contains Open Flash Chart components.\nThis report uses Open Flash Chart V2 Beta 1, (C) 2007 John Glazebrook and released under the LGPL License.\nhttp://teethgrinder.co.uk/open-flash-chart-2/");

        reportRes.readData(getClass().getResourceAsStream("/reports/jasper/OpenFlashChartsReport.jrxml"));

        ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
        unit.setName("OpenFlashChartsReport");
        unit.setLabel("Open Flash Charts Report");
        unit.setDescription("A report that displays Open Flash Charts");
        unit.setParentFolder(folder);

        unit.setDataSourceReference("/datasources/JServerJNDIDS");
        unit.setMainReport(reportRes);

        getUnsecureRepositoryService().saveResource(null, unit);
    }


    private void createCustomDSReportFileResource(Folder folder) {
        FileResource reportRes = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        reportRes.setFileType(FileResource.TYPE_JRXML);
        reportRes.setName("DataSourceReportTemplate");
        reportRes.setLabel("Report showing Custom Data Source");
        reportRes.setDescription("Report showing use of Custom Data Source via a bean");
        reportRes.setParentFolder(folder);

        InputStream jrxml = getClass().getResourceAsStream(
                "/reports/jasper/DataSourceReport.jrxml");
        reportRes.readData(jrxml);

        getUnsecureRepositoryService().saveResource(null, reportRes);
    }

    private void createCustomDSReport(Folder folder) {

        ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
        unit.setName("DataSourceReport");
        unit.setLabel("Report showing Custom Data Source");
        unit.setDescription("Report showing use of Custom Data Source via a bean");
        unit.setParentFolder(folder);

        unit.setMainReportReference("/reports/samples/DataSourceReportTemplate");
        unit.setDataSourceReference("/datasources/CustomDSFromBean");

        getUnsecureRepositoryService().saveResource(null, unit);
    }

    private void createTableModelDSReport(Folder folder) {

        ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
        unit.setName("DataSourceTableModel");
        unit.setLabel("Table Model Data Source");
        unit.setDescription("Report showing use of Custom Data Source via table model");
        unit.setParentFolder(folder);

        unit.setMainReportReference("/reports/samples/DataSourceReportTemplate");
        unit.setDataSourceReference("/datasources/CustomTableModelDS");
        unit.setMainReportReference("/reports/samples/DataSourceReportTemplate");

        getUnsecureRepositoryService().saveResource(null, unit);
    }

    private void update() {
        ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().getResource(null, "/reports/samples/AllAccounts");
        assertEquals("AllAccounts", unit.getName());
        assertEquals("/reports/samples/AllAccounts", unit.getURIString());

        unit.setLabel("Accounts Report");

        FileResource removed = unit.removeResourceLocal("AllAccounts_Res1");
        assertNotNull(removed);

        FileResource res3 = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        res3.setFileType(FileResource.TYPE_IMAGE);
        res3.readData(getClass().getResourceAsStream("/images/jasperreports.png"));
        res3.setName("AllAccounts_Res3");
        res3.setLabel("AllAccounts_Res3");
        res3.setDescription("AllAccounts_Res3");
        unit.addResource(res3);

        FileResource res4 = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        res4.setFileType(FileResource.TYPE_IMAGE);
        res4.setReferenceURI("/images/JRLogo");
        setCommon(res4, "LogoLink");
        unit.addResource(res4);

        getUnsecureRepositoryService().saveResource(null, unit);

        unit = (ReportUnit) getUnsecureRepositoryService().getResource(null, "/reports/samples/AllAccounts");
        assertTrue(unit.getLabel().startsWith("Accounts "));

        List resources = unit.getResources();
        assertNotNull(resources);
        assertEquals(3, resources.size());
    }

    private void read() {
        ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().getResource(null, "/reports/samples/AllAccounts");
        assertNotNull(unit);
        assertEquals(ReportUnit.class.getName(), unit.getResourceType());
        assertEquals("AllAccounts", unit.getName());

        ResourceReference dsRef = unit.getDataSource();
        assertNotNull(dsRef);
        assertFalse(dsRef.isLocal());
        assertEquals("/datasources/JServerJNDIDS", dsRef.getReferenceURI());

        ResourceReference mainReportRef = unit.getMainReport();
        assertNotNull(mainReportRef);
        assertTrue(mainReportRef.isLocal());
        Resource mainReport = mainReportRef.getLocalResource();
        assertTrue(mainReport instanceof FileResource);
        assertEquals("AllAccountsReport", mainReport.getName());

        List resources = unit.getResources();
        assertNotNull(resources);
        assertEquals(2, resources.size());

        FileResource img = (FileResource) getUnsecureRepositoryService().getResource(null, "/images/JRLogo");
        assertNotNull(img);
        assertEquals("JRLogo", img.getName());

        datasources();
        parentFolder();
        propertyFilter();
        disjunctionFilter();
        orFilter();
    }

    private void datasources() {
        FilterCriteria criteria = FilterCriteria.createFilter(ReportDataSource.class);
        ResourceLookup[] lookups = getUnsecureRepositoryService().findResource(null, criteria);
        assertNotNull(lookups);
        assertTrue(2 <= lookups.length);
        for (int i = 0; i < lookups.length; i++) {
            Resource res = getUnsecureRepositoryService().getResource(null, lookups[i].getURIString());
            assertTrue(res instanceof ReportDataSource);
        }
    }

    private void parentFolder() {
        FilterCriteria criteria = FilterCriteria.createFilter();
        criteria.addFilterElement(FilterCriteria.createParentFolderFilter("/datasources"));
        ResourceLookup[] folderResources = getUnsecureRepositoryService().findResource(null, criteria);
        assertNotNull(folderResources);
        assertTrue(folderResources.length > 0);
        for (int i = 0; i < folderResources.length; i++) {
            ResourceLookup lookup = folderResources[i];
            assertEquals("/datasources", lookup.getParentFolder());
            if (lookup.getName().equals("JServerJdbcDS")) {
                assertEquals(JdbcReportDataSource.class.getName(), lookup.getResourceType());
            } else if (lookup.getName().equals("JServerJNDIDS")) {
                assertEquals(JndiJdbcReportDataSource.class.getName(), lookup.getResourceType());
            }
        }
    }

    private void propertyFilter() {
        FilterCriteria criteria = FilterCriteria.createFilter(FileResource.class);
        criteria.addFilterElement(FilterCriteria.createPropertyEqualsFilter("fileType", FileResource.TYPE_IMAGE));
        ResourceLookup[] resources = getUnsecureRepositoryService().findResource(null, criteria);
        assertNotNull(resources);
        assertTrue(resources.length > 0);
        for (int i = 0; i < resources.length; i++) {
            Resource res = getUnsecureRepositoryService().getResource(null, resources[i].getURIString());
            assertTrue(res instanceof FileResource);
            FileResource fileRes = (FileResource) res;
            assertEquals(FileResource.class.getName(), fileRes.getResourceType());
            assertEquals(FileResource.TYPE_IMAGE, fileRes.getFileType());
        }
    }

    private void disjunctionFilter() {
        FilterCriteria criteria = FilterCriteria.createFilter();
        FilterElementDisjunction disjunction = criteria.addDisjunction();
        disjunction.addFilterElement(FilterCriteria.createPropertyLikeFilter("name", "%JdbcDS"));
        disjunction.addNegatedFilterElement(FilterCriteria.createParentFolderFilter("/datasources"));

        ResourceLookup[] resources = getUnsecureRepositoryService().findResource(null, criteria);
        assertNotNull(resources);
        assertTrue(resources.length > 0);
        for (int i = 0; i < resources.length; i++) {
            ResourceLookup lookup = resources[i];
            assertTrue(lookup.getName().endsWith("JdbcDS") || !lookup.getParentFolder().equals("/datasources"));
        }
    }

    private void orFilter() {
        FilterCriteria criteria = FilterCriteria.createFilter();
        FilterElementOr or = criteria.addOr();
        or.setLeftHandSide(FilterCriteria.createParentFolderFilter("/images"));
        or.setRightHandSide(FilterCriteria.createParentFolderFilter("/datasources"));

        ResourceLookup[] resources = getUnsecureRepositoryService().findResource(null, criteria);
        assertNotNull("Null resources found for or filter", resources);
        assertTrue("No resources found for or filter", resources.length > 0);
        boolean imagesFound = false;
        boolean dataSourcesFound = false;
        for (int i = 0; i < resources.length && (!imagesFound || !dataSourcesFound); i++) {
            ResourceLookup lookup = resources[i];
            if (lookup.getParentFolder().equals("/images")) {
                imagesFound = true;
            } else if (lookup.getParentFolder().equals("/datasources")) {
                dataSourcesFound = true;
            }
        }
        assertTrue("No images found for or filter", imagesFound);
        assertTrue("No data sources found for or filter", dataSourcesFound);
    }

    private void readFolders() {
        List folders = getUnsecureRepositoryService().getAllFolders(null);
        assertNotNull(folders);
        assertTrue(5 <= folders.size());

        Iterator it = folders.iterator();
        Folder folder = (Folder) it.next();
        assertEquals("/", folder.getURIString());

        Set folderURIs = new HashSet();
        while (it.hasNext()) {
            folder = (Folder) it.next();
            folderURIs.add(folder.getURIString());
        }
        assertTrue(folderURIs.contains("/datasources"));
        assertTrue(folderURIs.contains("/images"));
        assertTrue(folderURIs.contains("/reports"));
        assertTrue(folderURIs.contains("/reports/samples"));

        List subFolders = getUnsecureRepositoryService().getSubFolders(null, "/reports");
        assertNotNull(subFolders);
        assertEquals(1, subFolders.size());
        folder = (Folder) subFolders.get(0);
        assertEquals("/reports/samples", folder.getURIString());
    }

    private void list() {
        ResourceLookup[] units = getUnsecureRepositoryService().findResource(null, FilterCriteria.createFilter(ReportUnit.class));
        assertNotNull(units);
        assertTrue(units.length >= 2);
    }

    private void resources() {
        Resource[] resources = getUnsecureRepositoryService().findResource(null, null);
        assertNotNull(resources);
        assertTrue(resources.length >= 2);
    }
    
    /**
     * set these folders so that ROLE_USER can't see them but can use the resources in them for reports
     */
    private void setupExecuteOnlyPerms() {
        Role userRole = getOrCreateRole(userRoleName);
    	createObjectPermission("/datasources", userRole, JasperServerAclEntry.EXECUTE);
    	// bug 21880; we still need read access for datatypes
    	// createObjectPermission("/datatypes", userRole, JasperServerAclEntry.EXECUTE);
    	createObjectPermission("/images", userRole, JasperServerAclEntry.EXECUTE);
    	createObjectPermission("/themes", userRole, JasperServerAclEntry.EXECUTE);
    }


    private void optimisticLocking() {
        JndiJdbcReportDataSource ds1 = (JndiJdbcReportDataSource) getUnsecureRepositoryService().getResource(null, "/datasources/JServerJNDIDS");
        ds1.setLabel(ds1.getLabel() + " Updated 1");

        JndiJdbcReportDataSource ds2 = (JndiJdbcReportDataSource) getUnsecureRepositoryService().getResource(null, "/datasources/JServerJNDIDS");
        ds2.setLabel(ds1.getLabel() + " Updated 2");

        getUnsecureRepositoryService().saveResource(null, ds1);

        boolean failed = false;
        try {
            getUnsecureRepositoryService().saveResource(null, ds2);
        } catch (Exception e) {
            failed = true;
        }
        assertTrue(failed);
        
        // bug 21186: set label value back to its original value
        ds1 = (JndiJdbcReportDataSource) getUnsecureRepositoryService().getResource(null, "/datasources/JServerJNDIDS");
        ds1.setLabel("JServer JNDI Data Source");
        
        getUnsecureRepositoryService().saveResource(null, ds1);
        
        
    }


    public void testLocalResourceReplace() {
        assertNotNull("Repo not null", getUnsecureRepositoryService());

        Folder folder = new FolderImpl();
        setCommon(folder, "testLocalResourceReplace");
        folder.setParentFolder("/");
        getUnsecureRepositoryService().saveFolder(null, folder);

        ReportUnit unit = (ReportUnit) getUnsecureRepositoryService().newResource(null, ReportUnit.class);
        setCommon(unit, "unit");
        unit.setParentFolder(folder);

        FileResource rep = (FileResource) getUnsecureRepositoryService().newResource(null, FileResource.class);
        setCommon(rep, "report");
        rep.readData(getClass().getResourceAsStream("/reports/jasper/SalesByMonth.jrxml"));
        unit.setMainReport(rep);

        JdbcReportDataSource jdbcDS = (JdbcReportDataSource) getUnsecureRepositoryService().newResource(null, JdbcReportDataSource.class);
        setCommon(jdbcDS, "ds");
        jdbcDS.setConnectionUrl("jdbc:mysql://localhost:3306/jasperserver");
        jdbcDS.setDriverClass("com.mysql.jdbc.Driver");
        jdbcDS.setUsername("user");
        jdbcDS.setPassword("passwd");
        unit.setDataSource(jdbcDS);

        getUnsecureRepositoryService().saveResource(null, unit);

        Resource res = getUnsecureRepositoryService().getResource(null, "/testLocalResourceReplace/unit");
        assertNotNull(unit);
        assertTrue(res instanceof ReportUnit);
        unit = (ReportUnit) res;
        ResourceReference dsRef = unit.getDataSource();
        assertNotNull(dsRef);
        assertTrue(dsRef.isLocal());
        Resource ds = dsRef.getLocalResource();
        assertTrue(ds instanceof JdbcReportDataSource);
        assertEquals("ds", ds.getName());

        JndiJdbcReportDataSource jndiDS = (JndiJdbcReportDataSource) getUnsecureRepositoryService().newResource(null, JndiJdbcReportDataSource.class);
        setCommon(jndiDS, "ds");
        jndiDS.setJndiName("jdbc/jserver");
        unit.setDataSource(jndiDS);

        getUnsecureRepositoryService().saveResource(null, unit);

        res = getUnsecureRepositoryService().getResource(null, "/testLocalResourceReplace/unit");
        assertNotNull(unit);
        assertTrue(res instanceof ReportUnit);
        unit = (ReportUnit) res;

        dsRef = unit.getDataSource();
        assertNotNull(dsRef);
        assertTrue(dsRef.isLocal());
        Resource dsLocal = dsRef.getLocalResource();
        assertEquals("ds", dsLocal.getName());
        assertTrue(dsLocal instanceof JndiJdbcReportDataSource);
        jndiDS = (JndiJdbcReportDataSource) dsLocal;
        assertEquals("jdbc/jserver", jndiDS.getJndiName());

        getUnsecureRepositoryService().deleteFolder(null, "/testLocalResourceReplace");
    }

    public void testLoadResourcesList() {
        RepositoryService repositoryService = getRepositoryService();
        assertNotNull("Repository service should not be null", repositoryService);

        /* Basic transformer factory. It is mandatory for calling target method. */
        TransformerFactory transformerFactory = new BasicTransformerFactory();

        /* Testing target method. */
        Map<Class, Integer> resourcesCountMap = repositoryService.loadResourcesMapCount(null, "", null, null, null,
            null, transformerFactory);
        assertEquals(1, resourcesCountMap.size());
        /* TODO: there is a problem with amount of resources. Locally we have it 21, but on aphid it somehow
            retrieves 22. */        
//        assertEquals(21, resourcesCountMap.get(null).intValue());

        /* Testing target method. */
        resourcesCountMap = repositoryService.loadResourcesMapCount(null, "all", null, null, null, null,
            transformerFactory);
        assertEquals(1, resourcesCountMap.size());
        assertEquals(1, resourcesCountMap.get(null).intValue());

        /* Stub for execution context. */
        ExecutionContext executionContext = new ExecutionContextImpl();

        /* Filters. */
        List<SearchFilter> filters = new ArrayList<SearchFilter>();
        filters.add(new FolderFilter());

        /* Types are needed otherwise filter.applyRestrictions will have null type and will throw NPE. */
        List<Class> types = new ArrayList<Class>();
        types.add(ReportDataSource.class);
        types.add(ReportUnit.class);

        /* Testing target method. */
        resourcesCountMap = repositoryService.loadResourcesMapCount(executionContext, "", types, filters, null, null,
            transformerFactory);
        assertEquals(2, resourcesCountMap.size());
        assertEquals(5, resourcesCountMap.get(ReportDataSource.class).intValue());
        assertEquals(13, resourcesCountMap.get(ReportUnit.class).intValue());
    }

}
