// ---------------------------------------------------------------------------
// This file has been generated partially by the Web Dynpro Code Generator.
// MODIFY CODE ONLY IN SECTIONS ENCLOSED BY @@begin AND @@end.
// ALL OTHER CHANGES WILL BE LOST IF THE FILE IS REGENERATED.
// ---------------------------------------------------------------------------
package uwl.rss.subscriptions.ui;

// 
// IMPORTANT NOTE: 
// _ALL_ IMPORT STATEMENTS MUST BE PLACED IN THE FOLLOWING SECTION ENCLOSED
// BY @@begin imports AND @@end. FURTHERMORE, THIS SECTION MUST ALWAYS CONTAIN
// AT LEAST ONE IMPORT STATEMENT (E.G. THAT FOR IPrivateRssSubscriptionsView).
// OTHERWISE, USING THE ECLIPSE FUNCTION "Organize Imports" FOLLOWED BY
// A WEB DYNPRO CODE GENERATION (E.G. PROJECT BUILD) WILL RESULT IN THE LOSS
// OF IMPORT STATEMENTS.
//
//@@begin imports
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

import com.sap.netweaver.bc.uwl.IUWLService;
import com.sap.netweaver.bc.uwl.connect.IProviderConnector;
import com.sap.tc.logging.Category;
import com.sap.tc.logging.Severity;
import com.sap.tc.webdynpro.services.sal.um.api.IWDClientUser;
import com.sap.tc.webdynpro.services.sal.um.api.WDClientUser;
import com.sapportals.portal.prt.runtime.PortalRuntime;

import uwl.rss.portal.IRssRegistrationService;
import uwl.rss.provider.RssItemProvider;
import uwl.rss.subscriptions.ui.wdp.IPrivateRssSubscriptionsView;
//@@end

//@@begin documentation
//@@end

public class RssSubscriptionsView
{
  /**
   * Logging location.
   */
  private static final com.sap.tc.logging.Location logger = 
    com.sap.tc.logging.Location.getLocation(RssSubscriptionsView.class);

  static 
  {
    //@@begin id
    String id = "$Id$";
    //@@end
    com.sap.tc.logging.Location.getLocation("ID.com.sap.tc.webdynpro").infoT(id);
  }

  /**
   * Private access to the generated Web Dynpro counterpart 
   * for this controller class.  </p>
   *
   * Use <code>wdThis</code> to gain typed access to the context,
   * to trigger navigation via outbound plugs, to get and enable/disable
   * actions, fire declared events, and access used controllers and/or 
   * component usages.
   *
   * @see uwl.rss.subscriptions.ui.wdp.IPrivateRssSubscriptionsView for more details
   */
  private final IPrivateRssSubscriptionsView wdThis;

  /**
   * Root node of this controller's context. </p>
   *
   * Provides typed access not only to the elements of the root node 
   * but also to all nodes in the context (methods node<i>XYZ</i>()) 
   * and their currently selected element (methods current<i>XYZ</i>Element()). 
   * It also facilitates the creation of new elements for all nodes 
   * (methods create<i>XYZ</i>Element()). </p>
   *
   * @see uwl.rss.subscriptions.ui.wdp.IPrivateRssSubscriptionsView.IContextNode for more details.
   */
  private final IPrivateRssSubscriptionsView.IContextNode wdContext;

  /**
   * A shortcut for <code>wdThis.wdGetAPI()</code>. </p>
   * 
   * Represents the generic API of the generic Web Dynpro counterpart 
   * for this controller. </p>
   */
  private final com.sap.tc.webdynpro.progmodel.api.IWDViewController wdControllerAPI;
  
  /**
   * A shortcut for <code>wdThis.wdGetAPI().getComponent()</code>. </p>
   * 
   * Represents the generic API of the Web Dynpro component this controller 
   * belongs to. Can be used to access the message manager, the window manager,
   * to add/remove event handlers and so on. </p>
   */
  private final com.sap.tc.webdynpro.progmodel.api.IWDComponent wdComponentAPI;
  
  public RssSubscriptionsView(IPrivateRssSubscriptionsView wdThis)
  {
    this.wdThis = wdThis;
    this.wdContext = wdThis.wdGetContext();
    this.wdControllerAPI = wdThis.wdGetAPI();
    this.wdComponentAPI = wdThis.wdGetAPI().getComponent();
  }

