text:
package org.sakaiproject.tool.app.scheduler;

import java.text.ParseException;
import java.util.*;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import javax.faces.validator.ValidatorException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.CronTrigger;
import org.quartz.InterruptableJob;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.JobExecutionContext;
import org.sakaiproject.api.app.scheduler.ConfigurableJobBeanWrapper;
import org.sakaiproject.api.app.scheduler.ConfigurableJobProperty;
import org.sakaiproject.api.app.scheduler.ConfigurableJobPropertyValidationException;
import org.sakaiproject.api.app.scheduler.ConfigurableJobPropertyValidator;
import org.sakaiproject.api.app.scheduler.JobDetailWrapper;
import org.sakaiproject.api.app.scheduler.SchedulerManager;
import org.sakaiproject.api.app.scheduler.TriggerWrapper;
import org.sakaiproject.api.app.scheduler.JobBeanWrapper;
import org.sakaiproject.api.app.scheduler.events.TriggerEventManager;
import org.sakaiproject.component.app.scheduler.JobDetailWrapperImpl;
import org.sakaiproject.component.app.scheduler.TriggerWrapperImpl;
import org.sakaiproject.util.ResourceLoader;

public class SchedulerTool
{

  private static final Log LOG = LogFactory.getLog(SchedulerTool.class);

  private static final String CRON_CHECK_ASTERISK = "**";
  private static final String CRON_CHECK_QUESTION_MARK = "??";
  /** The maximum length of a trigger name. */
  private static final int TRIGGER_NAME_LENGTH_LIMIT = 80;
  /** The maximum length of a job name. */
  private static final int JOB_NAME_LENGTH_LIMIT = 80;

  private SchedulerManager schedulerManager;
  private String jobName;
  private String triggerName;
  private String triggerExpression;
  private String selectedClass;

  private List<JobDetailWrapper> jobDetailWrapperList;
  private List<JobDetailWrapper> filteredJobDetailWrapperList;
  private JobDetailWrapper selectedJobDetailWrapper;
  private boolean isSelectAllJobsSelected = false;
  private boolean isSelectAllTriggersSelected = false;

  private List<TriggerWrapper> filteredTriggersWrapperList;

  private LinkedList<String> configurableJobErrorMessages = null;
  private ConfigurableJobBeanWrapper configurableJobBeanWrapper;
  private Map<String, String> configurableJobResources;
  private List<ConfigurablePropertyWrapper> configurableJobProperties;
  private JobDetail jobDetail;
  protected ResourceLoader rb = new ResourceLoader("org.sakaiproject.tool.scheduler.bundle.Messages");
  private TriggerWrapper triggerWrapper = null;

  private TriggerEventManager
      triggerEventManager = null;
  private EventPager evtPager = new EventPager();

  public SchedulerTool()
  {
  }

  public void setTriggerEventManager (TriggerEventManager tem)
  {
      triggerEventManager = tem;

      evtPager.setTriggerEventManager(triggerEventManager);
  }

  public TriggerEventManager getTriggerEventManager()
  {
      return triggerEventManager;
  }

  public EventPager getEventPager()
  {
      return evtPager;
  }

  /**
   * @return Returns the filteredTriggersWrapperList.
   */
  public List<TriggerWrapper> getFilteredTriggersWrapperList()
  {
    return filteredTriggersWrapperList;
  }

  /**
   * @param filteredTriggersWrapperList The filteredTriggersWrapperList to set.
   */
  public void setFilteredTriggersWrapperList(List<TriggerWrapper> filteredTriggersWrapperList)
  {
    this.filteredTriggersWrapperList = filteredTriggersWrapperList;
  }

    /**
     * Returns a List of ConfigurablePropertyWrapper objects which correspond to the properties which
     * can be configured for the current ConfigurableJobBeanWrapper. {@link #setConfigurableJobBeanWrapper(ConfigurableJobBeanWrapper)}
     * must be called first, or this method will return null.
     *
     * @return List of ConfigurablePropertyWrappers, or null.
     */
  public List<ConfigurablePropertyWrapper> getConfigurableProperties()
  {
      return configurableJobProperties;
  }

    /**
     * This method runs internally to refresh the set of ConfigurablePropertyWrappers whenever
     * {@link #setConfigurableJobBeanWrapper(ConfigurableJobBeanWrapper)} or
     * {@link #setJobDetail(JobDetail)} is called. {@link getConfigurableJobBeanWrapper()} must not be null
     * for this operation to succeed.
     */
  private void refreshProperties ()
  {
      final ConfigurableJobBeanWrapper
          job = getConfigurableJobBeanWrapper();

      if (job == null)
      {
          configurableJobProperties = null;
          return;
      }

      final Set<ConfigurableJobProperty>
          props = job.getConfigurableJobProperties();

      final JobDetail
          jd = getJobDetail();

      final JobDataMap
          dataMap = (jd != null) ? jd.getJobDataMap() : null;

      if (configurableJobResources == null)
      {
          LOG.error ("no resource bundle provided for jobs of type: " + job.getJobType() + ". Labels will not be rendered correctly in the scheduler UI");
      }

      //create a List of jobs, b/c JSF can't handle Sets as a backing bean for a dataTable
      if (props != null)
      {
          configurableJobProperties = new LinkedList<ConfigurablePropertyWrapper>();

          for (ConfigurableJobProperty prop : props)
          {
              ConfigurablePropertyWrapper
                  wrapper = new ConfigurablePropertyWrapper();
              String
                  value = null;

              wrapper.setJobProperty(prop);

              if (dataMap == null || (value = (String) dataMap.get(prop.getLabelResourceKey())) == null)
              {
                  wrapper.setValue (prop.getDefaultValue());
              }
              else
              {
                  wrapper.setValue (value);
              }

              configurableJobProperties.add(wrapper);

              if (configurableJobResources != null)
              {
                  //check for resource strings for label and desc - warn if they are not present
                  final ConfigurableJobProperty
                      property = wrapper.getJobProperty();
                  final String
                      labelKey = property.getLabelResourceKey(),
                      descKey = property.getDescriptionResourceKey();

                  if (labelKey == null)
                  {
                      LOG.error ("no resource key provided for property label - NullPointerExceptions may occur in scheduler when processing jobs of type " + job.getJobType());
                  }
                  else if (configurableJobResources.get(labelKey) == null)
                  {
                      LOG.warn("no resource string provided for the property label key '" + labelKey + "' for the job type " + job.getJobType());
                  }

                  if (descKey == null)
                  {
                      LOG.warn ("no resource key provided for property description in job type " + job.getJobType());
                  }
                  else if (configurableJobResources.get(descKey) == null)
                  {
                      LOG.warn("no resource string provided for the property description key '" + descKey + "' for the job type " + job.getJobType());
                  }
              }
          }
      }
  }

    /**
     *  Sets the JobDetail object for the job presently being editted or sor which properties or triggers are being
     *  editted.
     *
     * @param detail
     */
  public void setJobDetail (JobDetail detail)
  {
      jobDetail = detail;

      refreshProperties();
  }

    /**
     *  Returns the JobDetail object for the job presently being editted or sor which properties or triggers are being
     *  editted.
     *
     * @returns JobDetail
     */
  public JobDetail getJobDetail()
  {
      return jobDetail;
  }

    /**
     * Sets the TriggerWrapper being editted.
     *
     * @param tw
     */
  public void setTriggerWrapper (TriggerWrapper tw)
  {
	  triggerWrapper = tw;
  }

    /**
     * Returns the TriggerWrapper being editted.
     *
     * @return TroggerWrapper
     */
  public TriggerWrapper getTriggerWrapper ()
  {
	  return triggerWrapper;
  }

    /**
     * Sets the ConfigurableJobBeanWrapper to establish the job whose properties are being editted
     * during a job or trigger creation process.
     *
     * @param job
     */
  public void setConfigurableJobBeanWrapper(ConfigurableJobBeanWrapper job)
  {
      configurableJobBeanWrapper = job;

      if (job != null)
      {
          final String
              rbBase = job.getResourceBundleBase();

          //process the ResourceBundle into a map, b/c JSF won't allow method calls like rb.getString()
          final ResourceBundle
              rb = ResourceBundle.getBundle(rbBase);

          if(rb != null)
          {
              configurableJobResources = new HashMap<String, String> ();

              final Enumeration
                  keyIt = rb.getKeys();

              while (keyIt.hasMoreElements())
              {
                  final String
                      key = (String)keyIt.nextElement();

                  configurableJobResources.put(key, rb.getString(key));
              }
          }
          else
          {
              configurableJobResources = null;
          }
      }
      else
      {
          configurableJobResources = null;
      }
      refreshProperties();
  }

    /**
     * Returns the ConfigurableJobBeanWrapper currently the focus for editting properties either to create a job
     * or to schedule a trigger for a job.
     *
     * @return ConfigurableJobBeanWrapper
     */
  public ConfigurableJobBeanWrapper getConfigurableJobBeanWrapper ()
  {
      return configurableJobBeanWrapper;
  }

    /**
     * Returns the resource map which will provide labels for the ConfigurableJobBeanWrapper currently the focus
     * of the job or trigger creation process. This is a read-only property which is set by {@link #setConfigurableJobBeanWrapper(ConfigurableJobBeanWrapper)}
     *
     * @return
     */
  public Map<String, String> getConfigurableJobResources()
  {
      return configurableJobResources;
  }

    /**
     * Returns validation errors which have occured during the editting of properties for a ConfigurableJobBeanWrapper.
     *
     * @return List of validation error Strings
     */
  public List<String> getConfigurableJobErrorMessages()
  {
      return configurableJobErrorMessages;
  }

  /**
   * @return Returns the isSelectAllJobsSelected.
   */
  public boolean isSelectAllJobsSelected()
  {
    return isSelectAllJobsSelected;
  }

  /**
   * @param isSelectAllJobsSelected
   *          The isSelectAllJobsSelected to set.
   */
  public void setSelectAllJobsSelected(boolean isSelectAllJobsSelected)
  {
    this.isSelectAllJobsSelected = isSelectAllJobsSelected;
  }

  /**
   * @return Returns the selectedClass.
   */
  public String getSelectedClass()
  {
    return selectedClass;
  }

  /**
   * @param selectedClass
   *          The selectedClass to set.
   */
  public void setSelectedClass(String selectedClass)
  {
    this.selectedClass = selectedClass;
  }

  /**
   * @return Returns the jobName.
   */
  public String getJobName()
  {
    return jobName;
  }

  /**
   * @param jobName
   *          The jobName to set.
   */
  public void setJobName(String jobName)
  {
    this.jobName = jobName;
  }

  /**
   * @return Returns the triggerName.
   */
  public String getTriggerName()
  {
    return triggerName;
  }

