com.diversityarrays.dal.db.kddart.KddartDalDatabase.java Source code

Java tutorial

Introduction

Here is the source code for com.diversityarrays.dal.db.kddart.KddartDalDatabase.java

Source

/*
 * dalserver-interop library - implementation of DAL server for interoperability
 * Copyright (C) 2015  Diversity Arrays Technology
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.diversityarrays.dal.db.kddart;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections15.Closure;

import com.diversityarrays.dal.db.AbstractDalDatabase;
import com.diversityarrays.dal.db.AuthenticationException;
import com.diversityarrays.dal.db.DalDatabaseUtil;
import com.diversityarrays.dal.db.DalDbException;
import com.diversityarrays.dal.db.DalResponseBuilder;
import com.diversityarrays.dal.db.DbDataLoader;
import com.diversityarrays.dal.db.SystemGroupInfo;
import com.diversityarrays.dal.db.UserInfo;
import com.diversityarrays.dal.entity.DalEntity;
import com.diversityarrays.dal.entity.Genotype;
import com.diversityarrays.dal.entity.Genus;
import com.diversityarrays.dal.ops.AbstractDalOperation;
import com.diversityarrays.dal.ops.DalOperation;
import com.diversityarrays.dal.server.DalSession;
import com.diversityarrays.dalclient.DALClient;
import com.diversityarrays.dalclient.DalException;
import com.diversityarrays.dalclient.DalResponse;
import com.diversityarrays.dalclient.DalResponseException;
import com.diversityarrays.dalclient.DalResponseFormatException;
import com.diversityarrays.dalclient.DalResponseRecord;
import com.diversityarrays.dalclient.DalResponseRecordVisitor;
import com.diversityarrays.dalclient.DefaultDALClient;
import com.diversityarrays.dalclient.ResponseType;
import com.diversityarrays.dalclient.SessionExpiryOption;

import fi.iki.elonen.NanoHTTPD.Method;

public class KddartDalDatabase extends AbstractDalDatabase {

    private static final String DATABASE_VERSION = "0.1";

    private static final boolean USE_JSON = Boolean.parseBoolean(KddartDalDatabase.class.getName() + ".USE_JSON");

    public static final String PARAM_USERNAME = "Username";
    public static final String PARAM_PASSWORD = "Password";

    private Map<String, Class<? extends DalEntity>> entityClassByName = new HashMap<String, Class<? extends DalEntity>>();
    private List<DalOperation> operations;

    private final String dalUrl;

    private Map<String, DALClient> clientBySessionId = new HashMap<String, DALClient>();

    private final String dalUsername;

    private final String dalPassword;

    private boolean autoSwitchGroupOnLogin;

    public KddartDalDatabase(Closure<String> progress, boolean test, URI uri, String username, String password,
            Boolean autoSwitchGroup) throws DalDbException {
        super("KDDart-DAL@" + uri.toString());

        this.dalUrl = uri.toString();
        this.dalUsername = username;
        this.dalPassword = password;
        this.autoSwitchGroupOnLogin = autoSwitchGroup == null ? false : autoSwitchGroup.booleanValue();

        entityClassByName.put("genus", Genus.class);
        entityClassByName.put("genotype", Genotype.class);

        if (test) {
            DALClient client = new DefaultDALClient(dalUrl);
            try {
                progress.execute("Attempting login to " + dalUrl);
                client.login(username, password);
            } catch (DalException e) {
                throw new DalDbException(e);
            } catch (IOException e) {
                throw new DalDbException(e);
            } finally {
                client.logout();
            }
        }
    }

    @Override
    public String getDatabaseVersion(DalSession session) throws DalDbException {
        DALClient client = session == null ? null : clientBySessionId.get(session.sessionId);
        if (client == null) {
            return DATABASE_VERSION;
        } else {
            try {
                DalResponse response = client.performQuery(DalOperation.GET_VERSION);
                return response.getRecordFieldValue(DALClient.TAG_INFO, DALClient.ATTR_VERSION);
            } catch (DalResponseException e) {
                throw new DalDbException(e);
            } catch (IOException e) {
                throw new DalDbException(e);
            }
        }

    }

    @Override
    public List<DalOperation> getOperations() {
        /*
        <Operation REST="get/genus/_id" />
        <Operation REST="list/genus" />
            
        <Operation REST="genus/_genusid/list/genotype" />
        <Operation REST="genus/_genusid/list/genotype/_nperpage/page/_num" />
            
        <Operation REST="get/genotype/_id" />
        <Operation REST="list/genotype/_nperpage/page/_num" />
            
        <Operation REST="export/genotype" />
            
        <Operation REST="genotype/_genoid/list/alias" />
        <Operation REST="genotype/_genoid/list/ancestor" />
        <Operation REST="genotype/_genoid/list/descendant" />
        <Operation REST="genotype/_genoid/list/specimen" />
        <Operation REST="genotype/_genoid/list/specimen/_nperpage/page/_num" />
        <Operation REST="genotype/_genoid/remove/trait/_traitid" />
        <Operation REST="genotype/_id/list/trait" />
            
        list/group
            
         */

        if (operations == null) {
            synchronized (this) {
                if (operations == null) {
                    List<DalOperation> tmp = new ArrayList<DalOperation>();

                    tmp.add(new ForwardingDalOperation("genus", "get/genus/_id"));
                    tmp.add(new ForwardingDalOperation("genus", "list/genus"));

                    tmp.add(new ForwardingDalOperation("genotype", "get/genotype/_id"));
                    tmp.add(new ForwardingDalOperation("genotype", "list/genotype/_nperpage/page/_num"));

                    tmp.add(new ForwardingDalOperation("genotypealias", "get/genotypealias/_id"));
                    tmp.add(new ForwardingDalOperation("genotypealias", "list/genotypealias/_nperpage/page/_num"));
                    tmp.add(new ForwardingDalOperation("genotypealias", "genotype/_genoid/list/alias"));

                    //               tmp.add(new ListGroupVariantDalOperation(DalOperation.LIST_GROUP));
                    //               tmp.add(new ListGroupVariantDalOperation(DalOperation.LIST_ALL_GROUP));

                    operations = tmp;
                }
            }
        }
        return operations;
    }

    @Override
    public Collection<String> getEntityNames() {
        return Collections.unmodifiableCollection(entityClassByName.keySet());
    }

    @Override
    public SystemGroupInfo getSystemGroupInfo(DalSession session) throws DalDbException {
        DALClient client = clientBySessionId.get(session.sessionId);
        if (client == null) {
            throw new AuthenticationException("Not logged in");
        }

        return new SystemGroupInfoImpl(client.getGroupId(), client.getGroupName(), client.isInAdminGroup());
    }

    @Override
    public void performListAllGroup(DalSession session, DalResponseBuilder builder, String[] returnSql)
            throws DalDbException {
        DALClient client = clientBySessionId.get(session.sessionId);
        if (client == null) {
            throw new AuthenticationException("Not logged in");
        }

        try {
            DalResponse response = client.performQuery(DalOperation.LIST_ALL_GROUP);
            feedResponseToResponseBuilder(response, builder);
        } catch (DalResponseException e) {
            throw new DalDbException(e);
        } catch (IOException e) {
            throw new DalDbException(e);
        }
    }

    @Override
    public void performListGroup(DalSession session, DalResponseBuilder builder, String[] returnSql)
            throws DalDbException {
        DALClient client = clientBySessionId.get(session.sessionId);
        if (client == null) {
            throw new AuthenticationException("Not logged in");
        }

        try {
            DalResponse response = client.performQuery(DalOperation.LIST_GROUP);
            feedResponseToResponseBuilder(response, builder);
        } catch (DalResponseException e) {
            throw new DalDbException(e);
        } catch (IOException e) {
            throw new DalDbException(e);
        }
    }

    @Override
    public void performListField(DalSession session, String tableName, DalResponseBuilder responseBuilder)
            throws DalDbException {

        DALClient client = clientBySessionId.get(session.sessionId);
        if (client == null) {
            throw new AuthenticationException("Not logged in");
        }

        try {
            DalResponse response = client.performQuery(tableName + DalOperation.LIST_FIELD_TAIL);
            feedResponseToResponseBuilder(response, responseBuilder);
        } catch (DalResponseException e) {
            throw new DalDbException(e);
        } catch (IOException e) {
            throw new DalDbException(e);
        }
    }

    /**
     * 
     * @return
     */
    public boolean isAutoSwitchGroupOnLogin() {
        return autoSwitchGroupOnLogin;
    }

    /**
     * Provided to assist in testing
     * @param autoSwitchGroupOnLogin
     */
    public void setAutoSwitchGroupOnLogin(boolean b) {
        this.autoSwitchGroupOnLogin = b;
    }

    @Override
    public UserInfo doLogin(String newSessionId, String userName, SessionExpiryOption seo,
            Map<String, String> parms) throws AuthenticationException {

        String errmsg = DalDatabaseUtil.getUsernamePasswordErrorMessage(userName, dalPassword, parms);
        if (errmsg != null) {
            throw new AuthenticationException(errmsg + " (0)");
        }

        try {
            DALClient client = new DefaultDALClient(dalUrl);
            if (USE_JSON) {
                client.setResponseType(ResponseType.JSON);
            }
            client.setSessionExpiryOption(seo);
            client.setAutoSwitchGroupOnLogin(autoSwitchGroupOnLogin);
            client.login(dalUsername, dalPassword);
            clientBySessionId.put(newSessionId, client);
            return new UserInfoImpl(userName, client.getUserId());
        } catch (DalException e) {
            throw new AuthenticationException(e);
        } catch (IOException e) {
            throw new AuthenticationException(e);
        }
    }

    @Override
    public void doLogout(DalSession session) {
        DALClient client = clientBySessionId.remove(session.sessionId);
        if (client != null) {
            client.logout();
        }
    }

    @Override
    public boolean isInitialiseRequired() {
        return false;
    }

    @Override
    public void initialise(Closure<String> progress) throws DalDbException {
        throw new UnsupportedOperationException();
    }

    @Override
    public String getDatabasePath() {
        return dalUrl;
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            shutdown();
        } finally {
            super.finalize();
        }
    }

    @Override
    public void shutdown() throws DalDbException {
        Collection<DALClient> clients = clientBySessionId.values();
        clientBySessionId.clear();
        for (DALClient client : clients) {
            client.logout();
        }
    }

    @Override
    public Class<? extends DalEntity> getEntityClass(String tname) {
        Class<? extends DalEntity> result = null;
        for (String name : entityClassByName.keySet()) {
            if (name.equalsIgnoreCase(tname)) {
                result = entityClassByName.get(name);
                break;
            }
        }
        return result;
    }

    @Override
    public DbDataLoader getDbDataLoader() throws DalDbException {
        throw new DalDbException("Not yet implemented");
        // TODO implement KddartDalDatabase.getDbDataLoader()
    }

    protected void feedResponseToResponseBuilder(DalResponse response, final DalResponseBuilder responseBuilder)
            throws DalResponseFormatException, DalResponseException {
        final Set<String> tags = new LinkedHashSet<String>();
        DalResponseRecordVisitor tagCollector = new DalResponseRecordVisitor() {
            @Override
            public boolean visitResponseRecord(String tag, DalResponseRecord rr) {
                tags.add(tag);
                return true;
            }
        };
        response.visitResults(tagCollector);
        for (String tag : tags) {
            responseBuilder.addResponseMeta(tag);
        }

        /*
         * The Pagination record isn't usually included in the visited tags because it isn't
         * included in the RecordMeta list of tags. So we need to find it and process it manually
         */
        DalResponseRecord paginationRecord = response.getFirstRecord(DALClient.TAG_PAGINATION);
        if (paginationRecord != null && !paginationRecord.rowdata.isEmpty()) {
            copyResponseRecord(responseBuilder, DALClient.TAG_PAGINATION, paginationRecord);
        }

        DalResponseRecordVisitor visitor = new DalResponseRecordVisitor() {
            @Override
            public boolean visitResponseRecord(String tag, DalResponseRecord rr) {
                copyResponseRecord(responseBuilder, tag, rr);
                return true;
            }
        };
        response.visitResults(visitor, tags);
    }

    private void copyResponseRecord(final DalResponseBuilder responseBuilder, String tag, DalResponseRecord rr) {
        responseBuilder.startTag(tag);
        for (String k : rr.rowdata.keySet()) {
            responseBuilder.attribute(k, rr.rowdata.get(k));
        }
        responseBuilder.endTag();
    }

    //   class ListGroupVariantDalOperation extends AbstractDalOperation<KddartDalDatabase> {
    //
    //      public ListGroupVariantDalOperation(String template) {
    //         super(KddartDalDatabase.this, "group", template);
    //      }
    //
    //      @Override
    //      public void execute(String userId, 
    //            DalResponseBuilder responseBuilder, 
    //            Method method,
    //            String dalcmd,
    //            List<String> dalOpParameters,
    //            Map<String, String> methodParms,
    //            Map<String,String> filePathByName)
    //      throws DalDbException 
    //      {
    //         if (DalOperation.LIST_ALL_GROUP.equals(getCommandTemplate())) {
    //            performListGroup(null, responseBuilder, null);
    //         }
    //         else {
    //            performListGroup(userId, responseBuilder, null);
    //         }
    //      }
    //   }

    class ForwardingDalOperation extends AbstractDalOperation<KddartDalDatabase> {

        public ForwardingDalOperation(String entityName, String template) {
            super(KddartDalDatabase.this, entityName, template);
        }

        @Override
        public void execute(DalSession session, final DalResponseBuilder responseBuilder, Method method,
                String dalcmd, List<String> dalOpParameters, Map<String, String> methodParms,
                Map<String, String> filePathByName) throws DalDbException {

            DALClient client = clientBySessionId.get(session.sessionId);

            if (client == null) {
                throw new AuthenticationException("Not logged in");
            }

            if (Method.GET == method) {
                try {
                    DalResponse response = client.performQuery(dalcmd);

                    feedResponseToResponseBuilder(response, responseBuilder);

                } catch (DalResponseException e) {
                    throw new DalDbException(e);
                } catch (IOException e) {
                    throw new DalDbException(e);
                }
            } else if (Method.POST == method) {
                throw new DalDbException("Not Yet Implemented: " + method.name() + " for " + dalcmd);
            } else {
                throw new DalDbException("Unsupported request method: " + method.name());
            }
        }

    }

}