  //@@begin javadoc:wdDoInit()
  /** Hook method called to initialize controller. */
  //@@end
  public void wdDoInit()
  {
    //@@begin wdDoInit()
	try {
		setPathToXmlStore();
		
		IPrivateRssSubscriptionsView.ISubscriptionsElement firstSubscription =  wdContext.createSubscriptionsElement();
		firstSubscription.setUrl("New Feed URL");
		firstSubscription.setTitle("Feed Title");
		wdContext.nodeSubscriptions().addElement(firstSubscription);

		List feeds = getUsersFeeds();
		if(feeds != null) {
			Iterator feedIt = feeds.iterator();
			while (feedIt.hasNext()) {
				Element feed = (Element) feedIt.next();
				String rssFeedurl = feed.getAttributeValue("url");
				String rssFeedTitle = feed.getAttributeValue("title");
				String strDisabled = feed.getAttributeValue("disabled");
				IPrivateRssSubscriptionsView.ISubscriptionsElement subscription =  wdContext.createSubscriptionsElement();
				subscription.setUrl(rssFeedurl);
				subscription.setTitle(rssFeedTitle);
				subscription.setDisabled(Boolean.valueOf(strDisabled).booleanValue());
				
				//test the Url and indicate status accordingly to the user.
				if(testUrl(rssFeedurl)) subscription.setStatusImage("s_s_ledg.gif");
				else subscription.setStatusImage("s_s_ledr.gif");
				 
				wdContext.nodeSubscriptions().addElement(subscription);
			}
		}				
	}
	catch(Exception e) {
		Category.APPLICATIONS.logThrowable(Severity.FATAL,
											logger,
											(Object)"wdInit()",
											new Object[]{this},
											"Error in Initialization",
											e);
	}
    //@@end
  }

  //@@begin javadoc:wdDoExit()
  /** Hook method called to clean up controller. */
  //@@end
  public void wdDoExit()
  {
    //@@begin wdDoExit()
    //@@end
  }

  //@@begin javadoc:wdDoModifyView
  /**
   * Hook method called to modify a view just before rendering.
   * This method conceptually belongs to the view itself, not to the
   * controller (cf. MVC pattern).
   * It is made static to discourage a way of programming that
   * routinely stores references to UI elements in instance fields
   * for access by the view controller's event handlers, and so on.
   * The Web Dynpro programming model recommends that UI elements can
   * only be accessed by code executed within the call to this hook method.
   *
   * @param wdThis Generated private interface of the view's controller, as
   *        provided by Web Dynpro. Provides access to the view controller's
   *        outgoing controller usages, etc.
   * @param wdContext Generated interface of the view's context, as provided
   *        by Web Dynpro. Provides access to the view's data.
   * @param view The view's generic API, as provided by Web Dynpro.
   *        Provides access to UI elements.
   * @param firstTime Indicates whether the hook is called for the first time
   *        during the lifetime of the view.
   */
  //@@end
  public static void wdDoModifyView(IPrivateRssSubscriptionsView wdThis, IPrivateRssSubscriptionsView.IContextNode wdContext, com.sap.tc.webdynpro.progmodel.api.IWDView view, boolean firstTime)
  {
    //@@begin wdDoModifyView
    //@@end
  }

  //@@begin javadoc:onActionSave(ServerEvent)
  /** Declared validating event handler. */
  //@@end
  public void onActionSave(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent )
  {
    //@@begin onActionSave(ServerEvent)
    	//save the changes here
	try {
		SAXBuilder builder = new SAXBuilder();
		builder.setValidation(false);
		builder.setIgnoringElementContentWhitespace(true);
		//sys.global.dir
		Document doc = builder.build(pathToXmlStore);
		Element userElement = getUserElement(doc, true);

		/*
		 * primitive logic -
		 * remove feeds and re-add the current feeds
		 */
		userElement.removeChildren("feed");
		int size = wdContext.nodeSubscriptions().size();
		ArrayList contentCollection = new ArrayList();
		for(int i=1;i<size;i++) {
			IPrivateRssSubscriptionsView.ISubscriptionsElement subElement = 
					wdContext.nodeSubscriptions().getSubscriptionsElementAt(i);
					
			Element feed = new Element("feed");
			feed.setAttribute("url", subElement.getUrl());
			feed.setAttribute("title", subElement.getTitle());
			feed.setAttribute("disabled", Boolean.toString(subElement.getDisabled()));
			contentCollection.add(feed);
			
			//test the Url and indicate status accordingly to the user.
			if(testUrl(subElement.getUrl())) subElement.setStatusImage("s_s_ledg.gif");
			else subElement.setStatusImage("s_s_ledr.gif");
		}

		IPrivateRssSubscriptionsView.ISubscriptionsElement subElement = 
				wdContext.nodeSubscriptions().getSubscriptionsElementAt(0);
		if (!subElement.getUrl().equalsIgnoreCase("New Feed URL")){
			//first element has changed => new subscription.
			Element feed = new Element("feed");
			feed.setAttribute("url", subElement.getUrl());
			feed.setAttribute("title", subElement.getTitle());
			feed.setAttribute("disabled", Boolean.toString(subElement.getDisabled()));
			contentCollection.add(feed);

			//test the Url and indicate status accordingly to the user.
			if(testUrl(subElement.getUrl())) subElement.setStatusImage("s_s_ledg.gif");
			else subElement.setStatusImage("s_s_ledr.gif");

			//move the first (changed) element to the end.
			wdContext.nodeSubscriptions().removeElement(subElement);
			wdContext.nodeSubscriptions().addElement(subElement);
			
			//add a new first entry so that it can again be used to add new subscriptions.
			IPrivateRssSubscriptionsView.ISubscriptionsElement firstSubscription =  wdContext.createSubscriptionsElement();
			firstSubscription.setUrl("New Feed URL");
			firstSubscription.setTitle("Feed Title");
			wdContext.nodeSubscriptions().addElement(0, firstSubscription);
		}
		
		userElement.addContent(contentCollection);
		XMLOutputter output = new XMLOutputter();
		FileOutputStream file = new FileOutputStream(pathToXmlStore);
		output.output(doc,file);
			
		//notify the RssItemProvider to refresh this user's subscriptions. ?
		//right now the RssItemProvider checks if the xml store has changed, whenever it 
		//is called by the Connector/UWLService

	}
	catch(Exception e) {
		Category.APPLICATIONS.logThrowable(Severity.FATAL,
											logger,
											(Object)"onActionSave()",
											new Object[]{this},
											"Error in Saving RSS Subscription(s)",
											e);
	}
    //@@end
  }

