/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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.apache.shindig.social;

import org.apache.shindig.common.servlet.GuiceServletContextListener;
import org.apache.shindig.social.abdera.json.JSONWriter;

import com.google.inject.Injector;
import org.apache.abdera.protocol.server.Provider;
import org.apache.abdera.protocol.server.servlet.AbderaServlet;
import org.apache.abdera.util.AbderaConfiguration;
import org.apache.abdera.util.Configuration;
import org.apache.abdera.writer.NamedWriter;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.logging.Logger;

/**
 * Superclass for all servlets related to processing of REST api.
 * The reason for its existence is to init Guice Injection.
 * Since this has AbderaServlet to extend Abdera Servlet,
 * it cannot extend InjectedServlet like GadgetDataServlet does.
 *
 * Injection is also a little different because of Abdera is in the middle.
 * instead of injecting (this) as the GadgetServlet does,
 * here the Provider is injected.
 */
public class RestServerServlet extends AbderaServlet {
  private static Logger logger =
      Logger.getLogger(RestServerServlet.class.getName());

  @Override public void init() {
    // Abdera provider stuff
    manager = createServiceManager();
    provider = createProvider();
  }

  @Override
  protected Provider createProvider() {
    Provider provider = manager.newProvider(getProperties(getServletConfig()));
    try {
      initGuice(getServletConfig(), provider);
    } catch (ServletException e) {
      logger.severe(e.getMessage());
      e.printStackTrace();
      return null;
    }
    
    // init Writers
    // setup my NamedWriter for "json"
    // TODO why not inject here. because I am not ready to change code
    // copied from abdera yet. but go to do it..everything gets guiced.
    JSONWriter jsonWriter = new JSONWriter();
    Configuration config = getAbdera().getConfiguration();
    if (config instanceof AbderaConfiguration) {
      ((AbderaConfiguration)config).addNamedWriter(jsonWriter);
    } else {
      logger.severe("Invalid Abdera configuration");
      return null;
    }
    
    // print all the writers available
    Map<String, NamedWriter> writersMap = 
        ((AbderaConfiguration)config).getNamedWriters();
    for (NamedWriter writer : writersMap.values()) {
      StringBuilder sbuf = new StringBuilder();
      for (String s : writer.getOutputFormats()) {
        sbuf.append(s + ", ");
      }
      logger.fine("NamedWriter: " + writer.getClass().getName() +
          " is for writing '" + writer.getName() + "'" +
          ". Handles the following formats: " + sbuf.toString());
      
    }
    return provider;
  }

  protected void initGuice(ServletConfig config, Provider provider)
      throws ServletException {
    ServletContext context = config.getServletContext();
    Injector injector = (Injector)
        context.getAttribute(GuiceServletContextListener.INJECTOR_ATTRIBUTE);
    if (injector == null) {
      throw new UnavailableException(
          "Guice Injector not found! Make sure you registered " +
          GuiceServletContextListener.class.getName() + " as a listener");
    }
    injector.injectMembers(provider);
    // all providers should implement initialize() so injection could happen
    try {
      Method m = provider.getClass().getMethod("initialize", new Class<?>[0]);
      m.invoke(provider, new Object[0]);
    } catch (IllegalArgumentException e) {
        logger.severe(e.getMessage());
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        logger.severe(e.getMessage());
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        logger.severe(e.getMessage());
        e.printStackTrace();
    } catch (SecurityException e) {
      logger.severe(e.getMessage());
      e.printStackTrace();
    } catch (NoSuchMethodException e) {
      logger.severe(e.getMessage());
      e.printStackTrace();
    }
  }
}

@@ -1119,104 +1119,8 @@
 et;%0A
-import org.apache.abdera.util.AbderaConfiguration;%0Aimport org.apache.abdera.util.Configuration;%0A
 impo
@@ -2499,29 +2499,8 @@
   //
- init Writers%0A    // 
 setu
@@ -2535,455 +2535,72 @@
     
-// TODO why not inject here. because I am not ready to change code%0A    // copied from abdera yet. but go to do it..everything gets guiced.%0A    JSONWriter jsonWriter = new JSONWriter();%0A    Configuration config = getAbdera().getConfiguration();%0A    if (config instanceof AbderaConfiguration) %7B%0A      ((AbderaConfiguration)config).addNamedWriter(jsonWriter);%0A    %7D else %7B%0A      logger.severe(%22Invalid Abdera configuration%22);%0A      return null;%0A    %7D
+getAbdera().getConfiguration().addNamedWriter(new JSONWriter());
 %0A   
@@ -2695,16 +2695,23 @@
     
-((
+get
 Abdera
+().get
 Conf
@@ -2723,15 +2723,9 @@
 tion
-)config
+(
 ).ge
@@ -3051,24 +3051,24 @@
 e() + %22'%22 +%0A
+
           %22.
@@ -3125,15 +3125,8 @@
 ));%0A
-      %0A
     

Patch from Vasu Nori to simplify our abdera setup