text:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Tagging;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Editor.Shared.Tagging
{
    /// <summary>
    /// Async thin tagger implementation.
    ///
    /// Actual tag information is stored in TagSource and shared between multiple taggers created for same views or buffers.
    ///
    /// It's responsibility is on interfaction between host and tagger. TagSource has responsibility on how to provide information for this tagger.
    /// </summary>
    internal sealed partial class AsynchronousTagger<TTag> : ITagger<TTag>, IDisposable
        where TTag : ITag
    {
        private const int MaxNumberOfRequestedSpans = 100;

        #region Fields that can be accessed from either thread

        private readonly ITextBuffer _subjectBuffer;
        private readonly TagSource<TTag> _tagSource;
        private readonly int _uiUpdateDelayInMS;

        #endregion

        #region Fields that can only be accessed from the foreground thread

        /// <summary>
        /// The batch change notifier that we use to throttle update to the UI.
        /// </summary>
        private readonly BatchChangeNotifier _batchChangeNotifier;

        #endregion

        public event EventHandler<SnapshotSpanEventArgs> TagsChanged;

        public AsynchronousTagger(
            IAsynchronousOperationListener listener,
            IForegroundNotificationService notificationService,
            TagSource<TTag> tagSource,
            ITextBuffer subjectBuffer,
            TimeSpan uiUpdateDelay)
        {
            Contract.ThrowIfNull(subjectBuffer);

            _subjectBuffer = subjectBuffer;
            _uiUpdateDelayInMS = (int)uiUpdateDelay.TotalMilliseconds;

            _batchChangeNotifier = new BatchChangeNotifier(subjectBuffer, listener, notificationService, ReportChangedSpan);

            _tagSource = tagSource;

            _tagSource.OnTaggerAdded(this);
            _tagSource.TagsChangedForBuffer += OnTagsChangedForBuffer;
            _tagSource.Paused += OnPaused;
            _tagSource.Resumed += OnResumed;
        }

        public void Dispose()
        {
            _tagSource.Resumed -= OnResumed;
            _tagSource.Paused -= OnPaused;
            _tagSource.TagsChangedForBuffer -= OnTagsChangedForBuffer;
            _tagSource.OnTaggerDisposed(this);
        }

        private void ReportChangedSpan(SnapshotSpan changeSpan)
        {
            var tagsChanged = TagsChanged;
            if (tagsChanged != null)
            {
                tagsChanged(this, new SnapshotSpanEventArgs(changeSpan));
            }
        }

        private void OnPaused(object sender, EventArgs e)
        {
            _batchChangeNotifier.Pause();
        }

        private void OnResumed(object sender, EventArgs e)
        {
            _batchChangeNotifier.Resume();
        }

        private void OnTagsChangedForBuffer(object sender, TagsChangedForBufferEventArgs args)
        {
            if (args.Buffer != _subjectBuffer)
            {
                return;
            }

            // Note: This operation is uncancellable. Once we've been notified here, our cached tags
            // in the tag source are new. If we don't update the UI of the editor then we will end
            // up in an inconsistent state between us and the editor where we have new tags but the
            // editor will never know.
            var spansChanged = args.Spans;

            _tagSource.RegisterNotification(() =>
            {
                _tagSource.WorkQueue.AssertIsForeground();

                // Now report them back to the UI on the main thread.
                _batchChangeNotifier.EnqueueChanges(spansChanged.First().Snapshot, spansChanged);
            }, _uiUpdateDelayInMS, CancellationToken.None);
        }

        public IEnumerable<ITagSpan<TTag>> GetTags(NormalizedSnapshotSpanCollection requestedSpans)
        {
            if (requestedSpans.Count == 0)
            {
                return SpecializedCollections.EmptyEnumerable<ITagSpan<TTag>>();
            }

            var buffer = requestedSpans.First().Snapshot.TextBuffer;
            var tags = _tagSource.GetTagIntervalTreeForBuffer(buffer);

            if (tags == null)
            {
                return SpecializedCollections.EmptyEnumerable<ITagSpan<TTag>>();
            }

            var result = GetTags(requestedSpans, tags);

            DebugVerifyTags(requestedSpans, result);

            return result;
        }

        private static IEnumerable<ITagSpan<TTag>> GetTags(NormalizedSnapshotSpanCollection requestedSpans, ITagSpanIntervalTree<TTag> tags)
        {
            // Special case the case where there is only one requested span.  In that case, we don't
            // need to allocate any intermediate collections
            return requestedSpans.Count == 1
                ? tags.GetIntersectingSpans(requestedSpans[0])
                : requestedSpans.Count < MaxNumberOfRequestedSpans
                    ? GetTagsForSmallNumberOfSpans(requestedSpans, tags)
                    : GetTagsForLargeNumberOfSpans(requestedSpans, tags);
        }

        private static IEnumerable<ITagSpan<TTag>> GetTagsForSmallNumberOfSpans(
            NormalizedSnapshotSpanCollection requestedSpans,
            ITagSpanIntervalTree<TTag> tags)
        {
            var result = new List<ITagSpan<TTag>>();

            foreach (var s in requestedSpans)
            {
                result.AddRange(tags.GetIntersectingSpans(s));
            }

            return result;
        }

        private static IEnumerable<ITagSpan<TTag>> GetTagsForLargeNumberOfSpans(
            NormalizedSnapshotSpanCollection requestedSpans,
            ITagSpanIntervalTree<TTag> tags)
        {
            // we are asked with bunch of spans. rather than asking same question again and again, ask once with big span
            // which will return superset of what we want. and then filter them out in O(m+n) cost.
            // m == number of requested spans, n = number of returned spans
            var mergedSpan = new SnapshotSpan(requestedSpans[0].Start, requestedSpans[requestedSpans.Count - 1].End);
            var result = tags.GetIntersectingSpans(mergedSpan);

            int requestIndex = 0;

            var enumerator = result.GetEnumerator();

            try
            {
                if (!enumerator.MoveNext())
                {
                    return SpecializedCollections.EmptyEnumerable<ITagSpan<TTag>>();
                }

                var hashSet = new HashSet<ITagSpan<TTag>>();
                while (true)
                {
                    var currentTag = enumerator.Current;

                    var currentRequestSpan = requestedSpans[requestIndex];
                    var currentTagSpan = currentTag.Span;

                    if (currentRequestSpan.Start > currentTagSpan.End)
                    {
                        if (!enumerator.MoveNext())
                        {
                            break;
                        }
                    }
                    else if (currentTagSpan.Start > currentRequestSpan.End)
                    {
                        requestIndex++;

                        if (requestIndex >= requestedSpans.Count)
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (currentTagSpan.Length > 0)
                        {
                            hashSet.Add(currentTag);
                        }

                        if (!enumerator.MoveNext())
                        {
                            break;
                        }
                    }
                }

                return hashSet;
            }
            finally
            {
                enumerator.Dispose();
            }
        }

        [Conditional("DEBUG")]
        private static void DebugVerifyTags(NormalizedSnapshotSpanCollection requestedSpans, IEnumerable<ITagSpan<TTag>> tags)
        {
            if (tags == null)
            {
                return;
            }

            foreach (var tag in tags)
            {
                var span = tag.Span;

                if (!requestedSpans.Any(s => s.IntersectsWith(span)))
                {
                    Contract.Fail(tag + " doesn't intersects with any requested span");
                }
            }
        }
    }
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace WifiManager
{
	/// <summary>
	/// This class is used to get info about the available network profiles,
	/// on the current machine and the profiles stored in the ./data/conf directory
	/// </summary>
	class ProfileInfo
	{
		/// <summary>
		/// Calls IOHandler.GetStoredConfigFielNames() and filters out the interface name and file extension,
		/// and returns a String List with the profile names
		/// </summary>
		/// <returns>A String List with stored profile names</returns>
		public List<String> GetStoredProfileList()
		{
			XmlReader xmlReader = new XmlReader();

			List<String> returnBuilder = new List<String>();
			foreach(string s in IOHandler.GetStoredConfigFilesWithPath())
			{
				// Match match = Regex.Match(s, @"(?:^\w+-)(.*)(?:\.xml$)", RegexOptions.IgnoreCase);
				// returnBuilder.Add(match.Groups[1].Value);

				returnBuilder.Add(xmlReader.GetProfileName(s));
			}
			return returnBuilder;
		}

		/// <summary>
		/// Gets the output from GetNetshWlanProfiles() uses regex to get the network profile names,
		/// and returns a list of the available network profiles on the current machine
		/// </summary>
		/// <returns>A string list with local network profile names</returns>
		public List<String> GetLocalProfileList()
		{
			// Get the netsh wlan profiles
			string netshOutput = GetNetshWlanProfiles();
			List<string> wifiList = new List<string>();

			// Find all the AP names and put them into the wifiList
			MatchCollection matches = Regex.Matches(netshOutput, @"(?::\s)(.*)", RegexOptions.IgnoreCase);
            foreach (Match m in matches)
			{
				if (m.Groups[1].Value.Length > 1)
					wifiList.Add(m.Groups[1].Value);
			}
			// Return a list with no duplicate profiles
			// In case of multiple Wifi cards
			return wifiList.Distinct().ToList();
		}

		/// <summary>
		/// Runs a netsh command to get all the network profiles on the current machine
		/// </summary>
		/// <returns>Raw output from the cmd command</returns>
		public string GetNetshWlanProfiles()
		{
			System.Diagnostics.Process proc = new System.Diagnostics.Process();
			proc.StartInfo.FileName = "cmd.exe";
			proc.StartInfo.Arguments = "/c netsh wlan show profiles";
			proc.StartInfo.UseShellExecute = false;
			proc.StartInfo.CreateNoWindow = true;
			proc.StartInfo.RedirectStandardOutput = true;
			proc.Start();
			string s = proc.StandardOutput.ReadToEnd();
			proc.WaitForExit();
			return s;
		}
	}
}

redpajama_set_name: RedPajamaGithub


text:
using System;
using UnityEngine;
using OneLine;

namespace OneLine.Examples {
[CreateAssetMenu(menuName = "OneLine/HighlightExample")]
public class HighlightExample : ScriptableObject {
    [SerializeField, OneLine, Highlight]
    private string rootField;
    [SerializeField, OneLine]
    private HighlightedFields nestedFields;

    [Serializable]
    public class HighlightedFields {
        [SerializeField, Highlight(0, 1, 0)]
        private string first;
        [SerializeField, Highlight(0, 0, 1)]
        private string second;
        [SerializeField]
        private string third;
        [SerializeField, Highlight(1, 1, 0)]
        private string fourth;
    }
}
}


text:
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System.Windows;
using System.Windows.Data;

#if WINDOWS_PHONE
namespace Microsoft.Phone.Controls
#else
namespace System.Windows.Controls
#endif
{
    /// <summary>
    /// A framework element that permits a binding to be evaluated in a new data
    /// context leaf node.
    /// </summary>
    /// <typeparam name="T">The type of dynamic binding to return.</typeparam>
    internal partial class BindingEvaluator<T> : FrameworkElement
    {
        /// <summary>
        /// Gets or sets the string value binding used by the control.
        /// </summary>
        private Binding _binding;

        #region public T Value
        /// <summary>
        /// Gets or sets the data item string value.
        /// </summary>
        public T Value
        {
            get { return (T)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        /// <summary>
        /// Identifies the Value dependency property.
        /// </summary>
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register(
                "Value",
                typeof(T),
                typeof(BindingEvaluator<T>),
                new PropertyMetadata(default(T)));

        #endregion public string Value

        /// <summary>
        /// Gets or sets the value binding.
        /// </summary>
        public Binding ValueBinding
        {
            get { return _binding; }
            set
            {
                _binding = value;
                SetBinding(ValueProperty, _binding);
            }
        }

        /// <summary>
        /// Initializes a new instance of the BindingEvaluator class.
        /// </summary>
        public BindingEvaluator()
        {
        }

        /// <summary>
        /// Initializes a new instance of the BindingEvaluator class,
        /// setting the initial binding to the provided parameter.
        /// </summary>
        /// <param name="binding">The initial string value binding.</param>
        public BindingEvaluator(Binding binding)
        {
            SetBinding(ValueProperty, binding);
        }

        /// <summary>
        /// Clears the data context so that the control does not keep a
        /// reference to the last-looked up item.
        /// </summary>
        public void ClearDataContext()
        {
            DataContext = null;
        }

        /// <summary>
        /// Updates the data context of the framework element and returns the
        /// updated binding value.
        /// </summary>
        /// <param name="o">The object to use as the data context.</param>
        /// <param name="clearDataContext">If set to true, this parameter will
        /// clear the data context immediately after retrieving the value.</param>
        /// <returns>Returns the evaluated T value of the bound dependency
        /// property.</returns>
        public T GetDynamicValue(object o, bool clearDataContext)
        {
            DataContext = o;
            T value = Value;
            if (clearDataContext)
            {
                DataContext = null;
            }
            return value;
        }

        /// <summary>
        /// Updates the data context of the framework element and returns the
        /// updated binding value.
        /// </summary>
        /// <param name="o">The object to use as the data context.</param>
        /// <returns>Returns the evaluated T value of the bound dependency
        /// property.</returns>
        public T GetDynamicValue(object o)
        {
            DataContext = o;
            return Value;
        }
    }
}


text:
package cmd

import (
	bosherr "github.com/cloudfoundry/bosh-utils/errors"
	boshuuid "github.com/cloudfoundry/bosh-utils/uuid"

	boshdir "github.com/cloudfoundry/bosh-init/director"
	boshssh "github.com/cloudfoundry/bosh-init/ssh"
	biui "github.com/cloudfoundry/bosh-init/ui"
)

type SCPCmd struct {
	deployment boshdir.Deployment
	uuidGen    boshuuid.Generator
	scpRunner  boshssh.SCPRunner
	ui         biui.UI
}

func NewSCPCmd(
	deployment boshdir.Deployment,
	uuidGen boshuuid.Generator,
	scpRunner boshssh.SCPRunner,
	ui biui.UI,
) SCPCmd {
	return SCPCmd{
		deployment: deployment,
		uuidGen:    uuidGen,
		scpRunner:  scpRunner,
		ui:         ui,
	}
}

func (c SCPCmd) Run(opts SCPOpts) error {
	scpArgs := boshssh.NewSCPArgs(opts.Args.Paths, opts.Recursive)

	slug, err := scpArgs.AllOrPoolOrInstanceSlug()
	if err != nil {
		return err
	}

	sshOpts, privKey, err := boshdir.NewSSHOpts(c.uuidGen)
	if err != nil {
		return bosherr.WrapErrorf(err, "Generating SSH options")
	}

	connOpts := boshssh.ConnectionOpts{
		PrivateKey: privKey,

		GatewayDisable: opts.GatewayFlags.Disable,

		GatewayUsername:       opts.GatewayFlags.Username,
		GatewayHost:           opts.GatewayFlags.Host,
		GatewayPrivateKeyPath: opts.GatewayFlags.PrivateKeyPath,
	}

	result, err := c.deployment.SetUpSSH(slug, sshOpts)
	if err != nil {
		return err
	}

	defer func() {
		_ = c.deployment.CleanUpSSH(slug, sshOpts)
	}()

	err = c.scpRunner.Run(connOpts, result, scpArgs)
	if err != nil {
		return bosherr.WrapErrorf(err, "Running SCP")
	}

	return nil
}


text:
package ru.job4j.calculator;

import org.junit.Test;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

/**
* Test.
*
* @author Sergey Indyukov (mailto:onl.ont@mail.ri)
* @version $Id$
* @since 0.1
*/

public class CalculatorTest {
/**
* Test add.
*/
@Test
public void whenAddOnePlusOneThenTwo() {
        Calculator calc = new Calculator();
        calc.add(1D, 1D);
        double result = calc.getResult();
        double expected = 2D;
        assertThat(result, is(expected));
    }
/**
* Test substruct.
*/
public void whenSubstructOneMinusOneThenZero() {
        Calculator calc = new Calculator();
        calc.add(1D, 1D);
        double result = calc.getResult();
        double expected = 0D;
        assertThat(result, is(expected));
    }
/**
* Test div.
*/
public void whenDivOneDivOneThenOne() {
        Calculator calc = new Calculator();
        calc.add(1D, 1D);
        double result = calc.getResult();
        double expected = 1D;
        assertThat(result, is(expected));
    }
/**
* Test multiple.
*/
public void whenMultipleOneMultipleOneThenOne() {
Calculator calc = new Calculator();
calc.add(1D, 1D);
double result = calc.getResult();
double expected = 1D;
assertThat(result, is(expected));
}
}


text:
import {Logger} from './lib/log';
import {ConfigLoader} from './lib/config';

export {Logger, ConfigLoader};


text:
/* global chai */
/* global describe */
/* global sinon */
/* global it */

var React = require('react');
var TestUtils = require('react-addons-test-utils');
var expect = chai.expect;

var Messages = require('../../../../app/components/messages/messages');

describe('Messages', function () {
  it('should be exposed as a module and be of type function', function() {
    expect(Messages).to.be.a('function');
  });

  describe('render', function() {
    it('should render without problems when required props are present', function () {
      console.error = sinon.stub();
      var props = {
        timePrefs: {}
      };
      var elem = React.createElement(Messages, props);
      var render = TestUtils.renderIntoDocument(elem);
      expect(render).to.be.ok;
      expect(console.error.callCount).to.equal(0);
    });
  });

  describe('getInitialState', function() {
    it('should equal expected initial state', function() {
      var props = {
        messages : []
      };
      var elem = React.createElement(Messages, props);
      var render = TestUtils.renderIntoDocument(elem);
      var state = render.getWrappedInstance().getInitialState();

      expect(state.messages).to.deep.equal(props.messages);
    });
  });
});


text:
@interface DetailViewController : UIViewController <MFMailComposeViewControllerDelegate> {

           UIView *myview;
           UIWebView *detailWebView;
           NSURL *detailURL;
           UIActivityIndicatorView *activity;
           NSString *tweetcontent;
           UIToolbar *bottomBar;
           UIBarButtonItem *item;
           // int nbtweet;

}

@property (nonatomic,retain) NSURL *detailURL;
@property (nonatomic,retain) NSString *tweetcontent;
@property (nonatomic, retain) IBOutlet UIWebView *detailWebView;
@property (nonatomic, retain) IBOutlet UIView *myview;
@property (nonatomic, retain) IBOutlet UIActivityIndicatorView *activity;
@property (nonatomic, retain) IBOutlet UIToolbar *bottomBar;
@property (nonatomic, retain) IBOutlet UIBarButtonItem *item;

-(void)AddtoFavorites;
-(void)sendEmail:(id)sender;

@end


text:
package com.jfinalshop.validator.admin;

import com.jfinal.core.Controller;
import com.jfinal.validate.Validator;
import com.jfinalshop.model.Admin;
import com.jfinalshop.model.Role;

public class AdminValidator extends Validator {

	@Override
	protected void validate(Controller c) {
		validateRequiredString("admin.username", "usernameMessages", "用户名不允许为空!");
		validateRequiredString("admin.email", "emailMessages", "E-mail不允许为空!");
		validateRequiredString("admin.isAccountEnabled", "isAccountEnabledMessages", "是否启用不允许为空!");
		validateString("admin.username", 2, 20, "usernameMessages", "用户名长度必须在【2】到【20】之间!");
		validateEmail("admin.email", "emailMessages", "E-mail格式错误!");
		//\u4e00-\u9fa5  匹配中文
        validateRegex("admin.username", "^[0-9a-z_A-Z\u4e00-\u9fa5]+$", "usernameMessages", "用户名只允许包含中文、英文、数字和下划线!");
        // 更新为空不更新密码
        String actionKey = getActionKey();
        if (!actionKey.equals("/admin/update")) {
			validateRequiredString("admin.password", "passwordMessages", "密码不允许为空!");
			validateEqualField("admin.password", "rePassword", "rePasswordMessages", "两次密码输入不一致!");
			validateString("admin.password", 4, 20, "passwordMessages", "密码长度必须在【4】到【20】之间!");
		}
        String newValue = c.getPara("admin.username","");
        Admin newAdmin = Admin.dao.getAdminByUsername(newValue);
		if (newAdmin != null && !newAdmin.get("id").toString().equals(c.getPara("admin.id",""))) {//TODO:SUN.AO 对于修改的情况需要排除自身
			addError("usernameMessages","用户名称已存在!");
		}

	}

	@Override
	protected void handleError(Controller c) {
		c.keepModel(Admin.class);
		c.setAttr("allRole", Role.dao.getAllRole());
		c.render("/admin/admin_input.html");
	}
}


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Comm. fung. clav. (Lipsiae) 23 (1797)

#### Original name
Hydnum clathroides Pall., 1773

### Remarks
null


text:
package ma.glasnost.orika.test.filters;

import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.junit.Assert;
import org.junit.Test;

/**
 * @author: Ilya Krokhmalyov
 * @email jad7kii@gmail.com
 * @since: 5/6/14
 */

public class SourceNestedFilterTest {

    public static class A_Source {
       private A1_Source a1_source;

        public A1_Source getA1_source() {
            return a1_source;
        }

        public void setA1_source(A1_Source a1_source) {
            this.a1_source = a1_source;
        }
    }

    public static class A1_Source {
        private Integer id;

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }
    }

    public static class A_Destination {
        private Integer id;

        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }
    }

    @Test
    public void test() {
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().captureFieldContext(true).build();

        mapperFactory.classMap(A_Source.class, A_Destination.class)
                .field("a1_source.id", "id")
                .register();

        A_Source a_source = new A_Source();
        a_source.a1_source = new A1_Source();
        a_source.a1_source.id = 10;

        A_Destination map = mapperFactory.getMapperFacade().map(a_source, A_Destination.class);
        Assert.assertEquals(map.getId(), Integer.valueOf(10));
    }
}


text:
Via Composer

```
$ composer install
```

### Run sample

```
$ php sample.php
```

The application will output a few encoding results for

* a resource with no relationships
* a resource with included relationships
* sparse and field set filters usage sample
* top level links and meta information usage sample

For more details see [the app source code](sample.php)

## Performance test

This application includes performance test as well. It can be run with default parameters

```
$ php sample.php -t
```

or with execution time measurement and specified number of iterations

```
$ time php sample.php -t=10000
```

If your system has debug assertions enabled it is recommended to turn them off. Just to give you an idea that debug assert are not free here is the execution time comparison

|Debug asserts mode   |Command                                           |Execution time|
|---------------------|--------------------------------------------------|--------------|
|Enabled              |```$ php -d assert.active=1 sample.php -t=10000```|7.589s        |
|Disabled             |```$ php -d assert.active=0 sample.php -t=10000```|2.884s        |


text:
package org.kuali.kpme.core.accrualcategory.dao;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.query.QueryFactory;
import org.apache.ojb.broker.query.ReportQueryByCriteria;
import org.joda.time.LocalDate;
import org.kuali.kpme.core.accrualcategory.AccrualCategoryBo;
import org.kuali.kpme.core.util.OjbSubQueryUtil;
import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb;

public class AccrualCategoryDaoOjbImpl extends PlatformAwareDaoBaseOjb implements AccrualCategoryDao {

    @Override
    public AccrualCategoryBo getAccrualCategory(String accrualCategory, LocalDate asOfDate) {
    	AccrualCategoryBo accrlCategory = null;
		Criteria root = new Criteria();

        root.addEqualTo("accrualCategory", accrualCategory);
		root.addEqualTo("active",true);
        root.addEqualTo("effectiveDate", OjbSubQueryUtil.getEffectiveDateSubQuery(AccrualCategoryBo.class, asOfDate, AccrualCategoryBo.BUSINESS_KEYS, false));
        root.addEqualTo("timestamp", OjbSubQueryUtil.getTimestampSubQuery(AccrualCategoryBo.class, AccrualCategoryBo.BUSINESS_KEYS, false));

		Query query = QueryFactory.newQuery(AccrualCategoryBo.class, root);
		Object obj = this.getPersistenceBrokerTemplate().getObjectByQuery(query);
		if (obj != null) {
			accrlCategory = (AccrualCategoryBo) obj;
		}

		return accrlCategory;
    }

    //@Override
    //public AccrualCategoryBo saveOrUpdate(AccrualCategoryBo accrualCategory) {
    //	return this.getPersistenceBrokerTemplate().store(accrualCategory);
    //}

	@Override
	public AccrualCategoryBo getAccrualCategory(String lmAccrualCategoryId) {
		Criteria crit = new Criteria();
		crit.addEqualTo("lmAccrualCategoryId", lmAccrualCategoryId);

		Query query = QueryFactory.newQuery(AccrualCategoryBo.class, crit);
		return (AccrualCategoryBo)this.getPersistenceBrokerTemplate().getObjectByQuery(query);

	}

	@Override
	// KPME-1011
    public List<AccrualCategoryBo> getActiveAccrualCategories(LocalDate asOfDate) {
		List<AccrualCategoryBo> accrualCategories = new ArrayList<AccrualCategoryBo>();
		Criteria root = new Criteria();
		Criteria timestampSubCrit = new Criteria();

		timestampSubCrit.addEqualToField("accrualCategory", Criteria.PARENT_QUERY_PREFIX + "accrualCategory");
		ReportQueryByCriteria timestampSubQuery = QueryFactory.newReportQuery(AccrualCategoryBo.class, timestampSubCrit);
		timestampSubQuery.setAttributes(new String[]{ "max(timestamp)" });

		root.addLessOrEqualThan("effectiveDate", asOfDate.toDate());
		root.addEqualTo("timestamp", timestampSubQuery);
		root.addEqualTo("active",true);

		Query query = QueryFactory.newQuery(AccrualCategoryBo.class, root);

		Collection c = this.getPersistenceBrokerTemplate().getCollectionByQuery(query);

		if (c != null) {
			accrualCategories.addAll(c);
		}

		return accrualCategories;
    }

	@Override
    @SuppressWarnings("unchecked")
	public List<AccrualCategoryBo> getAccrualCategories(String accrualCategory, String descr, String leavePlan, String accrualEarnInterval,
													  String unitOfTime, String minPercentWorked, LocalDate fromEffdt, LocalDate toEffdt, String active,
													  String showHistory) {

        List<AccrualCategoryBo> results = new ArrayList<AccrualCategoryBo>();

    	Criteria root = new Criteria();

        if (StringUtils.isNotBlank(accrualCategory)) {
            root.addLike("UPPER(accrualCategory)", accrualCategory.toUpperCase()); // KPME-2695
        }

        if (StringUtils.isNotBlank(descr)) {
            root.addLike("UPPER(descr)", descr.toUpperCase()); // KPME-2695
        }

        if (StringUtils.isNotBlank(leavePlan)) {
        	root.addLike("UPPER(leavePlan)", leavePlan.toUpperCase()); // KPME-2695
        }

        if (StringUtils.isNotBlank(accrualEarnInterval)) {
        	root.addLike("accrualEarnInterval", accrualEarnInterval);
        }

        if (StringUtils.isNotBlank(unitOfTime)) {
        	root.addLike("unitOfTime", unitOfTime);
        }

        if (StringUtils.isNotBlank(minPercentWorked)) {
        	root.addLike("minPercentWorked", minPercentWorked);
        }

        Criteria effectiveDateFilter = new Criteria();
        if (fromEffdt != null) {
            effectiveDateFilter.addGreaterOrEqualThan("effectiveDate", fromEffdt.toDate());
        }
        if (toEffdt != null) {
            effectiveDateFilter.addLessOrEqualThan("effectiveDate", toEffdt.toDate());
        }
        if (fromEffdt == null && toEffdt == null) {
            effectiveDateFilter.addLessOrEqualThan("effectiveDate", LocalDate.now().toDate());
        }
        root.addAndCriteria(effectiveDateFilter);

        if (StringUtils.isNotBlank(active)) {
        	Criteria activeFilter = new Criteria();
            if (StringUtils.equals(active, "Y")) {
                activeFilter.addEqualTo("active", true);
            } else if (StringUtils.equals(active, "N")) {
                activeFilter.addEqualTo("active", false);
            }
            root.addAndCriteria(activeFilter);
        }

        if (StringUtils.equals(showHistory, "N")) {
            root.addEqualTo("effectiveDate", OjbSubQueryUtil.getEffectiveDateSubQueryWithFilter(AccrualCategoryBo.class, effectiveDateFilter, AccrualCategoryBo.BUSINESS_KEYS, false));
            root.addEqualTo("timestamp", OjbSubQueryUtil.getTimestampSubQuery(AccrualCategoryBo.class, AccrualCategoryBo.BUSINESS_KEYS, false));
        }

        Query query = QueryFactory.newQuery(AccrualCategoryBo.class, root);
        results.addAll(getPersistenceBrokerTemplate().getCollectionByQuery(query));

        return results;
    }

	public List<AccrualCategoryBo> getActiveAccrualCategories(String leavePlan, LocalDate asOfDate){
		List<AccrualCategoryBo> accrualCategories = new ArrayList<AccrualCategoryBo>();

		Criteria root = new Criteria();

		root.addEqualTo("leavePlan", leavePlan);
        root.addEqualTo("effectiveDate", OjbSubQueryUtil.getEffectiveDateSubQuery(AccrualCategoryBo.class, asOfDate, AccrualCategoryBo.BUSINESS_KEYS, false));
        root.addEqualTo("timestamp", OjbSubQueryUtil.getTimestampSubQuery(AccrualCategoryBo.class, AccrualCategoryBo.BUSINESS_KEYS, false));

		Criteria activeFilter = new Criteria(); // Inner Join For Activity
		activeFilter.addEqualTo("active", true);
		root.addAndCriteria(activeFilter);

		Query query = QueryFactory.newQuery(AccrualCategoryBo.class, root);
		Collection c = this.getPersistenceBrokerTemplate().getCollectionByQuery(query);

		if (c != null) {
			accrualCategories.addAll(c);
		}
		return accrualCategories;
	}

    @Override
	public List<AccrualCategoryBo> getActiveLeaveAccrualCategoriesForLeavePlan(String leavePlan, LocalDate asOfDate){
		Criteria root = new Criteria();
		root.addEqualTo("leavePlan", leavePlan);
		root.addLessOrEqualThan("effectiveDate", asOfDate.toDate());
		root.addNotEqualTo("accrualEarnInterval", "N");
		root.addEqualTo("active", true);

		Query query = QueryFactory.newQuery(AccrualCategoryBo.class, root);
		Collection c = this.getPersistenceBrokerTemplate().getCollectionByQuery(query);
		List<AccrualCategoryBo> accrualCategories = new ArrayList<AccrualCategoryBo>();

		if (c != null) {
			accrualCategories.addAll(c);
		}
		return accrualCategories;
	}

	@Override
	public List <AccrualCategoryBo> getInActiveLeaveAccrualCategoriesForLeavePlan(String leavePlan, LocalDate asOfDate) {
		Criteria root = new Criteria();
		root.addEqualTo("leavePlan", leavePlan);
		root.addNotEqualTo("accrualEarnInterval", "N");
		root.addLessOrEqualThan("effectiveDate", asOfDate.toDate());
		root.addEqualTo("active", false);
		Query query = QueryFactory.newQuery(AccrualCategoryBo.class, root);
		Collection c = this.getPersistenceBrokerTemplate().getCollectionByQuery(query);
		List<AccrualCategoryBo> accrualCategories = new ArrayList<AccrualCategoryBo>();

		if (c != null) {
			accrualCategories.addAll(c);
		}
		return accrualCategories;
	}
}


text:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.redkale.net.http;

import org.redkale.net.http.WebSocketPacket.FrameType;
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.logging.*;
import java.util.stream.Stream;
import java.util.zip.*;
import org.redkale.convert.Convert;
import org.redkale.net.AsyncConnection;
import org.redkale.util.Comment;

/**
 *

 * 一个WebSocket连接对应一个WebSocket实体,即一个WebSocket会绑定一个TCP连接。
 * 协议上符合HTML5规范, 其流程顺序如下:
 *      1.1 onOpen 若返回null,视为WebSocket的连接不合法,强制关闭WebSocket连接;通常用于判断登录态。
 *      1.2 createUserid 若返回null,视为WebSocket的连接不合法,强制关闭WebSocket连接;通常用于判断用户权限是否符合。
 *      1.3 onConnected WebSocket成功连接后在准备接收数据前回调此方法。
 *      1.4 onMessage/onFragment+ WebSocket接收到消息后回调此消息类方法。
 *      1.5 onClose WebSocket被关闭后回调此方法。
 *  普通模式下 以上方法都应该被重载。
 *

 *

 * 详情见: https://redkale.org
 *
 * @author zhangjx
 * @param <G> Groupid的泛型
 * @param <T> Message的泛型
 */
public abstract class WebSocket<G extends Serializable, T> {

    //--------------------------- CLOSECODE -------------------------------
    @Comment("服务器主动关闭")
    public static final int CLOSECODE_SERVERCLOSE = 3001;

    @Comment("客户端主动关闭")
    public static final int CLOSECODE_CLIENTCLOSE = 3002;

    @Comment("异常关闭")
    public static final int CLOSECODE_WSEXCEPTION = 3003;

    @Comment("异常数据强制关闭")
    public static final int CLOSECODE_ILLPACKET = 3004;

    //---------------------------- RETCODE --------------------------------
    @Comment("消息不合法")
    public static final int RETCODE_SEND_ILLPACKET = 1 << 1; //2

    @Comment("WebSocket已经关闭")
    public static final int RETCODE_WSOCKET_CLOSED = 1 << 2; //4

    @Comment("Socket的buffer不合法")
    public static final int RETCODE_ILLEGALBUFFER = 1 << 3; //8

    @Comment("WebSocket发送消息异常")
    public static final int RETCODE_SENDEXCEPTION = 1 << 4; //16

    @Comment("WebSocketEngine实例不存在")
    public static final int RETCODE_ENGINE_NULL = 1 << 5; //32

    @Comment("WebSocketNode实例不存在")
    public static final int RETCODE_NODESERVICE_NULL = 1 << 6; //64

    @Comment("WebSocket组为空, 表示无WebSocket连接")
    public static final int RETCODE_GROUP_EMPTY = 1 << 7; //128

    @Comment("WebSocket已离线")
    public static final int RETCODE_WSOFFLINE = 1 << 8; //256

    @Comment("WebSocket将延迟发送")
    public static final int RETCODE_DEAYSEND = 1 << 9; //512

    WebSocketRunner _runner; //不可能为空

    WebSocketEngine _engine; //不可能为空

    InetSocketAddress _sncpAddress; //分布式下不可为空

    AsyncConnection _channel;//不可能为空

    String _sessionid; //不可能为空

    G _userid; //不可能为空

    SocketAddress _remoteAddress;//不可能为空

    String _remoteAddr;//不可能为空

    Convert _textConvert; //不可能为空

    Convert _binaryConvert; //可能为空

    Convert _sendConvert; //不可能为空

    java.lang.reflect.Type _messageTextType; //不可能为空

    Deflater deflater; //压缩

    Inflater inflater; //解压

    long createtime = System.currentTimeMillis();

    private long pingtime;

    private Map<String, Object> attributes = new HashMap<>(); //非线程安全

    List<WebSocketPacket> delayPackets;

    protected WebSocket() {
    }

    //----------------------------------------------------------------
    public final CompletableFuture<Integer> sendPing() {
        this.pingtime = System.currentTimeMillis();
        //if (_engine.finest) _engine.logger.finest(this + " on "+_engine.getEngineid()+" ping...");
        return sendPacket(WebSocketPacket.DEFAULT_PING_PACKET);
    }

    public final CompletableFuture<Integer> sendPing(byte[] data) {
        this.pingtime = System.currentTimeMillis();
        return sendPacket(new WebSocketPacket(FrameType.PING, data));
    }

    public final CompletableFuture<Integer> sendPong(byte[] data) {
        return sendPacket(new WebSocketPacket(FrameType.PONG, data));
    }

    public final long getCreatetime() {
        return createtime;
    }

    /**
     * 给自身发送消息, 消息类型是String或byte[]或可JavaBean对象
     *
     * @param message 不可为空, 只能是String或byte[]或可JavaBean对象
     *
     * @return 0表示成功, 非0表示错误码
     */
    public final CompletableFuture<Integer> send(Object message) {
        return send(false, message, true);
    }

    /**
     * 给自身发送消息, 消息类型是key-value键值对
     *
     * @param messages key-value键值对
     *
     * @return 0表示成功, 非0表示错误码
     */
    public final CompletableFuture<Integer> sendMap(Object... messages) {
        return send(true, messages, true);
    }

    /**
     * 给自身发送消息, 消息类型是String或byte[]或可JavaBean对象
     *
     * @param message 不可为空, 只能是String或byte[]或可JavaBean对象
     * @param last    是否最后一条
     *
     * @return 0表示成功, 非0表示错误码
     */
    public final CompletableFuture<Integer> send(Object message, boolean last) {
        return send(false, message, last);
    }

    /**
     * 给自身发送消息, 消息类型是key-value键值对
     *
     * @param last     是否最后一条
     * @param messages key-value键值对
     *
     * @return 0表示成功, 非0表示错误码
     */
    public final CompletableFuture<Integer> sendMap(boolean last, Object... messages) {
        return send(true, messages, last);
    }

    /**
     * 给自身发送消息, 消息类型是Object[]
     *
     * @param mapconvable 是否convertMapTo
     * @param message     不可为空, 只能是String或byte[]或可JavaBean对象,或Object[]
     * @param last        是否最后一条
     *
     * @return 0表示成功, 非0表示错误码
     */
    private CompletableFuture<Integer> send(boolean mapconvable, Object message, boolean last) {
        if (message instanceof CompletableFuture) {
            return ((CompletableFuture) message).thenCompose((json) -> {
                if (json == null || json instanceof CharSequence || json instanceof byte[]) {
                    return sendPacket(new WebSocketPacket((Serializable) json, last));
                } else if (message instanceof WebSocketPacket) {
                    return sendPacket((WebSocketPacket) message);
                } else {
                    return sendPacket(new WebSocketPacket(getSendConvert(), mapconvable, json, last));
                }
            });
        }
        if (message == null || message instanceof CharSequence || message instanceof byte[]) {
            return sendPacket(new WebSocketPacket((Serializable) message, last));
        } else if (message instanceof WebSocketPacket) {
            return sendPacket((WebSocketPacket) message);
        } else {
            return sendPacket(new WebSocketPacket(getSendConvert(), mapconvable, message, last));
        }
    }

    /**
     * 给自身发送消息, 消息类型是JavaBean对象
     *
     * @param convert Convert
     * @param message 不可为空, 只能是JSON对象
     *
     * @return 0表示成功, 非0表示错误码
     */
    public final CompletableFuture<Integer> send(Convert convert, Object message) {
        return send(convert, message, true);
    }

    /**
     * 给自身发送消息, 消息类型是JavaBean对象
     *
     * @param convert Convert
     * @param message 不可为空, 只能是JavaBean对象
     * @param last    是否最后一条
     *
     * @return 0表示成功, 非0表示错误码
     */
    public final CompletableFuture<Integer> send(Convert convert, Object message, boolean last) {
        if (message instanceof CompletableFuture) {
            return ((CompletableFuture) message).thenCompose((json) -> sendPacket(new WebSocketPacket(convert == null ? getSendConvert() : convert, false, json, last)));
        }
        return sendPacket(new WebSocketPacket(convert == null ? getSendConvert() : convert, false, message, last));
    }

    /**
     * 给自身发送消息体, 包含二进制/文本
     *
     * @param packet WebSocketPacket
     *
     * @return 0表示成功, 非0表示错误码
     */
    CompletableFuture<Integer> sendPacket(WebSocketPacket packet) {
        if (this._runner == null) {
            if (delayPackets == null) delayPackets = new ArrayList<>();
            delayPackets.add(packet);
            return CompletableFuture.completedFuture(RETCODE_DEAYSEND);
        }
        CompletableFuture<Integer> rs = this._runner.sendMessage(packet);
        if (_engine.logger.isLoggable(Level.FINEST) && packet != WebSocketPacket.DEFAULT_PING_PACKET) {
            _engine.logger.finest("userid:" + getUserid() + " send websocket message(" + packet + ")" + " on " + this);
        }
        return rs == null ? CompletableFuture.completedFuture(RETCODE_WSOCKET_CLOSED) : rs;
    }

    //----------------------------------------------------------------
    /**
     * 给指定userid的WebSocket节点发送 二进制消息/文本消息/JavaBean对象消息
     *
     * @param message 不可为空
     * @param userids Stream
     *
     * @return 为0表示成功, 其他值表示异常
     */
    public final CompletableFuture<Integer> sendMessage(Object message, Stream<G> userids) {
        return sendMessage(message, true, userids);
    }

    /**
     * 给指定userid的WebSocket节点发送 二进制消息/文本消息/JavaBean对象消息
     *
     * @param message 不可为空
     * @param userids Serializable[]
     *
     * @return 为0表示成功, 其他值表示异常
     */
    public final CompletableFuture<Integer> sendMessage(Object message, G... userids) {
        return sendMessage(message, true, userids);
    }

    /**
     * 给指定userid的WebSocket节点发送 二进制消息/文本消息/JavaBean对象消息
     *
     * @param convert Convert
     * @param message 不可为空
     * @param userids Stream
     *
     * @return 为0表示成功, 其他值表示异常
     */
    public final CompletableFuture<Integer> sendMessage(final Convert convert, Object message, Stream<G> userids) {
        return sendMessage(convert, message, true, userids);
    }

    /**
     * 给指定userid的WebSocket节点发送 二进制消息/文本消息/JavaBean对象消息
     *
     * @param convert Convert
     * @param message 不可为空
     * @param userids Serializable[]
     *
     * @return 为0表示成功, 其他值表示异常
     */
    public final CompletableFuture<Integer> sendMessage(final Convert convert, Object message, G... userids) {
        return sendMessage(convert, message, true, userids);
    }

    /**
     * 给指定userid的WebSocket节点发送 二进制消息/文本消息/JavaBean对象消息
     *
     * @param message 不可为空
     * @param last    是否最后一条
     * @param userids Serializable[]
     *
     * @return 为0表示成功, 其他值表示异常
     */
    public final CompletableFuture<Integer> sendMessage(Object message, boolean last, Stream<G> userids) {
        return sendMessage((Convert) null, message, last, userids);
    }

    /**
     * 给指定userid的WebSocket节点发送 二进制消息/文本消息/JavaBean对象消息
     *
     * @param message 不可为空
     * @param last    是否最后一条
     * @param userids Serializable[]
     *
     * @return 为0表示成功, 其他值表示异常
     */
    public final CompletableFuture<Integer> sendMessage(Object message, boolean last, G... userids) {
        return sendMessage((Convert) null, message, last, userids);
    }

    /**
     * 给指定userid的WebSocket节点发送 二进制消息/文本消息/JavaBean对象消息
     *
     * @param convert Convert
     * @param message 不可为空
     * @param last    是否最后一条
     * @param userids Stream
     *
     * @return 为0表示成功, 其他值表示异常
     */
    public final CompletableFuture<Integer> sendMessage(final Convert convert, Object message, boolean last, final Stream<G> userids) {
        Object[] array = userids.toArray();
        Serializable[] ss = new Serializable[array.length];
        for (int i = 0; i < array.length; i++) {
            ss[i] = (Serializable) array[i];
        }
        return sendMessage(convert, message, last, ss);
    }

    /**
     * 给指定userid的WebSocket节点发送 二进制消息/文本消息/JavaBean对象消息
     *
     * @param convert Convert
     * @param message 不可为空
     * @param last    是否最后一条
     * @param userids Serializable[]
     *
     * @return 为0表示成功, 其他值表示异常
     */
    public final CompletableFuture<Integer> sendMessage(final Convert convert, Object message, boolean last, Serializable... userids) {
        if (_engine.node == null) return CompletableFuture.completedFuture(RETCODE_NODESERVICE_NULL);
        if (message instanceof CompletableFuture) {
            return ((CompletableFuture) message).thenCompose((json) -> _engine.node.sendMessage(convert, json, last, userids));
        }
        CompletableFuture<Integer> rs = _engine.node.sendMessage(convert, message, last, userids);
        if (_engine.logger.isLoggable(Level.FINEST)) _engine.logger.finest("userids:" + Arrays.toString(userids) + " send websocket message(" + message + ")");
        return rs;
    }

    /**
     * 广播消息, 给所有人发消息
     *
     * @param message 消息内容
     *
     * @return 为0表示成功, 其他值表示部分发送异常
     */
    public final CompletableFuture<Integer> broadcastMessage(final Object message) {
        return broadcastMessage((Convert) null, message, true);
    }

    /**
     * 广播消息, 给所有人发消息
     *
     * @param wsrange 过滤条件
     * @param message 消息内容
     *
     * @return 为0表示成功, 其他值表示部分发送异常
     */
    public final CompletableFuture<Integer> broadcastMessage(final WebSocketRange wsrange, final Object message) {
        return broadcastMessage((WebSocketRange) null, (Convert) null, message, true);
    }

    /**
     * 广播消息, 给所有人发消息
     *
     * @param convert Convert
     * @param message 消息内容
     *
     * @return 为0表示成功, 其他值表示部分发送异常
     */
    public final CompletableFuture<Integer> broadcastMessage(final Convert convert, final Object message) {
        return broadcastMessage(convert, message, true);
    }

    /**
     * 广播消息, 给所有人发消息
     *
     * @param wsrange 过滤条件
     * @param convert Convert
     * @param message 消息内容
     *
     * @return 为0表示成功, 其他值表示部分发送异常
     */
    public final CompletableFuture<Integer> broadcastMessage(final WebSocketRange wsrange, final Convert convert, final Object message) {
        return broadcastMessage((WebSocketRange) null, convert, message, true);
    }

    /**
     * 广播消息, 给所有人发消息
     *
     * @param message 消息内容
     * @param last    是否最后一条
     *
     * @return 为0表示成功, 其他值表示部分发送异常
     */
    public final CompletableFuture<Integer> broadcastMessage(final Object message, final boolean last) {
        return broadcastMessage((Convert) null, message, last);
    }

    /**
     * 广播消息, 给所有人发消息
     *
     * @param wsrange 过滤条件
     * @param message 消息内容
     * @param last    是否最后一条
     *
     * @return 为0表示成功, 其他值表示部分发送异常
     */
    public final CompletableFuture<Integer> broadcastMessage(final WebSocketRange wsrange, final Object message, final boolean last) {
        return broadcastMessage(wsrange, (Convert) null, message, last);
    }

    /**
     * 广播消息, 给所有人发消息
     *
     * @param convert Convert
     * @param message 消息内容
     * @param last    是否最后一条
     *
     * @return 为0表示成功, 其他值表示部分发送异常
     */
    public final CompletableFuture<Integer> broadcastMessage(final Convert convert, final Object message, final boolean last) {
        return broadcastMessage((WebSocketRange) null, convert, message, last);
    }

    /**
     * 广播消息, 给所有人发消息
     *
     * @param wsrange 过滤条件
     * @param convert Convert
     * @param message 消息内容
     * @param last    是否最后一条
     *
     * @return 为0表示成功, 其他值表示部分发送异常
     */
    public final CompletableFuture<Integer> broadcastMessage(final WebSocketRange wsrange, final Convert convert, final Object message, final boolean last) {
        if (_engine.node == null) return CompletableFuture.completedFuture(RETCODE_NODESERVICE_NULL);
        if (message instanceof CompletableFuture) {
            return ((CompletableFuture) message).thenCompose((json) -> _engine.node.broadcastMessage(wsrange, convert, json, last));
        }
        CompletableFuture<Integer> rs = _engine.node.broadcastMessage(wsrange, convert, message, last);
        if (_engine.logger.isLoggable(Level.FINEST)) _engine.logger.finest("broadcast send websocket message(" + message + ")");
        return rs;
    }

    /**
     * 给指定userid的WebSocket节点发送操作
     *
     * @param action  操作参数
     * @param userids Serializable[]
     *
     * @return 为0表示成功, 其他值表示异常
     */
    public final CompletableFuture<Integer> sendAction(final WebSocketAction action, Serializable... userids) {
        if (_engine.node == null) return CompletableFuture.completedFuture(RETCODE_NODESERVICE_NULL);
        CompletableFuture<Integer> rs = _engine.node.sendAction(action, userids);
        if (_engine.logger.isLoggable(Level.FINEST)) _engine.logger.finest("userids:" + Arrays.toString(userids) + " send websocket action(" + action + ")");
        return rs;
    }

    /**
     * 广播操作, 给所有人发操作指令
     *
     * @param action 操作参数
     *
     * @return 为0表示成功, 其他值表示部分发送异常
     */
    public final CompletableFuture<Integer> broadcastAction(final WebSocketAction action) {
        if (_engine.node == null) return CompletableFuture.completedFuture(RETCODE_NODESERVICE_NULL);
        CompletableFuture<Integer> rs = _engine.node.broadcastAction(action);
        if (_engine.logger.isLoggable(Level.FINEST)) _engine.logger.finest("broadcast send websocket action(" + action + ")");
        return rs;
    }

    /**
     * 获取用户在线的SNCP节点地址列表,不是分布式则返回元素数量为1,且元素值为null的列表

     * InetSocketAddress 为 SNCP节点地址
     *
     * @param userid Serializable
     *
     * @return 地址列表
     */
    public CompletableFuture<Collection<WebSocketAddress>> getRpcNodeAddresses(final Serializable userid) {
        if (_engine.node == null) return CompletableFuture.completedFuture(null);
        return _engine.node.getRpcNodeAddresses(userid);
    }

    /**
     * 获取在线用户的详细连接信息

     * Map.key 为 SNCP节点地址, 含值为null的key表示没有分布式
     * Map.value 为 用户客户端的IP
     *
     * @param userid Serializable
     *
     * @return 地址集合
     */
    public CompletableFuture<Map<WebSocketAddress, List<String>>> getRpcNodeWebSocketAddresses(final Serializable userid) {
        if (_engine.node == null) return CompletableFuture.completedFuture(null);
        return _engine.node.getRpcNodeWebSocketAddresses(userid);
    }

    /**
     * 更改本WebSocket的userid
     *
     * @param newuserid 新用户ID,不能为null
     *
     * @return CompletableFuture
     */
    public CompletableFuture<Void> changeUserid(final G newuserid) {
        if (newuserid == null) throw new NullPointerException("newuserid is null");
        return _engine.changeLocalUserid(this, newuserid);
    }

    /**
     * 强制关闭用户的所有WebSocket
     *
     * @param userid Serializable
     *
     * @return int
     */
    @Comment("强制关闭用户的所有WebSocket")
    public CompletableFuture<Integer> forceCloseWebSocket(Serializable userid) {
        return _engine.node.forceCloseWebSocket(userid);
    }

    /**
     * 获取WebSocketNode
     *
     *
     * @return WebSocketNode
     */
    @Comment("获取WebSocketNode")
    public final WebSocketNode webSocketNode() {
        return _engine.node;
    }

    /**
     * 获取当前WebSocket下的属性,非线程安全
     *
     * @param <V>  属性值的类型
     * @param name 属性名
     *
     * @return 属性值
     */
    @SuppressWarnings("unchecked")
    public final <V> V getAttribute(String name) {
        return attributes == null ? null : (V) attributes.get(name);
    }

    /**
     * 移出当前WebSocket下的属性,非线程安全
     *
     * @param <V>  属性值的类型
     * @param name 属性名
     *
     * @return 属性值
     */
    public final <V> V removeAttribute(String name) {
        return attributes == null ? null : (V) attributes.remove(name);
    }

    /**
     * 给当前WebSocket下的增加属性,非线程安全
     *
     * @param name  属性值
     * @param value 属性值
     */
    public final void setAttribute(String name, Object value) {
        if (attributes == null) attributes = new HashMap<>();
        attributes.put(name, value);
    }

    /**
     * 获取当前WebSocket所属的userid
     *
     * @return userid
     */
    public final G getUserid() {
        return _userid;
    }

    /**
     * 获取当前WebSocket的会话ID, 不会为null
     *
     * @return sessionid
     */
    public final String getSessionid() {
        return _sessionid;
    }

    /**
     * 获取客户端直接地址, 当WebSocket连接是由代理服务器转发的,则该值固定为代理服务器的IP地址
     *
     * @return SocketAddress
     */
    public final SocketAddress getRemoteAddress() {
        return _remoteAddress;
    }

    /**
     * 获取客户端真实地址 同 HttpRequest.getRemoteAddr()
     *
     * @return String
     */
    public final String getRemoteAddr() {
        return _remoteAddr;
    }

    protected Convert getTextConvert() {
        return _textConvert;
    }

    protected Convert getBinaryConvert() {
        return _binaryConvert;
    }

    protected Convert getSendConvert() {
        return _sendConvert;
    }

    //-------------------------------------------------------------------
    /**
     * 获取指定userid的WebSocket数组, 没有返回null

     * 此方法用于单用户多连接模式
     *
     * @param userid Serializable
     *
     * @return WebSocket集合
     */
    protected final Stream<WebSocket> getLocalWebSockets(G userid) {
        return _engine.getLocalWebSockets(userid);
    }

    /**
     * 获取指定userid的WebSocket数组, 没有返回null

     * 此方法用于单用户单连接模式
     *
     * @param userid Serializable
     *
     * @return WebSocket
     */
    protected final WebSocket findLocalWebSocket(G userid) {
        return _engine.findLocalWebSocket(userid);
    }

    /**
     * 获取当前进程节点所有在线的WebSocket
     *
     * @return WebSocketGroup列表
     */
    protected final Collection<WebSocket> getLocalWebSockets() {
        return _engine.getLocalWebSockets();
    }

    /**
     * 获取ByteBuffer生成器
     *
     * @return Supplier
     */
    protected Supplier<ByteBuffer> getBufferSupplier() {
        return this._channel.getBufferSupplier();
    }

    /**
     * 获取ByteBuffer回收器
     *
     * @return Consumer
     */
    protected Consumer<ByteBuffer> getBufferConsumer() {
        return this._channel.getBufferConsumer();
    }

    //-------------------------------------------------------------------
    /**
     * 返回sessionid, null表示连接不合法或异常,默认实现是request.sessionid(true),通常需要重写该方法
     *
     * @param request HttpRequest
     *
     * @return sessionid
     */
    protected CompletableFuture<String> onOpen(final HttpRequest request) {
        return CompletableFuture.completedFuture(request.getSessionid(true));
    }

    /**
     * 创建userid, null表示异常, 必须实现该方法
     *
     * @return userid
     */
    protected abstract CompletableFuture<G> createUserid();

    /**
     * WebSocket.broadcastMessage时的过滤条件
     *
     * @param wsrange 过滤条件
     *
     * @return boolean
     */
    protected boolean predicate(WebSocketRange wsrange) {
        return true;
    }

    /**
     * WebSocket.broadcastAction时的操作
     *
     * @param action 操作参数
     *
     * @return CompletableFuture
     *
     */
    protected CompletableFuture<Integer> action(WebSocketAction action) {
        return CompletableFuture.completedFuture(0);
    }

    /**
     * WebSokcet连接成功后的回调方法
     *
     * @return Future 可以为null
     */
    public CompletableFuture onConnected() {
        return null;
    }

    /**
     * ping后的回调方法
     *
     * @param bytes 数据
     */
    public void onPing(byte[] bytes) {
    }

    /**
     * pong后的回调方法
     *
     * @param bytes 数据
     */
    public void onPong(byte[] bytes) {
    }

    /**
     *
     * 接收到消息前的拦截方法, ping/pong不在其内

     * 注意:处理完后需要调用 messageEvent.run() 才能响应onMessage
     *
     * @param restmapping  Rest的方法名,没有则为空字符串
     * @param param        onMessage方法的参数
     * @param messageEvent onMessage事件
     */
    public void preOnMessage(String restmapping, WebSocketParam param, Runnable messageEvent) {
        messageEvent.run();
    }

    /**
     * 接收到消息的回调方法
     *
     * @param message 消息
     * @param last    是否最后一条
     */
    public void onMessage(T message, boolean last) {
    }

    /**
     * 接收到文本消息的回调方法
     *
     * @param text 消息
     * @param last 是否最后一条
     */
    public void onMessage(String text, boolean last) {
    }

    /**
     * 接收到二进制消息的回调方法
     *
     * @param bytes 消息
     * @param last  是否最后一条
     */
    public void onMessage(byte[] bytes, boolean last) {
    }

    /**
     * 关闭的回调方法,调用此方法时WebSocket已经被关闭
     *
     * @param code   结果码,非0表示非正常关闭
     * @param reason 关闭原因
     *
     * @return Future 可以为null
     */
    public CompletableFuture onClose(int code, String reason) {
        return null;
    }

    /**
     * 发生异常时调用
     *
     * @param t       异常
     * @param buffers ByteBuffer[]
     */
    public void onOccurException(Throwable t, ByteBuffer[] buffers) {
        this.getLogger().log(Level.SEVERE, "WebSocket receive or send Message error", t);
    }

    /**
     * 当Single模式下用户重复登录时回调函数,默认处理方式: 关闭旧连接
     *
     * @return Future 可以为null, 为null或者Future值为false表示关闭新连接, Future值为true表示关闭旧连接
     */
    public CompletableFuture<Boolean> onSingleRepeatConnect() {
        return forceCloseWebSocket(getUserid()).thenApply((r) -> true);
    }

    /**
     * 获取分布式情况下的SNCP地址, 非分布式下为null
     *
     * @return InetSocketAddress sncpAddress
     */
    public InetSocketAddress getSncpAddress() {
        return _sncpAddress;
    }

    /**
     * 获取Logger
     *
     * @return Logger Logger
     */
    public Logger getLogger() {
        return this._engine.logger;
    }

    /**
     * 获取最后一次发送消息的时间
     *
     * @return long
     */
    public long getLastSendTime() {
        return this._runner == null ? 0 : this._runner.lastSendTime;
    }

    /**
     * 获取最后一次读取消息的时间
     *
     * @return long
     */
    public long getLastReadTime() {
        return this._runner == null ? 0 : this._runner.lastReadTime;
    }

    /**
     * 获取最后一次发送PING消息的时间
     *
     * @return long
     */
    public long getLastPingTime() {
        return this.pingtime;
    }

    /**
     * 显式地关闭WebSocket
     */
    public final void close() {
        if (this.deflater != null) this.deflater.end();
        if (this.inflater != null) this.inflater.end();
        if (this._runner != null) {
            CompletableFuture<Void> future = this._runner.closeRunner(CLOSECODE_SERVERCLOSE, "user close");
            if (future != null) future.join();
        }
    }

    /**
     * 是否关闭
     *
     * @return boolean
     */
    public final boolean isClosed() {
        return this._runner != null ? this._runner.closed : true;
    }

    @Override
    public String toString() {
        return this.getUserid() + "@" + _remoteAddr;
    }
}


text:
package app.controllers.admin.special2.special3;

import org.javalite.activeweb.AppController;
import org.javalite.activeweb.AppController;
import org.javalite.activeweb.annotations.RESTful;
import org.javalite.activeweb.annotations.RESTful;

/**
 * @author Igor Polevoy
 */
@RESTful
public class Special3RestController extends AppController {
    public void options(){}
    public void update(){}
    public void destroy(){}

}


text:
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Scheme.Error where

import Text.Parsec.Error

data SchemeError = RuntimeError String
                 | SyntaxError ParseError
  deriving Show

instance Eq SchemeError where
  _ == _ = False

instance Eq ParseError where
  _ == _ = False


text:
#ifndef QUICKSTEP_STORAGE_COMPRESSED_COLUMN_STORE_TUPLE_STORAGE_SUB_BLOCK_HPP_
#define QUICKSTEP_STORAGE_COMPRESSED_COLUMN_STORE_TUPLE_STORAGE_SUB_BLOCK_HPP_

#include <cstddef>
#include <cstdint>
#include <utility>
#include <vector>

#include "catalog/CatalogTypedefs.hpp"
#include "expressions/predicate/PredicateCost.hpp"
#include "storage/CompressedTupleStorageSubBlock.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "storage/StorageBlockLayout.pb.h"
#include "storage/SubBlockTypeRegistryMacros.hpp"
#include "types/TypedValue.hpp"
#include "utility/BitVector.hpp"
#include "utility/Macros.hpp"
#include "utility/PtrVector.hpp"

namespace quickstep {

class CatalogRelationSchema;
class ComparisonPredicate;
class ValueAccessor;

QUICKSTEP_DECLARE_SUB_BLOCK_TYPE_REGISTERED(CompressedColumnStoreTupleStorageSubBlock);

/** \addtogroup Storage
 *  @{
 */

/**
 * @brief An implementation of TupleStorageSubBlock as a column store with a
 *        single sort column, optional column compression (dictionary or
 *        truncation), and no holes.
 * @warning This implementation does support variable-length attributes, but
 *          they must all be compressed (specified with compressed_attribute_id
 *          in the TupleStorageSubBlockDescription).
 **/
class CompressedColumnStoreTupleStorageSubBlock : public CompressedTupleStorageSubBlock {
 public:
  CompressedColumnStoreTupleStorageSubBlock(
      const CatalogRelationSchema &relation,
      const TupleStorageSubBlockDescription &description,
      const bool new_block,
      void *sub_block_memory,
      const std::size_t sub_block_memory_size);

  ~CompressedColumnStoreTupleStorageSubBlock() override {
  }

  /**
   * @brief Determine whether a TupleStorageSubBlockDescription is valid for
   *        this type of TupleStorageSubBlock.
   *
   * @param relation The relation a tuple store described by description would
   *        belong to.
   * @param description A description of the parameters for this type of
   *        TupleStorageSubBlock, which will be checked for validity.
   * @return Whether description is well-formed and valid for this type of
   *         TupleStorageSubBlock belonging to relation (i.e. whether a
   *         TupleStorageSubBlock of this type, belonging to relation, can be
   *         constructed according to description).
   **/
  static bool DescriptionIsValid(const CatalogRelationSchema &relation,
                                 const TupleStorageSubBlockDescription &description);

  /**
   * @brief Estimate the average number of bytes (including any applicable
   *        overhead) used to store a single tuple in this type of
   *        TupleStorageSubBlock. Used by StorageBlockLayout::finalize() to
   *        divide block memory amongst sub-blocks.
   * @warning description must be valid. DescriptionIsValid() should be called
   *          first if necessary.
   *
   * @param relation The relation tuples belong to.
   * @param description A description of the parameters for this type of
   *        TupleStorageSubBlock.
   * @return The average/ammortized number of bytes used to store a single
   *         tuple of relation in a TupleStorageSubBlock of this type described
   *         by description.
   **/
  static std::size_t EstimateBytesPerTuple(const CatalogRelationSchema &relation,
                                           const TupleStorageSubBlockDescription &description);

  inline TypedValue getAttributeValueTypedInl(const tuple_id tuple,
                                              const attribute_id attr) const;

  TupleStorageSubBlockType getTupleStorageSubBlockType() const override {
    return kCompressedColumnStore;
  }

  const void* getAttributeValue(const tuple_id tuple,
                                const attribute_id attr) const override;

  TypedValue getAttributeValueTyped(const tuple_id tuple,
                                    const attribute_id attr) const override;

  ValueAccessor* createValueAccessor(
      const TupleIdSequence *sequence = nullptr) const override;

  bool deleteTuple(const tuple_id tuple) override;
  bool bulkDeleteTuples(TupleIdSequence *tuples) override;

  predicate_cost_t estimatePredicateEvaluationCost(
      const ComparisonPredicate &predicate) const override;

  // This override can quickly evaluate comparisons between the sort column
  // and a literal value.
  TupleIdSequence* getMatchesForPredicate(const ComparisonPredicate &predicate,
                                          const TupleIdSequence *filter) const override;

  void rebuild() override;

  bool isInsertOrderPreserving() const override {
    // Rebuild sorts tuples based on sort column.
    return false;
  }

  std::uint32_t compressedGetCode(const tuple_id tid,
                                  const attribute_id attr_id) const override;

 protected:
  TupleIdSequence* getEqualCodes(const attribute_id attr_id,
                                 const std::uint32_t code,
                                 const TupleIdSequence *filter) const override;

  TupleIdSequence* getNotEqualCodes(const attribute_id attr_id,
                                    const std::uint32_t code,
                                    const TupleIdSequence *filter) const override;

  TupleIdSequence* getNotEqualCodesExcludingNull(const attribute_id attr_id,
                                                 const std::uint32_t code,
                                                 const std::uint32_t null_code,
                                                 const TupleIdSequence *filter) const override;

  TupleIdSequence* getLessCodes(const attribute_id attr_id,
                                const std::uint32_t code,
                                const TupleIdSequence *filter) const override;

  TupleIdSequence* getGreaterOrEqualCodes(const attribute_id attr_id,
                                          const std::uint32_t code,
                                          const TupleIdSequence *filter) const override;

  TupleIdSequence* getCodesInRange(const attribute_id attr_id,
                                   const std::pair<std::uint32_t, std::uint32_t> range,
                                   const TupleIdSequence *filter) const override;

 private:
  // Returns a pointer to an attribute's physical storage (the value itself if
  // uncompressed, OR the compressed code if compressed), or NULL if
  // 'check_null' is true and the attribute is null.
  template <bool check_null = true>
  inline const void* getAttributePtr(const tuple_id tid,
                                     const attribute_id attr_id) const {
    if (check_null
        && compression_info_.uncompressed_attribute_has_nulls(attr_id)
        && uncompressed_column_null_bitmaps_[attr_id].getBit(tid)) {
      return nullptr;
    } else {
      return static_cast<const char*>(column_stripes_[attr_id])
             + tid * compression_info_.attribute_size(attr_id);
    }
  }

  // Initialize this sub-block's runtime data structures after the physical
  // block has been built.
  void initialize();

  // Move 'num_tuples' values in each column from 'src_tuple' to
  // 'dest_position'.
  void shiftTuples(const tuple_id dest_position,
                   const tuple_id src_tuple,
                   const tuple_id num_tuples);

  // Shift the tails of 'uncompressed_column_null_bitmaps_' (starting from
  // 'from_position') by 'distance' bits (forward shift if 'distance' is
  // negative, backward shift if positive).
  void shiftUncompressedNullBitmaps(const tuple_id from_position,
                                    const tuple_id distance);

  std::pair<tuple_id, tuple_id> getCompressedSortColumnRange(
      const std::pair<std::uint32_t, std::uint32_t> code_range) const;

  // Note: order of application is
  // comparison_functor(literal_code, attribute_code).
  template <template <typename T> class comparison_functor>
  TupleIdSequence* getCodesSatisfyingComparison(const attribute_id attr_id,
                                                const std::uint32_t code,
                                                const TupleIdSequence *filter) const;

  attribute_id sort_column_id_;
  tuple_id uncompressed_nulls_in_sort_column_;

  std::vector<void*> column_stripes_;
  PtrVector<BitVector<false>, true> uncompressed_column_null_bitmaps_;

  DISALLOW_COPY_AND_ASSIGN(CompressedColumnStoreTupleStorageSubBlock);
};

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_STORAGE_COMPRESSED_COLUMN_STORE_TUPLE_STORAGE_SUB_BLOCK_HPP_


text:
SOURCE='
static void push_NAME (lua_State *L, UNKNOWN_TYPE *self)
{
        void **ud = static_cast<void**>(lua_newuserdata(L, sizeof(*ud)));
        ud[0] = static_cast<void*> (self);
        luaL_getmetatable(L, UNKNOWN_TAG);
        lua_setmetatable(L, -2);
        PARENT *p = self->getParent();
        TODO_maps& maps = grit->getUserDataTables().parents[parent];
        maps.UDNAME[self].push_back(ud);
}

static int NAME_gc (lua_State *L)
{
TRY_START
        check_args(L,1);
        GET_UD_MACRO_OFFSET(UNKNOWN_TYPE,self,1,UNKNOWN_TAG,0);
        if (self==NULL) return 0;
        CVERB << "nullifying "UNKNOWN_TAG << std::endl;
        vec_nullify_remove(grit->getUserDataTables().UDNAME[self],&self);
        return 0;
TRY_END
}

static int NAME_destroy (lua_State *L)
{
TRY_START
        check_args(L,1);
        GET_UD_MACRO(UNKNOWN_TYPE,self,1,UNKNOWN_TAG);
        CVERB << "destroying "UNKNOWN_TAG << std::endl;
        self.destroySomehow();
        map_nullify_remove(grit->getUserDataTables().UDNAME,&self);
        return 0;
TRY_END
}

TOSTRING_ADDR_MACRO(NAME,UNKNOWN_TYPE,UNKNOWN_TAG)

static int NAME_index (lua_State *L)
{
TRY_START
        check_args(L,2);
        GET_UD_MACRO(UNKNOWN_TYPE,self,1,UNKNOWN_TAG);
        std::string key = luaL_checkstring(L,2);
        if (key=="destroy") {
                lua_pushcfunction(L,NAME_destroy);
        } else if (key=="someField") {
                int v = 3;
                lua_pushnumber(L,v);
        } else {
                my_lua_error(L,"Not a valid USER_VISIBLE_NAME member: "+key);
        }
        return 1;
TRY_END
}

static int NAME_newindex (lua_State *L)
{
TRY_START
        check_args(L,3);
        GET_UD_MACRO(UNKNOWN_TYPE,self,1,UNKNOWN_TAG);
        std::string key = luaL_checkstring(L,2);
        if (key=="someField") {
                bool v = lua_toboolean(L,3);
                self.setSomeField(v);
        } else {
                my_lua_error(L,"Not a valid USER_VISIBLE_NAME member: "+key);
        }
        return 0;
TRY_END
}

EQ_PTR_MACRO(UNKNOWN_TYPE,NAME,UNKNOWN_TAG)

MT_MACRO_NEWINDEX(NAME);'

echo "Type to be wrapped (e.g. Ogre::MaterialPtr)"
read TYPE
echo "Name (e.g. mat)"
read NAME
echo "Userdata TAG (e.g. MAT_TAG)"
read TAG
echo "Title in code (e.g. MATERIAL)"
read TITLE
echo "User-visible name (e.g. Material)"
read UVNAME
echo "Userdata table name (e.g. materials)"
read UDNAME

echo "// $TITLE ===================================================================================" | cut -b 1-80

echo "$SOURCE" | sed "s/UNKNOWN_TYPE/$TYPE/g" | sed "s/UNKNOWN_TAG/$TAG/g" | sed "s/USER_VISIBLE_NAME/$UVNAME/g" | sed "s/UDNAME/$UDNAME/g"  | sed "s/NAME/$NAME/g"


text:
"""HTTP server base class.

Note: the class in this module doesn't implement any HTTP request; see
SimpleHTTPServer for simple implementations of GET, HEAD and POST
(including CGI scripts).  It does, however, optionally implement HTTP/1.1
persistent connections, as of version 0.3.

Contents:

- BaseHTTPRequestHandler: HTTP request handler base class
- test: test function

XXX To do:

- log requests even later (to capture byte count)
- log user-agent header and other interesting goodies
- send error log to separate file
"""

# See also:
#
# HTTP Working Group                                        T. Berners-Lee
# INTERNET-DRAFT                                            R. T. Fielding
# <draft-ietf-http-v10-spec-00.txt>                     H. Frystyk Nielsen
# Expires September 8, 1995                                  March 8, 1995
#
# URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt
#
# and
#
# Network Working Group                                      R. Fielding
# Request for Comments: 2616                                       et al
# Obsoletes: 2068                                              June 1999
# Category: Standards Track
#
# URL: http://www.faqs.org/rfcs/rfc2616.html

# Log files
# ---------
#
# Here's a quote from the NCSA httpd docs about log file format.
#
# | The logfile format is as follows. Each line consists of:
# |
# | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb
# |
# |        host: Either the DNS name or the IP number of the remote client
# |        rfc931: Any information returned by identd for this person,
# |                - otherwise.
# |        authuser: If user sent a userid for authentication, the user name,
# |                  - otherwise.
# |        DD: Day
# |        Mon: Month (calendar name)
# |        YYYY: Year
# |        hh: hour (24-hour format, the machine's timezone)
# |        mm: minutes
# |        ss: seconds
# |        request: The first line of the HTTP request as sent by the client.
# |        ddd: the status code returned by the server, - if not available.
# |        bbbb: the total number of bytes sent,
# |              *not including the HTTP/1.0 header*, - if not available
# |
# | You can determine the name of the file accessed through request.
#
# (Actually, the latter is only true if you know the server configuration
# at the time the request was made!)

__version__ = "0.3"

__all__ = ["HTTPServer", "BaseHTTPRequestHandler"]

import sys
import time
import socket # For gethostbyaddr()
from warnings import filterwarnings, catch_warnings
with catch_warnings():
    if sys.py3kwarning:
        filterwarnings("ignore", ".*mimetools has been removed",
                        DeprecationWarning)
    import mimetools
import SocketServer

# Default error message template
DEFAULT_ERROR_MESSAGE = """\

<title>Error response</title>

Error response

Error code %(code)d.

Message: %(message)s.

Error code explanation: %(code)s = %(explain)s.

"""

DEFAULT_ERROR_CONTENT_TYPE = "text/html"

def _quote_html(html):
    return html.replace("&", "&").replace("<", "<").replace(">", ">")

class HTTPServer(SocketServer.TCPServer):

    allow_reuse_address = 1    # Seems to make sense in testing environment

    def server_bind(self):
        """Override server_bind to store the server name."""
        SocketServer.TCPServer.server_bind(self)
        host, port = self.socket.getsockname()[:2]
        self.server_name = socket.getfqdn(host)
        self.server_port = port

class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):

    """HTTP request handler base class.

    The following explanation of HTTP serves to guide you through the
    code as well as to expose any misunderstandings I may have about
    HTTP (so you don't need to read the code to figure out I'm wrong
    :-).

    HTTP (HyperText Transfer Protocol) is an extensible protocol on
    top of a reliable stream transport (e.g. TCP/IP).  The protocol
    recognizes three parts to a request:

    1. One line identifying the request type and path
    2. An optional set of RFC-822-style headers
    3. An optional data part

    The headers and data are separated by a blank line.

    The first line of the request has the form

    <command> <path> <version>

    where <command> is a (case-sensitive) keyword such as GET or POST,
    <path> is a string containing path information for the request,
    and <version> should be the string "HTTP/1.0" or "HTTP/1.1".
    <path> is encoded using the URL encoding scheme (using %xx to signify
    the ASCII character with hex code xx).

    The specification specifies that lines are separated by CRLF but
    for compatibility with the widest range of clients recommends
    servers also handle LF.  Similarly, whitespace in the request line
    is treated sensibly (allowing multiple spaces between components
    and allowing trailing whitespace).

    Similarly, for output, lines ought to be separated by CRLF pairs
    but most clients grok LF characters just fine.

    If the first line of the request has the form

    <command> <path>

    (i.e. <version> is left out) then this is assumed to be an HTTP
    0.9 request; this form has no optional headers and data part and
    the reply consists of just the data.

    The reply form of the HTTP 1.x protocol again has three parts:

    1. One line giving the response code
    2. An optional set of RFC-822-style headers
    3. The data

    Again, the headers and data are separated by a blank line.

    The response code line has the form

    <version> <responsecode> <responsestring>

    where <version> is the protocol version ("HTTP/1.0" or "HTTP/1.1"),
    <responsecode> is a 3-digit response code indicating success or
    failure of the request, and <responsestring> is an optional
    human-readable string explaining what the response code means.

    This server parses the request and the headers, and then calls a
    function specific to the request type (<command>).  Specifically,
    a request SPAM will be handled by a method do_SPAM().  If no
    such method exists the server sends an error response to the
    client.  If it exists, it is called with no arguments:

    do_SPAM()

    Note that the request name is case sensitive (i.e. SPAM and spam
    are different requests).

    The various request details are stored in instance variables:

    - client_address is the client IP address in the form (host,
    port);

    - command, path and version are the broken-down request line;

    - headers is an instance of mimetools.Message (or a derived
    class) containing the header information;

    - rfile is a file object open for reading positioned at the
    start of the optional input data part;

    - wfile is a file object open for writing.

    IT IS IMPORTANT TO ADHERE TO THE PROTOCOL FOR WRITING!

    The first thing to be written must be the response line.  Then
    follow 0 or more header lines, then a blank line, and then the
    actual data (if any).  The meaning of the header lines depends on
    the command executed by the server; in most cases, when data is
    returned, there should be at least one header line of the form

    Content-type: <type>/<subtype>

    where <type> and <subtype> should be registered MIME types,
    e.g. "text/html" or "text/plain".

    """

    # The Python system version, truncated to its first component.
    sys_version = "Python/" + sys.version.split()[0]

    # The server software version.  You may want to override this.
    # The format is multiple whitespace-separated strings,
    # where each string is of the form name[/version].
    server_version = "BaseHTTP/" + __version__

    # The default request version.  This only affects responses up until
    # the point where the request line is parsed, so it mainly decides what
    # the client gets back when sending a malformed request line.
    # Most web servers default to HTTP 0.9, i.e. don't send a status line.
    default_request_version = "HTTP/0.9"

    def parse_request(self):
        """Parse a request (internal).

        The request should be stored in self.raw_requestline; the results
        are in self.command, self.path, self.request_version and
        self.headers.

        Return True for success, False for failure; on failure, an
        error is sent back.

        """
        self.command = None  # set in case of error on the first line
        self.request_version = version = self.default_request_version
        self.close_connection = 1
        requestline = self.raw_requestline
        if requestline[-2:] == '\r\n':
            requestline = requestline[:-2]
        elif requestline[-1:] == '\n':
            requestline = requestline[:-1]
        self.requestline = requestline
        words = requestline.split()
        if len(words) == 3:
            [command, path, version] = words
            if version[:5] != 'HTTP/':
                self.send_error(400, "Bad request version (%r)" % version)
                return False
            try:
                base_version_number = version.split('/', 1)[1]
                version_number = base_version_number.split(".")
                # RFC 2145 section 3.1 says there can be only one "." and
                #   - major and minor numbers MUST be treated as
                #      separate integers;
                #   - HTTP/2.4 is a lower version than HTTP/2.13, which in
                #      turn is lower than HTTP/12.3;
                #   - Leading zeros MUST be ignored by recipients.
                if len(version_number) != 2:
                    raise ValueError
                version_number = int(version_number[0]), int(version_number[1])
            except (ValueError, IndexError):
                self.send_error(400, "Bad request version (%r)" % version)
                return False
            if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1":
                self.close_connection = 0
            if version_number >= (2, 0):
                self.send_error(505,
                          "Invalid HTTP Version (%s)" % base_version_number)
                return False
        elif len(words) == 2:
            [command, path] = words
            self.close_connection = 1
            if command != 'GET':
                self.send_error(400,
                                "Bad HTTP/0.9 request type (%r)" % command)
                return False
        elif not words:
            return False
        else:
            self.send_error(400, "Bad request syntax (%r)" % requestline)
            return False
        self.command, self.path, self.request_version = command, path, version

        # Examine the headers and look for a Connection directive
        self.headers = self.MessageClass(self.rfile, 0)

        conntype = self.headers.get('Connection', "")
        if conntype.lower() == 'close':
            self.close_connection = 1
        elif (conntype.lower() == 'keep-alive' and
              self.protocol_version >= "HTTP/1.1"):
            self.close_connection = 0
        return True

    def handle_one_request(self):
        """Handle a single HTTP request.

        You normally don't need to override this method; see the class
        __doc__ string for information on how to handle specific HTTP
        commands such as GET and POST.

        """
        self.raw_requestline = self.rfile.readline()
        if not self.raw_requestline:
            self.close_connection = 1
            return
        if not self.parse_request(): # An error code has been sent, just exit
            return
        mname = 'do_' + self.command
        if not hasattr(self, mname):
            self.send_error(501, "Unsupported method (%r)" % self.command)
            return
        method = getattr(self, mname)
        method()

    def handle(self):
        """Handle multiple requests if necessary."""
        self.close_connection = 1

        self.handle_one_request()
        while not self.close_connection:
            self.handle_one_request()

    def send_error(self, code, message=None):
        """Send and log an error reply.

        Arguments are the error code, and a detailed message.
        The detailed message defaults to the short entry matching the
        response code.

        This sends an error response (so it must be called before any
        output has been generated), logs the error, and finally sends
        a piece of HTML explaining the error to the user.

        """

        try:
            short, long = self.responses[code]
        except KeyError:
            short, long = '???', '???'
        if message is None:
            message = short
        explain = long
        self.log_error("code %d, message %s", code, message)
        # using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201)
        content = (self.error_message_format %
                   {'code': code, 'message': _quote_html(message), 'explain': explain})
        self.send_response(code, message)
        self.send_header("Content-Type", self.error_content_type)
        self.send_header('Connection', 'close')
        self.end_headers()
        if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
            self.wfile.write(content)

    error_message_format = DEFAULT_ERROR_MESSAGE
    error_content_type = DEFAULT_ERROR_CONTENT_TYPE

    def send_response(self, code, message=None):
        """Send the response header and log the response code.

        Also send two standard headers with the server software
        version and the current date.

        """
        self.log_request(code)
        if message is None:
            if code in self.responses:
                message = self.responses[code][0]
            else:
                message = ''
        if self.request_version != 'HTTP/0.9':
            self.wfile.write("%s %d %s\r\n" %
                             (self.protocol_version, code, message))
            # print (self.protocol_version, code, message)
        self.send_header('Server', self.version_string())
        self.send_header('Date', self.date_time_string())

    def send_header(self, keyword, value):
        """Send a MIME header."""
        if self.request_version != 'HTTP/0.9':
            self.wfile.write("%s: %s\r\n" % (keyword, value))

        if keyword.lower() == 'connection':
            if value.lower() == 'close':
                self.close_connection = 1
            elif value.lower() == 'keep-alive':
                self.close_connection = 0

    def end_headers(self):
        """Send the blank line ending the MIME headers."""
        if self.request_version != 'HTTP/0.9':
            self.wfile.write("\r\n")

    def log_request(self, code='-', size='-'):
        """Log an accepted request.

        This is called by send_response().

        """

        self.log_message('"%s" %s %s',
                         self.requestline, str(code), str(size))

    def log_error(self, format, *args):
        """Log an error.

        This is called when a request cannot be fulfilled.  By
        default it passes the message on to log_message().

        Arguments are the same as for log_message().

        XXX This should go to the separate error log.

        """

        self.log_message(format, *args)

    def log_message(self, format, *args):
        """Log an arbitrary message.

        This is used by all other logging functions.  Override
        it if you have specific logging wishes.

        The first argument, FORMAT, is a format string for the
        message to be logged.  If the format string contains
        any % escapes requiring parameters, they should be
        specified as subsequent arguments (it's just like
        printf!).

        The client host and current date/time are prefixed to
        every message.

        """

        sys.stderr.write("%s - - [%s] %s\n" %
                         (self.address_string(),
                          self.log_date_time_string(),
                          format%args))

    def version_string(self):
        """Return the server software version string."""
        return self.server_version + ' ' + self.sys_version

    def date_time_string(self, timestamp=None):
        """Return the current date and time formatted for a message header."""
        if timestamp is None:
            timestamp = time.time()
        year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp)
        s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
                self.weekdayname[wd],
                day, self.monthname[month], year,
                hh, mm, ss)
        return s

    def log_date_time_string(self):
        """Return the current time formatted for logging."""
        now = time.time()
        year, month, day, hh, mm, ss, x, y, z = time.localtime(now)
        s = "%02d/%3s/%04d %02d:%02d:%02d" % (
                day, self.monthname[month], year, hh, mm, ss)
        return s

    weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']

    monthname = [None,
                 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
                 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

    def address_string(self):
        """Return the client address formatted for logging.

        This version looks up the full hostname using gethostbyaddr(),
        and tries to find a name that contains at least one dot.

        """

        host, port = self.client_address[:2]
        return socket.getfqdn(host)

    # Essentially static class variables

    # The version of the HTTP protocol we support.
    # Set this to HTTP/1.1 to enable automatic keepalive
    protocol_version = "HTTP/1.0"

    # The Message-like class used to parse headers
    MessageClass = mimetools.Message

    # Table mapping response codes to messages; entries have the
    # form {code: (shortmessage, longmessage)}.
    # See RFC 2616.
    responses = {
        100: ('Continue', 'Request received, please continue'),
        101: ('Switching Protocols',
              'Switching to new protocol; obey Upgrade header'),

        200: ('OK', 'Request fulfilled, document follows'),
        201: ('Created', 'Document created, URL follows'),
        202: ('Accepted',
              'Request accepted, processing continues off-line'),
        203: ('Non-Authoritative Information', 'Request fulfilled from cache'),
        204: ('No Content', 'Request fulfilled, nothing follows'),
        205: ('Reset Content', 'Clear input form for further input.'),
        206: ('Partial Content', 'Partial content follows.'),

        300: ('Multiple Choices',
              'Object has several resources -- see URI list'),
        301: ('Moved Permanently', 'Object moved permanently -- see URI list'),
        302: ('Found', 'Object moved temporarily -- see URI list'),
        303: ('See Other', 'Object moved -- see Method and URL list'),
        304: ('Not Modified',
              'Document has not changed since given time'),
        305: ('Use Proxy',
              'You must use proxy specified in Location to access this '
              'resource.'),
        307: ('Temporary Redirect',
              'Object moved temporarily -- see URI list'),

        400: ('Bad Request',
              'Bad request syntax or unsupported method'),
        401: ('Unauthorized',
              'No permission -- see authorization schemes'),
        402: ('Payment Required',
              'No payment -- see charging schemes'),
        403: ('Forbidden',
              'Request forbidden -- authorization will not help'),
        404: ('Not Found', 'Nothing matches the given URI'),
        405: ('Method Not Allowed',
              'Specified method is invalid for this server.'),
        406: ('Not Acceptable', 'URI not available in preferred format.'),
        407: ('Proxy Authentication Required', 'You must authenticate with '
              'this proxy before proceeding.'),
        408: ('Request Timeout', 'Request timed out; try again later.'),
        409: ('Conflict', 'Request conflict.'),
        410: ('Gone',
              'URI no longer exists and has been permanently removed.'),
        411: ('Length Required', 'Client must specify Content-Length.'),
        412: ('Precondition Failed', 'Precondition in headers is false.'),
        413: ('Request Entity Too Large', 'Entity is too large.'),
        414: ('Request-URI Too Long', 'URI is too long.'),
        415: ('Unsupported Media Type', 'Entity body in unsupported format.'),
        416: ('Requested Range Not Satisfiable',
              'Cannot satisfy request range.'),
        417: ('Expectation Failed',
              'Expect condition could not be satisfied.'),

        500: ('Internal Server Error', 'Server got itself in trouble'),
        501: ('Not Implemented',
              'Server does not support this operation'),
        502: ('Bad Gateway', 'Invalid responses from another server/proxy.'),
        503: ('Service Unavailable',
              'The server cannot process the request due to a high load'),
        504: ('Gateway Timeout',
              'The gateway server did not receive a timely response'),
        505: ('HTTP Version Not Supported', 'Cannot fulfill request.'),
        }

def test(HandlerClass = BaseHTTPRequestHandler,
         ServerClass = HTTPServer, protocol="HTTP/1.0"):
    """Test the HTTP request handler class.

    This runs an HTTP server on port 8000 (or the first command line
    argument).

    """

    if sys.argv[1:]:
        port = int(sys.argv[1])
    else:
        port = 8000
    server_address = ('', port)

    HandlerClass.protocol_version = protocol
    httpd = ServerClass(server_address, HandlerClass)

    sa = httpd.socket.getsockname()
    print "Serving HTTP on", sa[0], "port", sa[1], "..."
    httpd.serve_forever()

if __name__ == '__main__':
    test()