  /**
   * @param triggerName The triggerName to set.
   */
  public void setTriggerName(String triggerName)
  {
    this.triggerName = triggerName;
  }

  /**
   * @return Returns the triggerExpression.
   */
  public String getTriggerExpression()
  {
    return triggerExpression;
  }

  /**
   * @param triggerExpression The triggerExpression to set.
   */
  public void setTriggerExpression(String triggerExpression)
  {
    this.triggerExpression = triggerExpression;
  }

  /**
   * @return Returns the jobClasses.
   */
  public Map getJobClasses()
  {
    return schedulerManager.getQrtzQualifiedJobs();
  }

  /**
   * @return Returns the schedulerManager.
   */
  public SchedulerManager getSchedulerManager()
  {
    return schedulerManager;
  }

  /**
   * @param schedulerManager
   *          The schedulerManager to set.
   */
  public void setSchedulerManager(SchedulerManager schedulerManager)
  {
    this.schedulerManager = schedulerManager;
  }

  /**
   * @return Returns the jobDetailWrapperList.
   */
  public List<JobDetailWrapper> getJobDetailWrapperList()
  {
    return jobDetailWrapperList;
  }

  /**
   * @param jobDetailWrapperList
   *          The jobDetailWrapperList to set.
   */
  public void setJobDetailWrapperList(List<JobDetailWrapper> jobDetailWrapperList)
  {
    this.jobDetailWrapperList = jobDetailWrapperList;
  }

  /**
   * @return Returns the filteredJobDetailWrapperList.
   */
  public List getFilteredJobDetailWrapperList()
  {
    return filteredJobDetailWrapperList;
  }

  /**
   * @param filteredJobDetailWrapperList
   *          The filteredJobDetailWrapperList to set.
   */
  public void setFilteredJobDetailWrapperList(List filteredJobDetailWrapperList)
  {
    this.filteredJobDetailWrapperList = filteredJobDetailWrapperList;
  }

  /**
   * @return Returns the selectedJobDetailWrapper.
   */
  public JobDetailWrapper getSelectedJobDetailWrapper()
  {
    return selectedJobDetailWrapper;
  }

  /**
   * @param selectedJobDetailWrapper
   *          The selectedJobDetailWrapper to set.
   */
  public void setSelectedJobDetailWrapper(
      JobDetailWrapper selectedJobDetailWrapper)
  {
    this.selectedJobDetailWrapper = selectedJobDetailWrapper;
  }

  /**
   * This method runs the current job only once, right now
   * @return int 0 if it's not running, 1 if it is, 2 if there is an error
   */
  public int getSelectedJobRunning()
  {
     Scheduler scheduler = schedulerManager.getScheduler();
     if (scheduler == null)
     {
       LOG.error("Scheduler is down!");
       return 2;
     }
     try
     {
        List executingJobs = scheduler.getCurrentlyExecutingJobs();

        for(Iterator i = executingJobs.iterator(); i.hasNext(); ) {
           JobExecutionContext jobExecContext = (JobExecutionContext)i.next();
           if(selectedJobDetailWrapper.getJobDetail().getFullName().equals(
                    jobExecContext.getJobDetail().getFullName()) )
              return 1;
        }
       return 0;
     }
     catch (Exception e)
     {
       LOG.error("Failed to trigger job now");
       return 2;
     }
  }

    /**
     * Convenience method for creating a JobDetail object from a JobBeanWrapper. The JobDetail object is
     * used to actually create a job within Quartz, and is also tracked by the {@link getJobDetail()} property
     * for use during the property editting process.
     *
     * @param job
     * @return JobDetail object constructed from the job argument
     */
  private JobDetail createJobDetail (JobBeanWrapper job)
  {
      JobDetail
          jd = new JobDetail (jobName, Scheduler.DEFAULT_GROUP, job.getJobClass(), false, true, true);
      JobDataMap
          map = jd.getJobDataMap();

      map.put(JobBeanWrapper.SPRING_BEAN_NAME, job.getBeanId());
      map.put(JobBeanWrapper.JOB_TYPE, job.getJobType());

      return jd;
  }

  public String processCreateJob()
  {
    Scheduler scheduler = schedulerManager.getScheduler();
    if (scheduler == null)
    {
      LOG.error("Scheduler is down!");
      return "error";
    }
    try
    {
        //get a JobDetail object in case one is already in the Session
        //  (eg. if we have returned her from a validation error
       JobDetail jd = getJobDetail();
       JobBeanWrapper job = getSchedulerManager().getJobBeanWrapper(selectedClass);

       if (job != null)
       {
           // create a new JobDetail object for this job
           jd = createJobDetail(job);

    	   //we have a job, so check to see if properties need to be set
           if (ConfigurableJobBeanWrapper.class.isAssignableFrom(job.getClass()))
           {
        	   //this job is configurable, provide a screen to edit properties
               final ConfigurableJobBeanWrapper
                   configurableJob = (ConfigurableJobBeanWrapper)job;

               // prepare properties for use within the property configuration UI
               setConfigurableJobBeanWrapper (configurableJob);
               setJobDetail(jd);

               return "edit_properties";
           }
           else
           {
        	   //not a configurable job, create the job and move on
               setConfigurableJobBeanWrapper(null);
           }
       }
       else
       {
    	   // this is not a job configured via a JobBeanWrapper
    	   // assume the class is a Job and schedule its execution
          setConfigurableJobBeanWrapper(null);
          jd = new JobDetail(jobName, Scheduler.DEFAULT_GROUP,
             Class.forName(selectedClass.toString()), false, true, true);
       }

       // create the job and show the list of jobs
      scheduler.addJob(jd, false);
      jobName = null;
      // Clear out the form.
      selectedClass = null;
      processRefreshJobs();
      return "jobs";
    }
    catch (Exception e)
    {
      LOG.error("Failed to create job. Exception message is: " + e.getMessage());
      return "error";
    }
  }

    /**
     * Processes the properties which have been set during creation of a job.
     *
     * @return
     */
  public String processSetProperties()
  {
      Scheduler scheduler = schedulerManager.getScheduler();
      if (scheduler == null)
      {
        LOG.error("Scheduler is down!");
        return "error";
      }

      configurableJobErrorMessages = new LinkedList<String>();

      try
      {
          JobDetail
              jd = getJobDetail();
          JobBeanWrapper
              job = getSchedulerManager().getJobBeanWrapper(selectedClass);

          final ConfigurableJobBeanWrapper
              configurableJob = getConfigurableJobBeanWrapper();

          final List<ConfigurablePropertyWrapper>
              properties = getConfigurableProperties();

          final ResourceBundle
              jobRb = ResourceBundle.getBundle(configurableJob.getResourceBundleBase());

          final ConfigurableJobPropertyValidator
              validator = configurableJob.getConfigurableJobPropertyValidator();

          if (jd != null)
          {
              final JobDataMap
                  dataMap = jd.getJobDataMap();

              for (ConfigurablePropertyWrapper wrapper : properties)
              {
                  final ConfigurableJobProperty
                      property = wrapper.getJobProperty();
                  final String
                      label = property.getLabelResourceKey(),
                      value = wrapper.getValue();

                  if (property.isRequired() && (value == null || value.trim().length() == 0))
                  {
                      String
                          propName = (jobRb != null)?jobRb.getString(label):label,
                          msg = null;

                      if (propName == null)
                          propName = label;

                      try
                      {
                          msg = rb.getString("properties_required");
                      }
                      catch (MissingResourceException mre)
                      {
                          msg = "<Missing resource string: properties_required>";
                      }

                      configurableJobErrorMessages.add(msg + ": " + propName);
                  }
                  else
                  {
                      try
                      {
                          validator.assertValid(label, value);
                      }
                      catch (ConfigurableJobPropertyValidationException cjpve)
                      {
                          String
                              errorKey = cjpve.getMessage(),
                              errorMessage = jobRb.getString(errorKey);

                          configurableJobErrorMessages.add ((errorMessage == null)?errorKey:errorMessage);
                          continue;
                      }
                      dataMap.put(property.getLabelResourceKey(), value);
                  }
              }

              if (!configurableJobErrorMessages.isEmpty())
              {
                  return null;
              }
          }
          else
          {
              setJobDetail (createJobDetail(job));
              return null;
          }
          scheduler.addJob(jd, false);
          // Clear out the form
          jobName = null;
          jobDetail = null;
          processRefreshJobs();
          return "jobs";
      }
      catch (Exception e)
      {
          LOG.error("Failed to create job. Exception message is: " + e.getMessage());
          return "error";
      }
  }

    /**
     * Convenience method for scheduling a Trigger with the Quartz Scheduler object.
     * @param wrapper
     * @throws SchedulerException
     */
  private void scheduleTrigger(TriggerWrapper wrapper) throws SchedulerException
  {
	  Trigger
	  	trigger = wrapper.getTrigger();

	  Scheduler
	  	scheduler = schedulerManager.getScheduler();

      scheduler.scheduleJob(trigger);
      selectedJobDetailWrapper.getTriggerWrapperList().add(wrapper);
      int currentTriggerCount = selectedJobDetailWrapper.getTriggerCount()
          .intValue();
      selectedJobDetailWrapper.setTriggerCount(Integer.valueOf(
          currentTriggerCount + 1));
  }

    /**
     * Creates a trigger for the currently selected JobDetailWrapper. This method redirects to UI
     * to override configured properties if the Job is configurable.
     *
     * @return
     */
  public String processCreateTrigger()
  {
    Scheduler scheduler = schedulerManager.getScheduler();
    if (scheduler == null)
    {
      LOG.error("Scheduler is down!");
      return "error";
    }
    try
    {
    	JobDetail
    		jd = selectedJobDetailWrapper.getJobDetail();

    	Trigger trigger = new CronTrigger(triggerName, Scheduler.DEFAULT_GROUP,
    		  						    jd.getName(),
    		  						    Scheduler.DEFAULT_GROUP, triggerExpression);

    	TriggerWrapper tempTriggerWrapper = new TriggerWrapperImpl();
    	tempTriggerWrapper.setTrigger(trigger);

      	JobBeanWrapper
      		job = getSchedulerManager().getJobBeanWrapper(selectedJobDetailWrapper.getJobType());

      	if (job != null)
      	{
		    if (ConfigurableJobBeanWrapper.class.isAssignableFrom(job.getClass()))
		    {
		        final ConfigurableJobBeanWrapper
		            configurableJob = (ConfigurableJobBeanWrapper)job;

                setJobDetail (jd);
		        setConfigurableJobBeanWrapper (configurableJob);
		        setTriggerWrapper (tempTriggerWrapper);

		        return "edit_trigger_properties";
		    }
		    else
		    {
		    	setConfigurableJobBeanWrapper(null);
                setJobDetail(null);
		    	setTriggerWrapper(null);
		    }
		}

      	scheduleTrigger (tempTriggerWrapper);

      	return "edit_triggers";
    }
    catch (Exception e)
    {
      LOG.error("Failed to create trigger. Exception message is: " + e.getMessage());
      return "error";
    }
    finally
    {
    	triggerName = null;
    	triggerExpression = null;
    }
  }