  //@@begin javadoc:onActionDelete(ServerEvent)
  /** Declared validating event handler. */
  //@@end
  public void onActionDelete(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent )
  {
    //@@begin onActionDelete(ServerEvent)
	int leadSelect = wdContext.nodeSubscriptions().getLeadSelection();
	int size = wdContext.nodeSubscriptions().size();
	for(int i= size-1; i>=0; i--) {
		if(wdContext.nodeSubscriptions().isMultiSelected(i) || leadSelect==i) {
			IPrivateRssSubscriptionsView.ISubscriptionsElement element = wdContext.nodeSubscriptions().getSubscriptionsElementAt(i);
			wdContext.nodeSubscriptions().removeElement(element);
		}
	}
	//save changes to xml store
	onActionSave(wdEvent);
	
    //@@end
  }

  //@@begin javadoc:onActionTestUrl(ServerEvent)
  /** Declared validating event handler. */
  //@@end
  public void onActionTestUrl(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent )
  {
    //@@begin onActionTestUrl(ServerEvent)
    //@@end
  }

  /*
   * The following code section can be used for any Java code that is 
   * not to be visible to other controllers/views or that contains constructs
   * currently not supported directly by Web Dynpro (such as inner classes or
   * member variables etc.). </p>
   *
   * Note: The content of this section is in no way managed/controlled
   * by the Web Dynpro Designtime or the Web Dynpro Runtime. 
   */
  //@@begin others
  
  private String pathToXmlStore = "";
  
  private void setPathToXmlStore() {
	String j2eeApplicationsDirectory = System.getProperty("Applications Directory");
	pathToXmlStore = j2eeApplicationsDirectory + "sap.com/irj/servlet_jsp/irj/root/WEB-INF/portal/portalapps/uwl.rss.portal/private/uwlrss/rssurls.xml";
	
	if(false) {
		String sysGlobalDir = System.getProperty("sys.global.dir");
		pathToXmlStore = sysGlobalDir + "/uwl.rss.portal/private/uwlrss/rssurls.xml";
	}
  }
  
  private List getUsersFeeds() {
	
	try {
		SAXBuilder builder = new SAXBuilder();
		builder.setValidation(false);
		builder.setIgnoringElementContentWhitespace(true);
		Document doc = builder.build(pathToXmlStore);
		List users = doc.getRootElement().getChildren("user");
		Iterator it = users.iterator();
		while (it.hasNext()) {
			Element user = (Element) it.next();
			String userId = user.getAttributeValue("id");
			IWDClientUser wdUser = WDClientUser.getLoggedInClientUser();
			if(wdUser != null) {
				if(wdUser.getSAPUser().getUniqueID().equals(userId)) {
					List feeds = user.getChildren("feed");
					return feeds;
				}
			}
		}
	} catch (JDOMException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return null;	  	
  }

  private Element getUserElement(Document doc, boolean bCreateIfRequired) {
	
	List users = doc.getRootElement().getChildren("user");
	Iterator it = users.iterator();
	IWDClientUser wdUser = WDClientUser.getLoggedInClientUser();
	String sapUserId = wdUser.getSAPUser().getUniqueID();
	if(wdUser == null) {
		// TODO throw exception. cannot view this view without authentication.
	}
	
	while (it.hasNext()) {
		Element user = (Element) it.next();
		String userId = user.getAttributeValue("id");
		if(sapUserId.equals(userId)) return user;
	}

	if(bCreateIfRequired) {
		Element newUserElement = new Element("user");
		newUserElement.setAttribute("id", sapUserId);
		doc.getRootElement().addContent(newUserElement);
		return newUserElement;
	}

	return null;	  	
  }
  
  //basic test of the URL
  private boolean testUrl(String url) {
  	try {
		URLConnection urlConnection = new URL(url).openConnection();
		return true;
  	}
  	catch(IOException ioe) {
		return false;
  	}
  }

  //@@end
}
