Package org.wso2.carbon.dataservices.core.description.config

Source Code of org.wso2.carbon.dataservices.core.description.config.GSpreadConfig

/*
*  Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you under the Apache License,
*  Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing,
*  software distributed under the License is distributed on an
*  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
*  KIND, either express or implied.  See the License for the
*  specific language governing permissions and limitations
*  under the License.
*
*/
package org.wso2.carbon.dataservices.core.description.config;

import java.net.URL;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.dataservices.common.DBConstants;
import org.wso2.carbon.dataservices.common.DBConstants.DataSourceTypes;
import org.wso2.carbon.dataservices.common.DBConstants.GSpread;
import org.wso2.carbon.dataservices.common.DBConstants.GSpreadVisibility;
import org.wso2.carbon.dataservices.core.DBUtils;
import org.wso2.carbon.dataservices.core.DataServiceFault;
import org.wso2.carbon.dataservices.core.engine.DataService;
import org.wso2.carbon.dataservices.core.internal.DataServicesDSComponent;
import org.wso2.carbon.dataservices.core.listeners.RegistryServiceListener;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.service.RegistryService;

import com.google.gdata.client.GoogleAuthTokenFactory.UserToken;
import com.google.gdata.client.spreadsheet.SpreadsheetService;
import com.google.gdata.data.IFeed;

/**
* This class represents a Google Spreadsheet based data source configuration.
*/
public class GSpreadConfig extends Config implements RegistryServiceListener {

  private static final Log log = LogFactory.getLog(GSpreadConfig.class);
 
  public static final String BASE_WORKSHEET_URL = "http://spreadsheets.google.com/feeds/worksheets/";
 
  public static final String BASE_REGISTRY_AUTH_TOKEN_PATH = "/repository/components/org.wso2.carbon.dataservices.core/services/";
 
  private String username;
 
  private String password;
 
  private String visibility;
 
  private String key;
 
  private SpreadsheetService service;
   
  public GSpreadConfig(DataService dataService, String configId, Map<String,
      String> properties) throws DataServiceFault {
    super(dataService, configId, DataSourceTypes.GDATA_SPREADSHEET, properties);
   
    this.username = this.getProperty(DBConstants.GSpread.USERNAME);
    this.password = DBUtils.resolvePasswordValue(this.getDataService(), this.getProperty(DBConstants.GSpread.PASSWORD));
    this.visibility = this.getProperty(DBConstants.GSpread.VISIBILITY);
    this.key = extractKey(this.getProperty(GSpread.DATASOURCE));   
    if (!dataService.isServiceInactive()) {
        this.service = new SpreadsheetService(this.getDataService().getName() +
            ":" + this.getConfigId());
    }
    /* register registry service listener */
    DataServicesDSComponent.registerRegistryServiceListener(this);
  }
 
  private void initRegistryService(RegistryService registryService) {
      if (this.requiresAuth()) {
        try {
            this.authenticate(false,
                registryService.getConfigSystemRegistry(DBUtils.getCurrentTenantId()));
        } catch (Exception e) {
        log.error("Error in GData Spreadhsheet Authentication", e);
      }
      }
  }
 
  public static String extractKey(String documentURL) throws DataServiceFault {
    int i1 = documentURL.lastIndexOf("key=");
    if (documentURL.length() < (i1 + 5)) {
      throw new DataServiceFault("Invalid documentURL: " + documentURL);
    }
    int i2 = documentURL.indexOf("&", i1);
    if (i2 < 0) {
      return documentURL.substring(i1 + 4);
    } else {
      return documentURL.substring(i1 + 4, i2);
    }
  }
 
  public String generateWorksheetFeedURL() {
    return GSpreadConfig.BASE_WORKSHEET_URL + key + "/" +
        this.getVisibility() + "/basic";
  }

  public String getKey() {
    return key;
  }

  public String getPassword() {
    return password;
  }

  private SpreadsheetService getService() {
    return service;
  }

  public String getUsername() {
    return username;
  }

  public String getVisibility() {
    return visibility;
  }
 