    /**
     * Validates and sets the properties for a Trigger once the property configuration UI has been completed.
     *
     * @return
     */
  public String processSetTriggerProperties ()
  {
      Scheduler scheduler = schedulerManager.getScheduler();
      if (scheduler == null)
      {
        LOG.error("Scheduler is down!");
        return "error";
      }

      configurableJobErrorMessages = new LinkedList<String>();

      try
      {
      	  final JobDetail
      	  	  jd = selectedJobDetailWrapper.getJobDetail();

          final ConfigurableJobBeanWrapper
              configurableJob = getConfigurableJobBeanWrapper();

          final TriggerWrapper
      	  	  triggerWrapper = getTriggerWrapper();

          final Trigger
          	  trigger = triggerWrapper.getTrigger();

          final List<ConfigurablePropertyWrapper>
              properties = getConfigurableProperties();

          final ResourceBundle
              jobRb = ResourceBundle.getBundle(configurableJob.getResourceBundleBase());

          final ConfigurableJobPropertyValidator
              validator = configurableJob.getConfigurableJobPropertyValidator();

          final JobDataMap
              dataMap = trigger.getJobDataMap();

          for (ConfigurablePropertyWrapper wrapper : properties)
          {
              final ConfigurableJobProperty
                  property = wrapper.getJobProperty();
              final String
                  label = property.getLabelResourceKey(),
                  value = wrapper.getValue();

              if (property.isRequired() && (value == null || value.trim().length() == 0))
              {
                  String
                      propName = (jobRb != null)?jobRb.getString(label):label,
                      msg = null;

                  if (propName == null)
                      propName = label;

                  try
                  {
                      msg = rb.getString("properties_required");
                  }
                  catch (MissingResourceException mre)
                  {
                      msg = "<Missing resource string: properties_required>";
                  }

                  configurableJobErrorMessages.add(msg + ": " + propName);
              }
              else
              {
                  try
                  {
                      validator.assertValid(label, value);
                  }
                  catch (ConfigurableJobPropertyValidationException cjpve)
                  {
                      String
                          errorKey = cjpve.getMessage(),
                          errorMessage = jobRb.getString(errorKey);

                      configurableJobErrorMessages.add ((errorMessage == null)?errorKey:errorMessage);
                      continue;
                  }
                  dataMap.put(property.getLabelResourceKey(), value);
              }
          }

          if (!configurableJobErrorMessages.isEmpty())
          {
              return null;
          }

          scheduleTrigger(triggerWrapper);
      }
      catch (Exception e)
      {
          LOG.error("Failed to create job. Exception message is: " + e.getMessage());
          return "error";
      }

	  return "edit_triggers";
  }

  public String processSelectAllJobs()
  {

    isSelectAllJobsSelected = !isSelectAllJobsSelected;
    processRefreshJobs();
    return "jobs";
  }

  public String processSelectAllTriggers()
  {

    isSelectAllTriggersSelected = !isSelectAllTriggersSelected;
    for (Iterator i = selectedJobDetailWrapper.getTriggerWrapperList()
        .iterator(); i.hasNext();)
    {
      if (isSelectAllTriggersSelected)
      {
        ((TriggerWrapper) i.next()).setIsSelected(true);
      }
      else
      {
        ((TriggerWrapper) i.next()).setIsSelected(false);
      }
    }
    return "edit_triggers";
  }

  public String processDeleteJobs()
  {
    try
    {
      for (Iterator i = filteredJobDetailWrapperList.iterator(); i.hasNext();)
      {
        JobDetailWrapper jobDetailWrapper = (JobDetailWrapper) i.next();
        schedulerManager.getScheduler().deleteJob(
            jobDetailWrapper.getJobDetail().getName(), Scheduler.DEFAULT_GROUP);
      }
    }
    catch (SchedulerException e)
    {
      LOG.error("Scheduler Down");
    }
    processRefreshJobs();
    return "jobs";
  }

  public String processDeleteTriggers()
  {
    try
    {
      TriggerWrapper triggerWrapper;
      for (Iterator<TriggerWrapper> i = filteredTriggersWrapperList.iterator(); i.hasNext();)
      {
        triggerWrapper = (TriggerWrapper) i.next();
        schedulerManager.getScheduler().unscheduleJob(
            triggerWrapper.getTrigger().getName(), triggerWrapper.getTrigger().getGroup());
        selectedJobDetailWrapper.getTriggerWrapperList().remove(triggerWrapper);
      }
    }
    catch (SchedulerException e)
    {
      LOG.error("Scheduler Down");
    }
    return "edit_triggers";
  }

  public String processRefreshJobs()
  {
    try
    {
      Scheduler scheduler = schedulerManager.getScheduler();
      String[] jobNames = scheduler.getJobNames(Scheduler.DEFAULT_GROUP);
      jobDetailWrapperList = new ArrayList();
      for (int i = 0; i < jobNames.length; i++)
      {
        JobDetailWrapper jobDetailWrapper = new JobDetailWrapperImpl();
        jobDetailWrapper.setJobDetail(scheduler.getJobDetail(jobNames[i],
            Scheduler.DEFAULT_GROUP));
        Trigger[] triggerArr = scheduler.getTriggersOfJob(jobNames[i],
            Scheduler.DEFAULT_GROUP);
        List<TriggerWrapper> triggerWrapperList = new ArrayList<TriggerWrapper>();
        TriggerWrapper tw;
        for (int j = 0; j < triggerArr.length; j++)
        {
          tw = new TriggerWrapperImpl();
          tw.setTrigger(triggerArr[j]);
          triggerWrapperList.add(tw);
        }

        jobDetailWrapper.setTriggerWrapperList(triggerWrapperList);
        jobDetailWrapperList.add(jobDetailWrapper);
      }
    }
    catch (SchedulerException e)
    {
      LOG.error("scheduler error while getting job detail");
    }

    // test for select all
    if (isSelectAllJobsSelected)
    {
      for (Iterator<JobDetailWrapper> i = jobDetailWrapperList.iterator(); i.hasNext();)
      {
        if (isSelectAllJobsSelected)
        {
          ((JobDetailWrapper) i.next()).setIsSelected(true);
        }
        else
        {
          ((JobDetailWrapper) i.next()).setIsSelected(false);
        }
      }
    }
    return "jobs";
  }

    /**
     * Determines if the Job has configuration properties which might need to be overriden when the
     * job is run. If so this redirects to a property configuration screen. Otherwise it simply continues
     * to a confirmation screen.
     *
     * @return
     */
  public String processPrepRunJobNow()
  {
      Scheduler scheduler = schedulerManager.getScheduler();
      if (scheduler == null)
      {
        LOG.error("Scheduler is down!");
        return "error";
      }

      try
      {
          JobDetail
              jd = selectedJobDetailWrapper.getJobDetail();

          JobBeanWrapper
              job = getSchedulerManager().getJobBeanWrapper(selectedJobDetailWrapper.getJobType());

          if (job != null)
          {
              if (ConfigurableJobBeanWrapper.class.isAssignableFrom(job.getClass()))
              {
                  final ConfigurableJobBeanWrapper
                      configurableJob = (ConfigurableJobBeanWrapper)job;

                  setJobDetail (jd);
                  setConfigurableJobBeanWrapper (configurableJob);

                  return "edit_runnow_properties";
              }
              else
              {
                  setConfigurableJobBeanWrapper(null);
                  setJobDetail(null);
              }
          }
          return "run_job_confirm";
      }
      catch (Exception e)
      {
    	LOG.error("Failed to run job now. Exception message is: " + e.getMessage());
        return "error";
      }
  }

    /**
     * Processes the properties set for a Job that will be run now.
     *
     * @return
     */
  public String processSetRunNowProperties()
  {
      Scheduler scheduler = schedulerManager.getScheduler();
      if (scheduler == null)
      {
        LOG.error("Scheduler is down!");
        return "error";
      }
      try
      {
          JobDetail
              jd = getJobDetail();

          JobBeanWrapper
              job = getSchedulerManager().getJobBeanWrapper(selectedJobDetailWrapper.getJobType());

          if (job != null)
          {
              if (ConfigurableJobBeanWrapper.class.isAssignableFrom(job.getClass()))
              {
                  configurableJobErrorMessages = new LinkedList<String>();

                  final ConfigurableJobBeanWrapper
                      configurableJob = (ConfigurableJobBeanWrapper) job;

                  final List<ConfigurablePropertyWrapper>
                      properties = getConfigurableProperties();

                  final ResourceLoader
                      jobRb = new ResourceLoader(configurableJob.getResourceBundleBase());

                  final ConfigurableJobPropertyValidator
                      validator = configurableJob.getConfigurableJobPropertyValidator();

                  for (ConfigurablePropertyWrapper wrapper : properties)
                  {
                      final ConfigurableJobProperty
                          property = wrapper.getJobProperty();
                      final String
                          label = property.getLabelResourceKey(),
                          value = wrapper.getValue();

                      if (property.isRequired() && (value == null || value.trim().length() == 0))
                      {
                          String
                              propName = (jobRb != null)?jobRb.getString(label):label,
                              msg = null;

                          if (propName == null)
                              propName = label;

                          try
                          {
                              msg = rb.getString("properties_required");
                          }
                          catch (MissingResourceException mre)
                          {
                              msg = "<Missing resource string: properties_required>";
                          }

                          configurableJobErrorMessages.add(msg + ": " + propName);
                      }
                      else
                      {
                          try
                          {
                              validator.assertValid(label, value);
                          }
                          catch (ConfigurableJobPropertyValidationException cjpve)
                          {
                              String
                                  errorKey = cjpve.getMessage(),
                                  errorMessage = jobRb.getString(errorKey);

                              configurableJobErrorMessages.add ((errorMessage==null)?errorKey:errorMessage);
                              continue;
                          }
                      }
                  }

                  if (!configurableJobErrorMessages.isEmpty())
                  {
                      return null;
                  }
              }
          }
          return "run_now_confirm";
      }
      catch (Exception e)
      {
          LOG.error("Failed to trigger job now");
          return "error";
      }
  }

