// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed 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 com.google.enterprise.adaptor.examples;

import com.google.enterprise.adaptor.AbstractAdaptor;
import com.google.enterprise.adaptor.AdaptorContext;
import com.google.enterprise.adaptor.Config;
import com.google.enterprise.adaptor.DocIdPusher;
import com.google.enterprise.adaptor.GroupPrincipal;
import com.google.enterprise.adaptor.Principal;
import com.google.enterprise.adaptor.Request;
import com.google.enterprise.adaptor.Response;
import com.google.enterprise.adaptor.UserPrincipal;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Logger;

/** Reads memberships from CSV, forms groups, and sends to to GSA. */
public class GroupDefinitionsFromCsv extends AbstractAdaptor {
  private static final Logger log
      = Logger.getLogger(GroupDefinitionsFromCsv.class.getName());
  private static Charset encoding = Charset.forName("UTF-8");

  private File csvFile;
  private String domain;

  @Override
  public void initConfig(Config config) {
    config.addKey("csv.filename", null);
    config.addKey("csv.domain", null);
  }

  @Override
  public void init(AdaptorContext context) throws Exception {
    String fname = context.getConfig().getValue("csv.filename");
    csvFile = new File(fname);
    if (!csvFile.exists() || !csvFile.isFile()) {
      throw new IllegalStateException("cannot find file: " + fname);
    }
    domain =  context.getConfig().getValue("csv.domain");
  }
  
  @Override
  public void getDocIds(DocIdPusher pusher) throws InterruptedException {
    try {
      getDocIdsHelper(pusher);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  private void getDocIdsHelper(DocIdPusher pusher) throws InterruptedException,
      IOException {
    BufferedReader br = new BufferedReader(new FileReader(csvFile));
    String line = br.readLine();
    if (null == line) {
      throw new IllegalStateException("no content in csv file");
    }
    if (!"GROUPID,ENTITYID".equalsIgnoreCase(line)) {
      throw new IllegalStateException("invalid csv header line"); 
    }

    Map<String, List<String>> groupdefs
        = new TreeMap<String, List<String>>();
    while ((line = br.readLine()) != null) {
      String parts[] = line.split(",", -1); 
      if (2 != parts.length) {
        throw new IllegalStateException("invalid csv line: " + line);
      }
      String groupid = parts[0];
      if (!groupdefs.containsKey(groupid)) {
        groupdefs.put(groupid, new LinkedList<String>());
      }
      if (!"".equals(parts[1])) {
        String entity = parts[1];
        groupdefs.get(groupid).add(entity);
      }
    }

    boolean caseSensitive = true;
    pusher.pushGroupDefinitions(convert(groupdefs), caseSensitive);
  }

  private String makeName(String id) {
    return "" + id + "@" + domain;
  }

  private Map<GroupPrincipal, List<Principal>> convert(
      Map<String, List<String>> src) {
    Map<GroupPrincipal, List<Principal>> dest
        = new TreeMap<GroupPrincipal, List<Principal>>();
    for (Map.Entry<String, List<String>> e : src.entrySet()) {
      int nentities = e.getValue().size();
      List<Principal> entities = new ArrayList<Principal>(nentities);
      for (int i = 0; i < nentities; i++) {
        String id = e.getValue().get(i);
        String name = makeName(id);
        boolean entityIsGroup = src.containsKey(id);
        if (entityIsGroup) {
          entities.add(new GroupPrincipal(name));
        } else {
          entities.add(new UserPrincipal(name));
        }
      }
      dest.put(new GroupPrincipal(makeName(e.getKey())), entities);
    }
    return dest;
  }

  @Override
  public void getDocContent(Request req, Response res) throws IOException {
    res.respondNotFound();
  }
 
  public static void main(String args[]) {
    AbstractAdaptor.main(new GroupDefinitionsFromCsv(), args);
  }
}

@@ -2309,208 +2309,8 @@
 her)
- throws InterruptedException %7B%0A    try %7B%0A      getDocIdsHelper(pusher);%0A    %7D catch (IOException e) %7B%0A      throw new RuntimeException(e);%0A    %7D%0A  %7D%0A%0A  private void getDocIdsHelper(DocIdPusher pusher)
  thr

Simplify exception handling in Group CSV example