  private String generateAuthTokenResourcePath() {
    StringBuilder userKey = new StringBuilder();
    /* append the username value 3 times because,
     * later when we do base64 encoding, we have to be sure,
     * it doesn't have "=" characters by making the source data
     * a multiple of 3, thus not to have any padding data.
     */
    String userName = this.getUsername();
    userKey.append(userName);
    userKey.append(userName);
    userKey.append(userName);
    String resPath = "/repository/components/org.wso2.carbon.dataservices.core/services/"
      + this.getDataService().getName()
      + "/configs/"
      + this.getConfigId() + "/user_auth_token/users/"
      + DBUtils.encodeBase64(userKey.toString());
    return resPath;
  }
 
  /**
   * Returns the resource associated with the current gspread config user authentication token.
   * the resource path is :-
   * "/repository/components/org.wso2.carbon.dataservices.core/services/[service_id]/configs/[config_id]/user_auth_token"
   */
  private Resource getAuthTokenResource(Registry registry) throws Exception {
    if (registry == null) {
      return null;
    }
    String resPath = this.generateAuthTokenResourcePath();
    if (!registry.resourceExists(resPath)) {
      return null;
    }
    return registry.get(resPath);
  }
 
  private String getLocalUserAuthToken(Registry registry) throws Exception {
    Resource authTokenRes = this.getAuthTokenResource(registry);
    if (authTokenRes != null) {
      Object content = authTokenRes.getContent();
      if (content != null) {
        return new String((byte[]) content, DBConstants.DEFAULT_CHAR_SET_TYPE);
      }
    }
    return null;
  }
 
  private void setLocalUserAuthToken(String userToken, Registry registry) throws Exception {
    registry.beginTransaction();
    Resource res = registry.newResource();
    res.setContent(userToken.getBytes(DBConstants.DEFAULT_CHAR_SET_TYPE));
    registry.put(this.generateAuthTokenResourcePath(), res);
    registry.commitTransaction();
  }
 
  public <F extends IFeed> F getFeed(URL feedUrl, Class<F> feedClass) throws Exception {
    try {
        return this.getService().getFeed(feedUrl, feedClass);
    } catch (Exception e) {
      /* authenticate again in case the user authentication token has expired */
      if (this.requiresAuth()) {
        Registry registry = null;
        if (DataServicesDSComponent.getRegistryService() == null) {
          log.warn("GSpreadConfig.getFeed(): Registry service is not available, authentication keys wont be saved");
        } else {
          registry = DataServicesDSComponent.getRegistryService()
              .getConfigSystemRegistry(DBUtils.getCurrentTenantId());
        }
          this.authenticate(true, registry);
          return this.getService().getFeed(feedUrl, feedClass);
      } else {
        throw e;
      }
    }
  }
 
  private boolean requiresAuth() {
    return (this.getVisibility() != null &&
        this.getVisibility().equals(GSpreadVisibility.PRIVATE));
  }
 
  private String getNewUserAuthToken() throws Exception {
    this.getService().setUserCredentials(this.getUsername(), this.getPassword());
    return ((UserToken) this.getService().getAuthTokenFactory().getAuthToken()).getValue();
  }
 
  private void authenticate(boolean refreshToken, Registry registry) throws Exception {
    String userToken;
    if (refreshToken || (registry == null)
        || (userToken = this.getLocalUserAuthToken(registry)) == null) {
      userToken = this.getNewUserAuthToken();
      if (registry != null) {
          this.setLocalUserAuthToken(userToken, registry);
      }
    }
    this.getService().setUserToken(userToken);
  }
 
  @Override
  public boolean isActive() {
    return this.getService() != null;
  }

  public void setRegistryService(RegistryService registryService) {
    this.initRegistryService(registryService);
  }
 
  public void close() {
    /* nothing to close */
  }

  @Override
  public int getTenantId() {
    return this.getDataService().getTenantId();
  }

}
TOP

Related Classes of org.wso2.carbon.dataservices.core.description.config.GSpreadConfig

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.