  /**
   * This method runs the current job only once, right now. It will set properties on the Job execution if the
   * Job has configurable properties.
   *
   * @return String
   */
  public String processRunJobNow()
  {
     Scheduler scheduler = schedulerManager.getScheduler();
     if (scheduler == null)
     {
       LOG.error("Scheduler is down!");
       return "error";
     }
     try
     {
         JobDetail
             jd = getJobDetail();

         JobBeanWrapper
             job = getSchedulerManager().getJobBeanWrapper(selectedJobDetailWrapper.getJobType());

         JobDataMap
             dataMap = null;

         if (job != null)
         {
             if (ConfigurableJobBeanWrapper.class.isAssignableFrom(job.getClass()))
             {
                 configurableJobErrorMessages = new LinkedList<String>();

                 final List<ConfigurablePropertyWrapper>
                     properties = getConfigurableProperties();

                 dataMap = new JobDataMap (jd.getJobDataMap());

                 for (ConfigurablePropertyWrapper wrapper : properties)
                 {
                     final ConfigurableJobProperty
                         property = wrapper.getJobProperty();
                     final String
                         label = property.getLabelResourceKey(),
                         value = wrapper.getValue();

                     dataMap.put(label, value);
                 }
             }
         }

         if (dataMap == null)
         {
             scheduler.triggerJob(selectedJobDetailWrapper.getJobDetail().getName(),
                                  selectedJobDetailWrapper.getJobDetail().getGroup());
         }
         else
         {
             scheduler.triggerJob(selectedJobDetailWrapper.getJobDetail().getName(),
                                  selectedJobDetailWrapper.getJobDetail().getGroup(),
                                  dataMap);
         }

       return "success";
     }
     catch (Exception e)
     {
       LOG.error("Failed to trigger job now");
       return "error";
     }
  }

  public List<JobExecutionContextWrapperBean> getRunningJobs() {
	  List<JobExecutionContext> currentJobs = new ArrayList<JobExecutionContext>();
	  List<JobExecutionContextWrapperBean> currentWrappedJobs = new ArrayList<JobExecutionContextWrapperBean>();
	  Scheduler scheduler = schedulerManager.getScheduler();
	  if (scheduler == null)
	  {
		  LOG.error("Scheduler is down!");
	  }
	  else {
		  try {
			  currentJobs = scheduler.getCurrentlyExecutingJobs();
		  } catch (SchedulerException e) {
			  LOG.warn("Unable to get currently executing jobs");
		  }
	  }

	  for (JobExecutionContext jec : currentJobs)
	  {
		  JobExecutionContextWrapperBean jobExecutionContextWrapper = new JobExecutionContextWrapperBean(this, jec);
		  jobExecutionContextWrapper.setIsKillable(isJobKillable(jec.getJobDetail()));
		  currentWrappedJobs.add(jobExecutionContextWrapper);
	  }

	  return currentWrappedJobs;
  }

  public boolean isJobKillable(JobDetail detail) {
	  if (InterruptableJob.class.isAssignableFrom(detail.getJobClass())) {
		  return true;
	  }
	  return false;
  }

  public String processRefreshFilteredJobs()
  {
    filteredJobDetailWrapperList = new ArrayList<JobDetailWrapper>();
    for (Iterator<JobDetailWrapper> i = jobDetailWrapperList.iterator(); i.hasNext();)
    {
      JobDetailWrapper jobDetailWrapper = (JobDetailWrapper) i.next();
      if (jobDetailWrapper.getIsSelected())
      {
        filteredJobDetailWrapperList.add(jobDetailWrapper);
      }
    }
    return "delete_jobs";
  }

  public String processRefreshFilteredTriggers()
  {
    filteredTriggersWrapperList = new ArrayList<TriggerWrapper>();
    for (Iterator<TriggerWrapper> i = selectedJobDetailWrapper.getTriggerWrapperList()
        .iterator(); i.hasNext();)
    {
      TriggerWrapper triggerWrapper = (TriggerWrapper) i.next();
      if (triggerWrapper.getIsSelected())
      {
        filteredTriggersWrapperList.add(triggerWrapper);
      }
    }
    return "delete_triggers";
  }

  public int getJobNameMaxLength() {
     return JOB_NAME_LENGTH_LIMIT;
  }

  public void validateJobName(FacesContext context, UIComponent component,
      Object object)
  {
    if (object instanceof String)
    {
      String value = (String)object;
      try
      {
        JobDetail jd = schedulerManager.getScheduler().getJobDetail(value, Scheduler.DEFAULT_GROUP);
        if (jd != null)
        {
          FacesMessage message = new FacesMessage(rb.getString("existing_job_name"));
          message.setSeverity(FacesMessage.SEVERITY_WARN);
          throw new ValidatorException(message);
        }
      }
      catch (SchedulerException e)
      {
        LOG.error("Scheduler down!");
      }
    }
  }

  public int getTriggerNameMaxLength() {
    return TRIGGER_NAME_LENGTH_LIMIT;
  }

  public void validateTriggerName(FacesContext context, UIComponent component,
      Object object)
  {
    if (object instanceof String)
    {
      String value = (String)object;
      try
      {
        Trigger trigger = schedulerManager.getScheduler().getTrigger(
            (String) value, Scheduler.DEFAULT_GROUP);
        if (trigger != null)
        {
          FacesMessage message = new FacesMessage(rb.getString("existing_trigger_name"));
          message.setSeverity(FacesMessage.SEVERITY_WARN);
          throw new ValidatorException(message);
        }
      }
      catch (SchedulerException e)
      {
        LOG.error("Scheduler down!");
      }
    }
  }

  public void validateTriggerExpression(FacesContext context,
      UIComponent component, Object value)
  {
    if (value != null)
    {
      try
      {
        String expression = (String) value;
        CronTrigger trigger = new CronTrigger();
        trigger.setCronExpression(expression);

        // additional checks
        // quartz does not check for more than 7 tokens in expression
        String[] arr = expression.split("\\s");
        if (arr.length > 7)
        {
          throw new ParseException("Expression has more than 7 tokens", 7);
        }

        //(check that last 2 entries are not both * or ?
        String trimmed_expression = expression.replaceAll("\\s", ""); // remove whitespace
        if (trimmed_expression.endsWith(CRON_CHECK_ASTERISK)
            || trimmed_expression.endsWith(CRON_CHECK_QUESTION_MARK))
        {
          throw new ParseException("Cannot End in * * or ? ?", 1);
        }
      }
      catch (ParseException e)
      {
        // not giving a detailed message to prevent line wraps
        FacesMessage message = new FacesMessage(rb.getString("parse_exception"));
        message.setSeverity(FacesMessage.SEVERITY_WARN);
        throw new ValidatorException(message);
      }
    }
  }

  public void editTriggersListener(ActionEvent e)
  {
    FacesContext context = FacesContext.getCurrentInstance();
    Map requestParams = context.getExternalContext().getRequestParameterMap();
    String jobName = (String) requestParams.get("jobName");

    //loop through jobDetailWrapperList finding the one selected by user.
    for (Iterator i = jobDetailWrapperList.iterator(); i.hasNext();)
    {
      JobDetailWrapper jobDetailWrapper = (JobDetailWrapper) i.next();
      if (jobDetailWrapper.getJobDetail().getName().equals(jobName))
      {
        selectedJobDetailWrapper = jobDetailWrapper;
        break;
      }
    }
  }

   public Map<String, String> getBeanJobs() {
      Map<String, String> beanJobs = new TreeMap<String, String>();
      Map<String, JobBeanWrapper> serverJobs = getSchedulerManager().getBeanJobs();
      for (Iterator<String> i=serverJobs.keySet().iterator();i.hasNext();) {
         String job = i.next();
         beanJobs.put(job, job);
      }
      return beanJobs;
   }

   public String processSetFilters()
   {
       getEventPager().setFilterEnabled(true);

       return "events";
   }

   public String processClearFilters()
   {
       getEventPager().setFilterEnabled(false);

       return "events";
   }

   public List<SelectItem> getScheduledJobs() throws SchedulerException
   {
       ArrayList<SelectItem>
           scheduledJobs = new ArrayList<SelectItem> ();
       String[]
           jArr = schedulerManager.getScheduler().getJobNames(Scheduler.DEFAULT_GROUP);

       for (int i = 0; i < jArr.length; i++)
       {
           scheduledJobs.add(new SelectItem(jArr[i]));
       }

       return scheduledJobs;
   }
}


text:
/*global opensocial */

/**
 * @fileoverview DataResponse containing information about
 * friends, contacts, profile, app data, and activities.
 *
 * Whenever a dataRequest is sent to the server it will return a dataResponse
 * object. Values from the server will be mapped to the requested keys specified
 * in the dataRequest.
 */

/**
 * @class
 * This object contains the requested server data mapped to the requested keys.
 *
 *

 * See also:
 * DataRequest
 *

 *
 * @name opensocial.DataResponse
 */

/**
 * Construct the data response.
 * This object contains the requested server data mapped to the requested keys.
 *
 * @param {Object.<string, ResponseItem>} responseItems Key/value map of data
 *    response information
 * @param {boolean=} opt_globalError Optional field indicating whether there were
 *    any errors generating this data response
 * @param {string=} opt_errorMessage
 *
 * @private
 * @constructor
 */
opensocial.DataResponse = function(responseItems, opt_globalError,
    opt_errorMessage) {
  this.responseItems_ = responseItems;
  this.globalError_ = opt_globalError;
  this.errorMessage_ = opt_errorMessage;
};

/**
 * Returns true if there was an error in fetching this data from the server.
 *
 * @return {boolean} True if there was an error; otherwise, false
 * @member opensocial.DataResponse
 */
opensocial.DataResponse.prototype.hadError = function() {
  return !!this.globalError_;
};

/**
 * If the entire request had a batch level error, returns the error message.
 *
 * @return {string} A human-readable description of the error that occurred.
 */
opensocial.DataResponse.prototype.getErrorMessage = function() {
  return this.errorMessage_;
};

/**
 * Gets the ResponseItem for the requested field.
 *
 * @return {opensocial.ResponseItem} The requested
 *    response calculated by the
 *    server
 * @member opensocial.DataResponse
 */
opensocial.DataResponse.prototype.get = function(key) {
  return this.responseItems_[key];
};

redpajama_set_name: RedPajamaGithub


text: CKEDITOR.plugins.setLang("selectall","es-mx",{toolbar:"Seleccionar todo"});


text:
README FOR FAC SEX COALESCENT

FacSexCoalescent is a simulation program, written in C, to simulate genealogies from individuals that alternate between sexual and asexual (parthenogenetic) reproduction. It is the source code for the Hartfield, Wright and Agrawal manuscript "Coalescence and linkage disequilibrium in facultatively sexual diploids". This updated version of the program can simulate genealogies at multiple sites, and is much faster since it is written in C (the 2015 program was written in R and only simulated genealogies at a single site).

COMPILATION:
This is a program written in C and needs to be compiled before execution. Compile using a program like gcc using the following command:

gcc -o FacSexCoalescent -lm -lgsl -lgslcblas -I/usr/local/include -L/usr/local/lib FacSexCoalescent.c

Simulation uses routines found with the GNU Scientific Library (GSL) (http://www.gnu.org/software/gsl/) Since GSL is distributed under the GNU General Public License (http://www.gnu.org/copyleft/gpl.html), you must download it separately from this file.

EXECUTION:
For basic usage, run the program without any input parameters to obtain the basic command line.
Otherwise, more information is available in the user documentation.

Comments to matthew.hartfield@birc.au.dk.


text:
package org.apache.samza.coordinator.stream;

import java.util.Arrays;
import java.util.List;
import org.apache.samza.coordinator.stream.messages.CoordinatorStreamMessage;
import org.apache.samza.serializers.JsonSerde;
import org.apache.samza.serializers.Serde;

/**
 * Serializer for keys written into coordinator stream.
 */
public class CoordinatorStreamKeySerde implements Serde<String> {

  private static final int KEY_INDEX = 2;

  private final Serde<List<?>> keySerde;
  private final String type;

  public CoordinatorStreamKeySerde(String type) {
    this.type = type;
    this.keySerde = new JsonSerde<>();
  }

  @Override
  public String fromBytes(byte[] bytes) {
    Object[] keyArray = keySerde.fromBytes(bytes).toArray();
    return (String) keyArray[KEY_INDEX];
  }

  @Override
  public byte[] toBytes(String key) {
    Object[] keyArray = new Object[]{CoordinatorStreamMessage.VERSION, type, key};
    return keySerde.toBytes(Arrays.asList(keyArray));
  }
}


text:
Function Test-CGMMTargetGroup {
    <#
    .SYNOPSIS
    Run Pester tests against a target group for migration.

    .DESCRIPTION
    Run Pester tests against a target group for migration.  A default Pester script is executed to validate whether the group can be staged successfully.

    .EXAMPLE
    Test-CGMMTargetGroup -Identity $Identity

    Run the default Pester test against an existing target group.
    .EXAMPLE
    Test-CGMMTargetGroup -Identity $Identity -Tag EXOnPrem

    Use predefined Tags to run one or more tests.  Allows you to rerun portions of the test when correcting group configurations.
    .EXAMPLE
    Test-CGMMTargetGroup -Identity $Identity -PassThru

    The PassThru switch causes Invoke-Pester to produce an output object which can be analyzed by its caller, instead of only sending output to the console.
    .EXAMPLE
    Test-CGMMTargetGroup -Identity $Identity -DomainController $DomainController

    Ensure on premise queries use a specified domain controller within the Pester test
    .NOTES

    #>
    #requires -Module Pester

    [CmdletBinding()]
    param(
        # Pipeline variable
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Identity,

        [Parameter()]
        [ValidateSet('EXOnline','EXOnPrem','MSOnline')]
        [string[]]$Tag,

        [Parameter()]
        [Switch]$PassThru,

        [Parameter()]
        [string]$DomainController
    )

	begin {}
	process	{
        # Use the default pester test path set in the PSM1
        $Script = $DefaultPesterTest

        # Check for Exchange cmdlet availability in On Prem & Exchange Online
        Try {Test-CGMMCmdletAccess -Environment OnPrem,Cloud -ErrorAction Stop}
        Catch {
            $PsCmdlet.ThrowTerminatingError($PSItem)
        }

        # Test for MSOnline access - the only function that uses it, but the Pester tests will skip
        # tests that utilize it if it's not available.
        Try {Get-MsolAccountSku -ErrorAction Stop | Out-Null}
        Catch {
            If ($PSItem -match 'You must call the Connect-MsolService cmdlet before calling any other cmdlets.') {
                Write-Warning 'Domain validation requires MSOnline connectivity, but is optional.  Run Connect-MsolService to avoid skipping those tests.'
            }
        }

        # Set Script Parameters
        $ScriptParameters = @{
            Identity   = $PSBoundParameters.Identity
        }
        If ($PSBoundParameters.DomainController) {
            $ScriptParameters.Add('DomainController',$PSBoundParameters.DomainController)
        }

        # Set Pester Parameters
        $invokePesterSplat = @{
            Script  = @{Path=$Script;Parameters=$ScriptParameters}
        }
        If ($PSBoundParameters.Tag) {
            $invokePesterSplat.Add('Tag',$PSBoundParameters.Tag)
        }
        If ($PSBoundParameters.PassThru) {
            $invokePesterSplat.Add('PassThru',$PSBoundParameters.PassThru)
        }
        Invoke-Pester @invokePesterSplat
    }
	end {}
}


text:
@implementation NSString (Tools)
// self 就是调用当前成员方法的NSString对象
- (CGRect)textRectWithSize:(CGSize)size attributes:(NSDictionary *)attributes
{
    return  [self boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
}
@end


text:
package com.alibaba.otter.node.common.config.impl;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;

import com.alibaba.otter.node.common.communication.NodeCommmunicationClient;
import com.alibaba.otter.node.common.config.ConfigClientService;
import com.alibaba.otter.shared.arbitrate.impl.config.ArbitrateConfig;
import com.alibaba.otter.shared.arbitrate.impl.config.ArbitrateConfigRegistry;
import com.alibaba.otter.shared.common.model.config.ConfigException;
import com.alibaba.otter.shared.common.model.config.channel.Channel;
import com.alibaba.otter.shared.common.model.config.node.Node;
import com.alibaba.otter.shared.common.model.config.pipeline.Pipeline;
import com.alibaba.otter.shared.common.utils.cache.RefreshMemoryMirror;
import com.alibaba.otter.shared.common.utils.cache.RefreshMemoryMirror.ComputeFunction;
import com.alibaba.otter.shared.communication.model.config.FindChannelEvent;
import com.alibaba.otter.shared.communication.model.config.FindNodeEvent;
import com.google.common.base.Function;
import com.google.common.collect.OtterMigrateMap;

/**
 * task节点对应的config对象管理服务
 *
 * @author jianghang
 */
public class ConfigClientServiceImpl implements InternalConfigClientService, ArbitrateConfig, InitializingBean {

    private static final String                NID_NAME       = "nid";
    private static final Long                  DEFAULT_PERIOD = 60 * 1000L;
    private static final Logger                logger         = LoggerFactory.getLogger(ConfigClientService.class);

    private Long                               timeout        = DEFAULT_PERIOD;
    private Long                               nid;
    private NodeCommmunicationClient           nodeCommmunicationClient;
    private RefreshMemoryMirror<Long, Channel> channelCache;
    private Map<Long, Long>                    channelMapping;                                                     // 将pipelineId映射为channelId
    private RefreshMemoryMirror<Long, Node>    nodeCache;

    public ConfigClientServiceImpl(){
        // 注册一下事件处理
        ArbitrateConfigRegistry.regist(this);
    }

    public Node currentNode() {
        Node node = nodeCache.get(nid);
        if (node == null) {
            throw new ConfigException("nid:" + nid + " in manager[" + nodeCommmunicationClient.getManagerAddress()
                                      + "]is not found!");
        }

        return node;
    }

    public Channel findChannel(Long channelId) {
        return channelCache.get(channelId);
    }

    public Channel findChannelByPipelineId(Long pipelineId) {
        Long channelId = channelMapping.get(pipelineId);
        return channelCache.get(channelId);
    }

    public Pipeline findOppositePipeline(Long pipelineId) {
        Long channelId = channelMapping.get(pipelineId);
        Channel channel = channelCache.get(channelId);
        List<Pipeline> pipelines = channel.getPipelines();
        for (Pipeline pipeline : pipelines) {
            if (pipeline.getId().equals(pipelineId) == false) {// 这里假定pipeline只有两个
                return pipeline;
            }
        }

        return null;
    }

    public Pipeline findPipeline(Long pipelineId) {
        Long channelId = channelMapping.get(pipelineId);
        Channel channel = channelCache.get(channelId);
        List<Pipeline> pipelines = channel.getPipelines();
        for (Pipeline pipeline : pipelines) {
            if (pipeline.getId().equals(pipelineId)) {
                return pipeline;
            }
        }

        throw new ConfigException("no pipeline for pipelineId[" + pipelineId + "]");
    }

    public Node findNode(Long nid) {
        return nodeCache.get(nid);
    }

    public void afterPropertiesSet() throws Exception {
        // 获取一下nid变量
        String nid = System.getProperty(NID_NAME);
        if (StringUtils.isEmpty(nid)) {
            throw new ConfigException("nid is not set!");
        }

        this.nid = Long.valueOf(nid);

        channelMapping = OtterMigrateMap.makeComputingMap(new Function<Long, Long>() {

            public Long apply(Long pipelineId) {
                // 处理下pipline -> channel映射关系不存在的情况
                FindChannelEvent event = new FindChannelEvent();
                event.setPipelineId(pipelineId);
                try {
                    Object obj = nodeCommmunicationClient.callManager(event);
                    if (obj != null && obj instanceof Channel) {
                        Channel channel = (Channel) obj;
                        updateMapping(channel, pipelineId);// 排除下自己
                        channelCache.put(channel.getId(), channel);// 更新下channelCache
                        return channel.getId();
                    }
                } catch (Exception e) {
                    logger.error("call_manager_error", event.toString(), e);
                }

                throw new ConfigException("No Such Channel by pipelineId[" + pipelineId + "]");
            }
        });

        nodeCache = new RefreshMemoryMirror<Long, Node>(timeout, new ComputeFunction<Long, Node>() {

            public Node apply(Long key, Node oldValue) {
                FindNodeEvent event = new FindNodeEvent();
                event.setNid(key);
                try {
                    Object obj = nodeCommmunicationClient.callManager(event);
                    if (obj != null && obj instanceof Node) {
                        return (Node) obj;
                    } else {
                        throw new ConfigException("No Such Node by id[" + key + "]");
                    }
                } catch (Exception e) {
                    logger.error("call_manager_error", event.toString(), e);
                }
                // 其他情况直接返回内存中的旧值
                return oldValue;
            }
        });

        channelCache = new RefreshMemoryMirror<Long, Channel>(timeout, new ComputeFunction<Long, Channel>() {

            public Channel apply(Long key, Channel oldValue) {
                FindChannelEvent event = new FindChannelEvent();
                event.setChannelId(key);
                try {
                    Object obj = nodeCommmunicationClient.callManager(event);
                    if (obj != null && obj instanceof Channel) {
                        updateMapping((Channel) obj, null);// 排除下自己
                        return (Channel) obj;
                    } else {
                        throw new ConfigException("No Such Channel by pipelineId[" + key + "]");
                    }
                } catch (Exception e) {
                    logger.error("call_manager_error", event.toString(), e);
                }
                // 其他情况直接返回内存中的旧值
                return oldValue;
            }
        });
    }

    public void createOrUpdateChannel(Channel channel) {
        channelCache.put(channel.getId(), channel);
        updateMapping(channel, null);
    }

    private void updateMapping(Channel channel, Long excludeId) {
        Long channelId = channel.getId();
        List<Pipeline> pipelines = channel.getPipelines();
        for (Pipeline pipeline : pipelines) {
            if (excludeId == null || !pipeline.getId().equals(excludeId)) {
                channelMapping.put(pipeline.getId(), channelId);
            }
        }
    }

    // =================== setter / getter ======================

    public void setNodeCommmunicationClient(NodeCommmunicationClient nodeCommmunicationClient) {
        this.nodeCommmunicationClient = nodeCommmunicationClient;
    }

    public void setTimeout(Long timeout) {
        this.timeout = timeout;
    }

}


text:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace LiveStreamDownloader
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    }
}


text:
#ifndef API_RTPPARAMETERS_H_
#define API_RTPPARAMETERS_H_

#include <string>
#include <unordered_map>
#include <vector>

#include BOSS_WEBRTC_U_api__mediatypes_h //original-code:"api/mediatypes.h"
#include BOSS_WEBRTC_U_api__optional_h //original-code:"api/optional.h"

namespace webrtc {

// These structures are intended to mirror those defined by:
// http://draft.ortc.org/#rtcrtpdictionaries*
// Contains everything specified as of 2017 Jan 24.
//
// They are used when retrieving or modifying the parameters of an
// RtpSender/RtpReceiver, or retrieving capabilities.
//
// Note on conventions: Where ORTC may use "octet", "short" and "unsigned"
// types, we typically use "int", in keeping with our style guidelines. The
// parameter's actual valid range will be enforced when the parameters are set,
// rather than when the parameters struct is built. An exception is made for
// SSRCs, since they use the full unsigned 32-bit range, and aren't expected to
// be used for any numeric comparisons/operations.
//
// Additionally, where ORTC uses strings, we may use enums for things that have
// a fixed number of supported values. However, for things that can be extended
// (such as codecs, by providing an external encoder factory), a string
// identifier is used.

enum class FecMechanism {
  RED,
  RED_AND_ULPFEC,
  FLEXFEC,
};

// Used in RtcpFeedback struct.
enum class RtcpFeedbackType {
  CCM,
  NACK,
  REMB,  // "goog-remb"
  TRANSPORT_CC,
};

// Used in RtcpFeedback struct when type is NACK or CCM.
enum class RtcpFeedbackMessageType {
  // Equivalent to {type: "nack", parameter: undefined} in ORTC.
  GENERIC_NACK,
  PLI,  // Usable with NACK.
  FIR,  // Usable with CCM.
};

enum class DtxStatus {
  DISABLED,
  ENABLED,
};

enum class DegradationPreference {
  MAINTAIN_FRAMERATE,
  MAINTAIN_RESOLUTION,
  BALANCED,
};

extern const double kDefaultBitratePriority;

struct RtcpFeedback {
  RtcpFeedbackType type = RtcpFeedbackType::CCM;

  // Equivalent to ORTC "parameter" field with slight differences:
  // 1. It's an enum instead of a string.
  // 2. Generic NACK feedback is represented by a GENERIC_NACK message type,
  //    rather than an unset "parameter" value.
  rtc::Optional<RtcpFeedbackMessageType> message_type;

  // Constructors for convenience.
  RtcpFeedback();
  explicit RtcpFeedback(RtcpFeedbackType type);
  RtcpFeedback(RtcpFeedbackType type, RtcpFeedbackMessageType message_type);
  ~RtcpFeedback();

  bool operator==(const RtcpFeedback& o) const {
    return type == o.type && message_type == o.message_type;
  }
  bool operator!=(const RtcpFeedback& o) const { return !(*this == o); }
};

// RtpCodecCapability is to RtpCodecParameters as RtpCapabilities is to
// RtpParameters. This represents the static capabilities of an endpoint's
// implementation of a codec.
struct RtpCodecCapability {
  RtpCodecCapability();
  ~RtpCodecCapability();

  // Build MIME "type/subtype" string from |name| and |kind|.
  std::string mime_type() const { return MediaTypeToString(kind) + "/" + name; }

  // Used to identify the codec. Equivalent to MIME subtype.
  std::string name;

  // The media type of this codec. Equivalent to MIME top-level type.
  cricket::MediaType kind = cricket::MEDIA_TYPE_AUDIO;

  // Clock rate in Hertz. If unset, the codec is applicable to any clock rate.
  rtc::Optional<int> clock_rate;

  // Default payload type for this codec. Mainly needed for codecs that use
  // that have statically assigned payload types.
  rtc::Optional<int> preferred_payload_type;

  // Maximum packetization time supported by an RtpReceiver for this codec.
  // TODO(deadbeef): Not implemented.
  rtc::Optional<int> max_ptime;

  // Preferred packetization time for an RtpReceiver or RtpSender of this
  // codec.
  // TODO(deadbeef): Not implemented.
  rtc::Optional<int> ptime;

  // The number of audio channels supported. Unused for video codecs.
  rtc::Optional<int> num_channels;

  // Feedback mechanisms supported for this codec.
  std::vector<RtcpFeedback> rtcp_feedback;

  // Codec-specific parameters that must be signaled to the remote party.
  //
  // Corresponds to "a=fmtp" parameters in SDP.
  //
  // Contrary to ORTC, these parameters are named using all lowercase strings.
  // This helps make the mapping to SDP simpler, if an application is using
  // SDP. Boolean values are represented by the string "1".
  std::unordered_map<std::string, std::string> parameters;

  // Codec-specific parameters that may optionally be signaled to the remote
  // party.
  // TODO(deadbeef): Not implemented.
  std::unordered_map<std::string, std::string> options;

  // Maximum number of temporal layer extensions supported by this codec.
  // For example, a value of 1 indicates that 2 total layers are supported.
  // TODO(deadbeef): Not implemented.
  int max_temporal_layer_extensions = 0;

  // Maximum number of spatial layer extensions supported by this codec.
  // For example, a value of 1 indicates that 2 total layers are supported.
  // TODO(deadbeef): Not implemented.
  int max_spatial_layer_extensions = 0;

  // Whether the implementation can send/receive SVC layers with distinct
  // SSRCs. Always false for audio codecs. True for video codecs that support
  // scalable video coding with MRST.
  // TODO(deadbeef): Not implemented.
  bool svc_multi_stream_support = false;

  bool operator==(const RtpCodecCapability& o) const {
    return name == o.name && kind == o.kind && clock_rate == o.clock_rate &&
           preferred_payload_type == o.preferred_payload_type &&
           max_ptime == o.max_ptime && ptime == o.ptime &&
           num_channels == o.num_channels && rtcp_feedback == o.rtcp_feedback &&
           parameters == o.parameters && options == o.options &&
           max_temporal_layer_extensions == o.max_temporal_layer_extensions &&
           max_spatial_layer_extensions == o.max_spatial_layer_extensions &&
           svc_multi_stream_support == o.svc_multi_stream_support;
  }
  bool operator!=(const RtpCodecCapability& o) const { return !(*this == o); }
};

// Used in RtpCapabilities; represents the capabilities/preferences of an
// implementation for a header extension.
//
// Just called "RtpHeaderExtension" in ORTC, but the "Capability" suffix was
// added here for consistency and to avoid confusion with
// RtpHeaderExtensionParameters.
//
// Note that ORTC includes a "kind" field, but we omit this because it's
// redundant; if you call "RtpReceiver::GetCapabilities(MEDIA_TYPE_AUDIO)",
// you know you're getting audio capabilities.
struct RtpHeaderExtensionCapability {
  // URI of this extension, as defined in RFC5285.
  std::string uri;

  // Preferred value of ID that goes in the packet.
  rtc::Optional<int> preferred_id;

  // If true, it's preferred that the value in the header is encrypted.
  // TODO(deadbeef): Not implemented.
  bool preferred_encrypt = false;

  // Constructors for convenience.
  RtpHeaderExtensionCapability();
  explicit RtpHeaderExtensionCapability(const std::string& uri);
  RtpHeaderExtensionCapability(const std::string& uri, int preferred_id);
  ~RtpHeaderExtensionCapability();

  bool operator==(const RtpHeaderExtensionCapability& o) const {
    return uri == o.uri && preferred_id == o.preferred_id &&
           preferred_encrypt == o.preferred_encrypt;
  }
  bool operator!=(const RtpHeaderExtensionCapability& o) const {
    return !(*this == o);
  }
};

// RTP header extension, see RFC 5285.
struct RtpExtension {
  RtpExtension();
  RtpExtension(const std::string& uri, int id);
  RtpExtension(const std::string& uri, int id, bool encrypt);
  ~RtpExtension();
  std::string ToString() const;
  bool operator==(const RtpExtension& rhs) const {
    return uri == rhs.uri && id == rhs.id && encrypt == rhs.encrypt;
  }
  static bool IsSupportedForAudio(const std::string& uri);
  static bool IsSupportedForVideo(const std::string& uri);
  // Return "true" if the given RTP header extension URI may be encrypted.
  static bool IsEncryptionSupported(const std::string& uri);

  // Returns the named header extension if found among all extensions,
  // nullptr otherwise.
  static const RtpExtension* FindHeaderExtensionByUri(
      const std::vector<RtpExtension>& extensions,
      const std::string& uri);

  // Return a list of RTP header extensions with the non-encrypted extensions
  // removed if both the encrypted and non-encrypted extension is present for
  // the same URI.
  static std::vector<RtpExtension> FilterDuplicateNonEncrypted(
      const std::vector<RtpExtension>& extensions);

  // Header extension for audio levels, as defined in:
  // http://tools.ietf.org/html/draft-ietf-avtext-client-to-mixer-audio-level-03
  static const char kAudioLevelUri[];
  static const int kAudioLevelDefaultId;

  // Header extension for RTP timestamp offset, see RFC 5450 for details:
  // http://tools.ietf.org/html/rfc5450
  static const char kTimestampOffsetUri[];
  static const int kTimestampOffsetDefaultId;

  // Header extension for absolute send time, see url for details:
  // http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
  static const char kAbsSendTimeUri[];
  static const int kAbsSendTimeDefaultId;

  // Header extension for coordination of video orientation, see url for
  // details:
  // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ts_126114v120700p.pdf
  static const char kVideoRotationUri[];
  static const int kVideoRotationDefaultId;

  // Header extension for video content type. E.g. default or screenshare.
  static const char kVideoContentTypeUri[];
  static const int kVideoContentTypeDefaultId;

  // Header extension for video timing.
  static const char kVideoTimingUri[];
  static const int kVideoTimingDefaultId;

  // Header extension for transport sequence number, see url for details:
  // http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions
  static const char kTransportSequenceNumberUri[];
  static const int kTransportSequenceNumberDefaultId;

  static const char kPlayoutDelayUri[];
  static const int kPlayoutDelayDefaultId;

  // Encryption of Header Extensions, see RFC 6904 for details:
  // https://tools.ietf.org/html/rfc6904
  static const char kEncryptHeaderExtensionsUri[];

  // Inclusive min and max IDs for one-byte header extensions, per RFC5285.
  static const int kMinId;
  static const int kMaxId;

  std::string uri;
  int id = 0;
  bool encrypt = false;
};

// TODO(deadbeef): This is missing the "encrypt" flag, which is unimplemented.
typedef RtpExtension RtpHeaderExtensionParameters;

struct RtpFecParameters {
  // If unset, a value is chosen by the implementation.
  // Works just like RtpEncodingParameters::ssrc.
  rtc::Optional<uint32_t> ssrc;

  FecMechanism mechanism = FecMechanism::RED;

  // Constructors for convenience.
  RtpFecParameters();
  explicit RtpFecParameters(FecMechanism mechanism);
  RtpFecParameters(FecMechanism mechanism, uint32_t ssrc);
  ~RtpFecParameters();

  bool operator==(const RtpFecParameters& o) const {
    return ssrc == o.ssrc && mechanism == o.mechanism;
  }
  bool operator!=(const RtpFecParameters& o) const { return !(*this == o); }
};

struct RtpRtxParameters {
  // If unset, a value is chosen by the implementation.
  // Works just like RtpEncodingParameters::ssrc.
  rtc::Optional<uint32_t> ssrc;

  // Constructors for convenience.
  RtpRtxParameters();
  explicit RtpRtxParameters(uint32_t ssrc);
  ~RtpRtxParameters();

  bool operator==(const RtpRtxParameters& o) const { return ssrc == o.ssrc; }
  bool operator!=(const RtpRtxParameters& o) const { return !(*this == o); }
};

struct RtpEncodingParameters {
  RtpEncodingParameters();
  ~RtpEncodingParameters();

  // If unset, a value is chosen by the implementation.
  //
  // Note that the chosen value is NOT returned by GetParameters, because it
  // may change due to an SSRC conflict, in which case the conflict is handled
  // internally without any event. Another way of looking at this is that an
  // unset SSRC acts as a "wildcard" SSRC.
  rtc::Optional<uint32_t> ssrc;

  // Can be used to reference a codec in the |codecs| member of the
  // RtpParameters that contains this RtpEncodingParameters. If unset, the
  // implementation will choose the first possible codec (if a sender), or
  // prepare to receive any codec (for a receiver).
  // TODO(deadbeef): Not implemented. Implementation of RtpSender will always
  // choose the first codec from the list.
  rtc::Optional<int> codec_payload_type;

  // Specifies the FEC mechanism, if set.
  // TODO(deadbeef): Not implemented. Current implementation will use whatever
  // FEC codecs are available, including red+ulpfec.
  rtc::Optional<RtpFecParameters> fec;

  // Specifies the RTX parameters, if set.
  // TODO(deadbeef): Not implemented with PeerConnection senders/receivers.
  rtc::Optional<RtpRtxParameters> rtx;

  // Only used for audio. If set, determines whether or not discontinuous
  // transmission will be used, if an available codec supports it. If not
  // set, the implementation default setting will be used.
  // TODO(deadbeef): Not implemented. Current implementation will use a CN
  // codec as long as it's present.
  rtc::Optional<DtxStatus> dtx;

  // The relative bitrate priority of this encoding. Currently this is
  // implemented on the sender level (using the first RtpEncodingParameters
  // of the rtp parameters).
  double bitrate_priority = kDefaultBitratePriority;

  // If set, this represents the Transport Independent Application Specific
  // maximum bandwidth defined in RFC3890. If unset, there is no maximum
  // bitrate.
  //
  // Just called "maxBitrate" in ORTC spec.
  //
  // TODO(deadbeef): With ORTC RtpSenders, this currently sets the total
  // bandwidth for the entire bandwidth estimator (audio and video). This is
  // just always how "b=AS" was handled, but it's not correct and should be
  // fixed.
  rtc::Optional<int> max_bitrate_bps;

  // TODO(deadbeef): Not implemented.
  rtc::Optional<int> max_framerate;

  // For video, scale the resolution down by this factor.
  // TODO(deadbeef): Not implemented.
  double scale_resolution_down_by = 1.0;

  // Scale the framerate down by this factor.
  // TODO(deadbeef): Not implemented.
  double scale_framerate_down_by = 1.0;

  // For an RtpSender, set to true to cause this encoding to be sent, and false
  // for it not to be sent. For an RtpReceiver, set to true to cause the
  // encoding to be decoded, and false for it to be ignored.
  // TODO(deadbeef): Not implemented for PeerConnection RtpReceivers.
  bool active = true;

  // Value to use for RID RTP header extension.
  // Called "encodingId" in ORTC.
  // TODO(deadbeef): Not implemented.
  std::string rid;

  // RIDs of encodings on which this layer depends.
  // Called "dependencyEncodingIds" in ORTC spec.
  // TODO(deadbeef): Not implemented.
  std::vector<std::string> dependency_rids;

  bool operator==(const RtpEncodingParameters& o) const {
    return ssrc == o.ssrc && codec_payload_type == o.codec_payload_type &&
           fec == o.fec && rtx == o.rtx && dtx == o.dtx &&
           bitrate_priority == o.bitrate_priority &&
           max_bitrate_bps == o.max_bitrate_bps &&
           max_framerate == o.max_framerate &&
           scale_resolution_down_by == o.scale_resolution_down_by &&
           scale_framerate_down_by == o.scale_framerate_down_by &&
           active == o.active && rid == o.rid &&
           dependency_rids == o.dependency_rids;
  }
  bool operator!=(const RtpEncodingParameters& o) const {
    return !(*this == o);
  }
};

struct RtpCodecParameters {
  RtpCodecParameters();
  ~RtpCodecParameters();

  // Build MIME "type/subtype" string from |name| and |kind|.
  std::string mime_type() const { return MediaTypeToString(kind) + "/" + name; }

  // Used to identify the codec. Equivalent to MIME subtype.
  std::string name;

  // The media type of this codec. Equivalent to MIME top-level type.
  cricket::MediaType kind = cricket::MEDIA_TYPE_AUDIO;

  // Payload type used to identify this codec in RTP packets.
  // This must always be present, and must be unique across all codecs using
  // the same transport.
  int payload_type = 0;

  // If unset, the implementation default is used.
  rtc::Optional<int> clock_rate;

  // The number of audio channels used. Unset for video codecs. If unset for
  // audio, the implementation default is used.
  // TODO(deadbeef): The "implementation default" part isn't fully implemented.
  // Only defaults to 1, even though some codecs (such as opus) should really
  // default to 2.
  rtc::Optional<int> num_channels;

  // The maximum packetization time to be used by an RtpSender.
  // If |ptime| is also set, this will be ignored.
  // TODO(deadbeef): Not implemented.
  rtc::Optional<int> max_ptime;

  // The packetization time to be used by an RtpSender.
  // If unset, will use any time up to max_ptime.
  // TODO(deadbeef): Not implemented.
  rtc::Optional<int> ptime;

  // Feedback mechanisms to be used for this codec.
  // TODO(deadbeef): Not implemented with PeerConnection senders/receivers.
  std::vector<RtcpFeedback> rtcp_feedback;

  // Codec-specific parameters that must be signaled to the remote party.
  //
  // Corresponds to "a=fmtp" parameters in SDP.
  //
  // Contrary to ORTC, these parameters are named using all lowercase strings.
  // This helps make the mapping to SDP simpler, if an application is using
  // SDP. Boolean values are represented by the string "1".
  //
  // TODO(deadbeef): Not implemented with PeerConnection senders/receivers.
  std::unordered_map<std::string, std::string> parameters;

  bool operator==(const RtpCodecParameters& o) const {
    return name == o.name && kind == o.kind && payload_type == o.payload_type &&
           clock_rate == o.clock_rate && num_channels == o.num_channels &&
           max_ptime == o.max_ptime && ptime == o.ptime &&
           rtcp_feedback == o.rtcp_feedback && parameters == o.parameters;
  }
  bool operator!=(const RtpCodecParameters& o) const { return !(*this == o); }
};

// RtpCapabilities is used to represent the static capabilities of an
// endpoint. An application can use these capabilities to construct an
// RtpParameters.
struct RtpCapabilities {
  RtpCapabilities();
  ~RtpCapabilities();

  // Supported codecs.
  std::vector<RtpCodecCapability> codecs;

  // Supported RTP header extensions.
  std::vector<RtpHeaderExtensionCapability> header_extensions;

  // Supported Forward Error Correction (FEC) mechanisms. Note that the RED,
  // ulpfec and flexfec codecs used by these mechanisms will still appear in
  // |codecs|.
  std::vector<FecMechanism> fec;

  bool operator==(const RtpCapabilities& o) const {
    return codecs == o.codecs && header_extensions == o.header_extensions &&
           fec == o.fec;
  }
  bool operator!=(const RtpCapabilities& o) const { return !(*this == o); }
};

// Note that unlike in ORTC, an RtcpParameters structure is not included in
// RtpParameters, because our API includes an additional "RtpTransport"
// abstraction on which RTCP parameters are set.
struct RtpParameters {
  RtpParameters();
  ~RtpParameters();

  // Used when calling getParameters/setParameters with a PeerConnection
  // RtpSender, to ensure that outdated parameters are not unintentionally
  // applied successfully.
  // TODO(deadbeef): Not implemented.
  std::string transaction_id;

  // Value to use for MID RTP header extension.
  // Called "muxId" in ORTC.
  // TODO(deadbeef): Not implemented.
  std::string mid;

  std::vector<RtpCodecParameters> codecs;

  // TODO(deadbeef): Not implemented with PeerConnection senders/receivers.
  std::vector<RtpHeaderExtensionParameters> header_extensions;

  std::vector<RtpEncodingParameters> encodings;

  // TODO(deadbeef): Not implemented.
  DegradationPreference degradation_preference =
      DegradationPreference::BALANCED;

  bool operator==(const RtpParameters& o) const {
    return mid == o.mid && codecs == o.codecs &&
           header_extensions == o.header_extensions &&
           encodings == o.encodings &&
           degradation_preference == o.degradation_preference;
  }
  bool operator!=(const RtpParameters& o) const { return !(*this == o); }
};

}  // namespace webrtc

#endif  // API_RTPPARAMETERS_H_


text:
//
//  RCAddPlayerViewController.m
//  BasketballTeamHelper
//
//  Created by Richard Chien on 14-5-23.
//  Copyright (c) 2014年 Richard Chien. All rights reserved.
//

#import "RCAddPlayerViewController.h"
#import "RCTextFieldWithPicker.h"

@interface RCAddPlayerViewController ()

@end

@implementation RCAddPlayerViewController

@synthesize positionPicker, positions;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.positions = [NSArray arrayWithContentsOfFile:[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Positions.plist"]];
    self.positionText.text = self.positions[0];
    self.positionPicker = [[UIPickerView alloc] init];
    self.positionPicker.backgroundColor = [UIColor whiteColor];
    self.positionPicker.dataSource = self;
    self.positionPicker.delegate = self;
    self.positionText.inputView = self.positionPicker;
    self.positionText.inputAccessoryView = (UIView *)self.inputAccessoryBar;

    self.nameText.inputAccessoryView = (UIView *)self.inputAccessoryBar;
    self.commentText.inputAccessoryView = (UIView *)self.inputAccessoryBar;
    self.commentText.layer.borderColor = [UIColor lightGrayColor].CGColor;
    self.commentText.layer.borderWidth = 0.3;
    self.commentText.layer.cornerRadius = 5.0;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)save:(id)sender
{
    if ([self.nameText.text isEqualToString:@""])
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"球员名字可不能为空哦~"
                                                        message:@"至少把球员的名字填上再保存吧!"
                                                       delegate:nil
                                              cancelButtonTitle:@"知道了"
                                              otherButtonTitles:nil, nil];
        [alert show];
        return;
    }

    RCTeam *team = [[RCTeam alloc] init];
    [team addPlayer:self.nameText.text inPosition:self.positionText.text withComment:self.commentText.text];

    [self dismissViewControllerAnimated:YES completion:nil];
}

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    return [self.positions count];
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    return self.positions[row];
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    self.positionText.text = self.positions[row];
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end


text:
package io.leopard.web.nobug.xss;

public class JsonViewXssUtil {

	// public static void checkXss(Object data) {
	//
	// }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:paddingTop="10dp"
    android:paddingBottom="10dp">

    <TextView
        android:id="@+id/title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="30dp"
        android:textSize="15dp"
        android:textStyle="bold" />
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_below="@id/title"
        android:background="@color/material_grey_600"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="30dp"
        android:id="@+id/separator"
        android:visibility="gone"/>

</RelativeLayout>


text:
'use strict';

var _consoleReporter;

function _load_consoleReporter() {
  return _consoleReporter = _interopRequireDefault(require('./reporters/console/console-reporter'));
}

var _conversion;

function _load_conversion() {
  return _conversion = require('./util/conversion.js');
}

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const defaultOptions = {
  emoji: true,
  peekMemoryCounter: false
};

/**
 * This code is based on yarn src/cli/index.js
 */
function createReporter(options = {}) {
  const reporter = new (_consoleReporter || _load_consoleReporter()).default({
    // $FlowFixMe
    emoji: options.emoji && process.stdout.isTTY,
    verbose: options.verbose,
    noProgress: options.noProgress,
    isSilent: (0, (_conversion || _load_conversion()).boolifyWithDefault)(process.env.YURNALIST_SILENT, false) || options.silent,
    nonInteractive: options.nonInteractive
  });

  if (options.peekMemoryCounter) {
    reporter.initPeakMemoryCounter();
  }

  return reporter;
}

const reporter = createReporter(defaultOptions);

function bindMethods(methods, instance) {
  return methods.reduce((result, name) => {
    try {
      /* $FlowFixMe: Indexible signature not found */
      result[name] = instance[name].bind(instance);
      return result;
    } catch (e) {
      throw new ReferenceError(`Unable to bind method: ${name}`);
    }
  }, {});
}

const boundMethods = bindMethods(['table', 'step', 'inspect', 'list', 'header', 'footer', 'log', 'success', 'error', 'info', 'command', 'warn', 'question', 'tree', 'activitySet', 'activity', 'select', 'progress', 'close', 'lang'], reporter);

module.exports = Object.assign({}, boundMethods, { createReporter });


text:
        Show a report for the specified customer ID using GAQL.

            All reports return the first 100 results retrieved without
            zero-impression
            for the sake of brevity.

        <form action="{{ url('show-report') }}" method="POST">
            {{ csrf_field() }}

                Customer ID

                    <input type="text" class="form-control" id="customerId" name="customerId"
                           aria-describedby="customerIdHelp"
                           placeholder="Enter your customer ID" required>
                    The ID of the
                        customer account to show the report for, e.g., 1234567890.

                    Type
                        See all types
                            here.

                    <select class="form-control" id="reportType" name="reportType">
                        <option selected>campaign</option>
                        <option>customer</option>
                    </select>
                    Some fields
                        specific to the specified type will also be selected. For example,
                        campaign.id and
                        campaign.status will be selected when
                            campaign
                         is specified.

            <fieldset class="form-group">

                    <legend class="col-sm-2 col-form-label pt-0">
                        Metric fields to be retrieved:
                    </legend>

                            <input type="checkbox" class="form-check-input" id="impressions" name="impressions" value="metrics.impressions"
                                   checked>
                            metrics.impressions

                            <input type="checkbox" class="form-check-input" id="clicks" name="clicks" value="metrics.clicks"
                                   checked>
                            metrics.clicks

                            <input type="checkbox" class="form-check-input" id="ctr" name="ctr" value="metrics.ctr"
                                   checked>
                            metrics.ctr

            </fieldset>

                Report date range

                    <select class="form-control" id="reportRange" name="reportRange">
                        <option selected>YESTERDAY</option>
                        <option>LAST_7_DAYS</option>
                        <option>LAST_WEEK_MON_SUN</option>
                        <option>LAST_MONTH</option>
                    </select>

                Number of rows per page

                    <select class="form-control" id="entriesPerPage" name="entriesPerPage">
                        <option selected>20</option>
                        <option>50</option>
                        <option>100</option>
                    </select>

                    <button type="submit" class="btn btn-primary">Show Report</button>

        </form>


text:
@(key:String, title:String, sortBy: String, order: String, link: (Int, String) => play.api.mvc.Call)

	@title


text:
// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/ads/googleads/v10/errors/errors.proto

package com.google.ads.googleads.v10.errors;

public interface ErrorDetailsOrBuilder extends
    // @@protoc_insertion_point(interface_extends:google.ads.googleads.v10.errors.ErrorDetails)
    com.google.protobuf.MessageOrBuilder {

  /**
   *

   * The error code that should have been returned, but wasn't. This is used
   * when the error code is not published in the client specified version.
   *

   *
   * string unpublished_error_code = 1;
   * @return The unpublishedErrorCode.
   */
  java.lang.String getUnpublishedErrorCode();
  /**
   *

   * The error code that should have been returned, but wasn't. This is used
   * when the error code is not published in the client specified version.
   *

   *
   * string unpublished_error_code = 1;
   * @return The bytes for unpublishedErrorCode.
   */
  com.google.protobuf.ByteString
      getUnpublishedErrorCodeBytes();

  /**
   *

   * Describes an ad policy violation.
   *

   *
   * .google.ads.googleads.v10.errors.PolicyViolationDetails policy_violation_details = 2;
   * @return Whether the policyViolationDetails field is set.
   */
  boolean hasPolicyViolationDetails();
  /**
   *

   * Describes an ad policy violation.
   *

   *
   * .google.ads.googleads.v10.errors.PolicyViolationDetails policy_violation_details = 2;
   * @return The policyViolationDetails.
   */
  com.google.ads.googleads.v10.errors.PolicyViolationDetails getPolicyViolationDetails();
  /**
   *

   * Describes an ad policy violation.
   *

   *
   * .google.ads.googleads.v10.errors.PolicyViolationDetails policy_violation_details = 2;
   */
  com.google.ads.googleads.v10.errors.PolicyViolationDetailsOrBuilder getPolicyViolationDetailsOrBuilder();

  /**
   *

   * Describes policy violation findings.
   *

   *
   * .google.ads.googleads.v10.errors.PolicyFindingDetails policy_finding_details = 3;
   * @return Whether the policyFindingDetails field is set.
   */
  boolean hasPolicyFindingDetails();
  /**
   *

   * Describes policy violation findings.
   *

   *
   * .google.ads.googleads.v10.errors.PolicyFindingDetails policy_finding_details = 3;
   * @return The policyFindingDetails.
   */
  com.google.ads.googleads.v10.errors.PolicyFindingDetails getPolicyFindingDetails();
  /**
   *

   * Describes policy violation findings.
   *

   *
   * .google.ads.googleads.v10.errors.PolicyFindingDetails policy_finding_details = 3;
   */
  com.google.ads.googleads.v10.errors.PolicyFindingDetailsOrBuilder getPolicyFindingDetailsOrBuilder();

  /**
   *

   * Details on the quota error, including the scope (account or developer), the
   * rate bucket name and the retry delay.
   *

   *
   * .google.ads.googleads.v10.errors.QuotaErrorDetails quota_error_details = 4;
   * @return Whether the quotaErrorDetails field is set.
   */
  boolean hasQuotaErrorDetails();
  /**
   *

   * Details on the quota error, including the scope (account or developer), the
   * rate bucket name and the retry delay.
   *

   *
   * .google.ads.googleads.v10.errors.QuotaErrorDetails quota_error_details = 4;
   * @return The quotaErrorDetails.
   */
  com.google.ads.googleads.v10.errors.QuotaErrorDetails getQuotaErrorDetails();
  /**
   *

   * Details on the quota error, including the scope (account or developer), the
   * rate bucket name and the retry delay.
   *

   *
   * .google.ads.googleads.v10.errors.QuotaErrorDetails quota_error_details = 4;
   */
  com.google.ads.googleads.v10.errors.QuotaErrorDetailsOrBuilder getQuotaErrorDetailsOrBuilder();

  /**
   *

   * Details for a resource count limit exceeded error.
   *

   *
   * .google.ads.googleads.v10.errors.ResourceCountDetails resource_count_details = 5;
   * @return Whether the resourceCountDetails field is set.
   */
  boolean hasResourceCountDetails();
  /**
   *

   * Details for a resource count limit exceeded error.
   *

   *
   * .google.ads.googleads.v10.errors.ResourceCountDetails resource_count_details = 5;
   * @return The resourceCountDetails.
   */
  com.google.ads.googleads.v10.errors.ResourceCountDetails getResourceCountDetails();
  /**
   *

   * Details for a resource count limit exceeded error.
   *

   *
   * .google.ads.googleads.v10.errors.ResourceCountDetails resource_count_details = 5;
   */
  com.google.ads.googleads.v10.errors.ResourceCountDetailsOrBuilder getResourceCountDetailsOrBuilder();
}