text:
package org.apereo.cas.support.saml;

import org.apereo.cas.audit.AuditableContext;
import org.apereo.cas.audit.AuditableExecution;
import org.apereo.cas.authentication.BaseAuthenticationServiceSelectionStrategy;
import org.apereo.cas.authentication.principal.Service;
import org.apereo.cas.authentication.principal.ServiceFactory;
import org.apereo.cas.authentication.principal.WebApplicationService;
import org.apereo.cas.services.ServicesManager;
import org.apereo.cas.util.EncodingUtils;
import org.apereo.cas.util.LoggingUtils;
import org.apereo.cas.web.support.WebUtils;

import com.google.common.base.Splitter;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.http.client.utils.URIBuilder;

import java.util.Arrays;
import java.util.Optional;

/**
 * This is {@link ShibbolethIdPEntityIdAuthenticationServiceSelectionStrategy}.
 *
 * @author Misagh Moayyed
 * @since 5.0.0
 */
@Slf4j
@Getter
public class ShibbolethIdPEntityIdAuthenticationServiceSelectionStrategy extends BaseAuthenticationServiceSelectionStrategy {
    private static final long serialVersionUID = -2059445756475980894L;

    private final String idpServerPrefix;

    private final transient AuditableExecution registeredServiceAccessStrategyEnforcer;

    public ShibbolethIdPEntityIdAuthenticationServiceSelectionStrategy(final ServicesManager servicesManager,
        final ServiceFactory<WebApplicationService> webApplicationServiceFactory, final String idpServerPrefix,
        final AuditableExecution registeredServiceAccessStrategyEnforcer) {
        super(servicesManager, webApplicationServiceFactory);
        this.idpServerPrefix = idpServerPrefix;
        this.registeredServiceAccessStrategyEnforcer = registeredServiceAccessStrategyEnforcer;
    }

    /**
     * Method attempts to resolve the service from the entityId parameter.  If present, an attempt is made
     * to find a service corresponding to the entityId in the Service Registry.  If a service is not resolved from
     * a passed entity id, the service= parameter of the request will be returned instead.  This is usually the
     * callback url to the external Shibboleth IdP.
     *
     * @param service the provided service by the caller
     * @return - the resolved service.
     */
    @Override
    public Service resolveServiceFrom(final Service service) {
        val result = getEntityIdAsParameter(service);
        if (result.isPresent()) {
            val entityId = result.get();
            LOGGER.debug("Located entity id [{}] from service authentication request at [{}]", entityId, service.getId());
            if (isEntityIdServiceRegistered(entityId, service)) {
                return createService(entityId, service);
            }
            LOGGER.debug("Entity id [{}] not registered as individual service", entityId);
        }
        LOGGER.debug("Could not located entity id from service authentication request at [{}]", service.getId());
        return service;
    }

    @Override
    public boolean supports(final Service service) {
        val casPattern = "^".concat(idpServerPrefix).concat(".*");
        return service != null && service.getId().matches(casPattern) && getEntityIdAsParameter(service).isPresent();
    }

    /**
     * Gets entity id as parameter.
     *
     * @param service the service
     * @return the entity id as parameter
     */
    protected static Optional<String> getEntityIdAsParameter(final Service service) {
        try {
            val builder = new URIBuilder(service.getId());
            val param = builder.getQueryParams()
                .stream()
                .filter(p -> p.getName().equals(SamlProtocolConstants.PARAMETER_ENTITY_ID))
                .findFirst();

            if (param.isPresent()) {
                LOGGER.debug("Found entity Id in service id [{}]", param.get().getValue());
                return Optional.of(param.get().getValue());
            }
            val request = WebUtils.getHttpServletRequestFromExternalWebflowContext();
            if (request != null && StringUtils.isNotBlank(request.getQueryString())) {
                val query = request.getQueryString().split("&");
                val paramRequest = Arrays.stream(query)
                    .map(p -> {
                        var params = Splitter.on("=").splitToList(p);
                        return Pair.of(params.get(0), params.get(1));
                    })
                    .filter(p -> p.getKey().equals(SamlProtocolConstants.PARAMETER_ENTITY_ID))
                    .map(Pair::getValue)
                    .map(EncodingUtils::urlDecode)
                    .findFirst();
                LOGGER.debug("Found entity id as part of request url [{}]", paramRequest);
                return paramRequest;
            }
        } catch (final Exception e) {
            LoggingUtils.error(LOGGER, e);
        }
        return Optional.empty();
    }

    private boolean isEntityIdServiceRegistered(final String entityId, final Service original) {
        val service = createService(entityId, original);
        val registeredService = getServicesManager().findServiceBy(service);
        val audit = AuditableContext.builder()
            .registeredService(registeredService)
            .build();
        return !registeredServiceAccessStrategyEnforcer.execute(audit).isExecutionFailure();
    }
}


text:
module Gena

  class Config

    @data = {}

    def Config.exists?
      File.exists?('gena.plist')
    end

    def Config.create
      hash = Hash.new
      hash[:plugins_url] = [
          '~/Development/gena-plugins'
      ]
      hash['sources_dir'] = '/Users/alex/Development/fisho-ios/Sources'

      File.open('gena.plist', 'w') { |f| f.write hash.to_plist }
    end

    def save!
      File.open('gena.plist', 'w') { |f| f.write self.data.to_plist }
    end

    def load_plist_config
      @data = Plist::parse_xml('gena.plist')
    end

    def data
      @data
    end

    def data=(new_data)
      @data = new_data
    end

    def data_without_plugins
      @data.reject { |k, v| k == GENA_PLUGINS_CONFIG_KEY }
    end

    def header_dir
      if @data['header'] && !@data['header'].empty?
        expand_to_project(@data['header'])
      else
        ''
      end
    end

    def project_dir
      File.expand_path((!self.data['project_dir'] || self.data['project_dir'].empty?)? '.' : self.data['project_dir'])
    end

    def expand_to_project(path)
      if path[0] == '/'
        path
      else
        File.join(self.project_dir, path)
      end
    end

    def collapse_to_project(path)
      if path[0] == '/'
        path = path.dup
        path["#{$config.project_dir}/"] = ''
      end
      path
    end

    def sources_dir
      self.expand_to_project(self.data['sources_dir'])
    end

    def tests_dir
      self.expand_to_project(self.data['tests_dir'])
    end

    def xcode_project_path
      path = self.expand_to_project("#{@data['project_name']}.xcodeproj")
      unless File.exists? path
        say "Can't find project with name '#{@data['project_name']}.xcodeproj''", Color::RED
        abort
      end
      path
    end

  end

end

redpajama_set_name: RedPajamaGithub


text:
function scbg(objRef, state) {
	objRef.style.backgroundColor = (1 == state) ? '#eefcff' : '#fff';
	return;
}

  			var testimonials = new Array();
            var current_testimonial = 0;

            testimonials[0] = "Good day you guys!
— Happy Children's Day!
";
            testimonials[1] = "Good day you guys!
— Happy Dragon Boat Festival!
";
            testimonials[2] = "Good day you guys!
— Summer solstice on June 19th.";

            function display_next_testimonial() {
                if (current_testimonial + 1 >= testimonials.length) {
                    current_testimonial = 0;
                } else {
                    current_testimonial++;
                }

                new Effect.Fade('headerquote', {duration:.3});

                window.setTimeout("$('headerquote').innerHTML = testimonials[current_testimonial];"+ " new Effect.Appear('headerquote', {duration:.3});",300);
            }

            setInterval('display_next_testimonial();', 5000);


text:
package com.infinityraider.settlercraft.settlement.building.townhall;

import com.infinityraider.settlercraft.api.v1.IBuilding;
import com.infinityraider.settlercraft.api.v1.IBuildingTownHall;
import com.infinityraider.settlercraft.api.v1.ISettlement;
import com.infinityraider.settlercraft.settlement.building.BuildingTypeBase;

public class BuildingTypeTownHall extends BuildingTypeBase {
    public BuildingTypeTownHall() {
        super("town_hall");
    }

    @Override
    public int maximumBuildingCountPerSettlement(ISettlement settlement) {
        return 1;
    }

    @Override
    public boolean addNewBuilding(IBuilding building) {
        return (building instanceof IBuildingTownHall) && super.addNewBuilding(building);
    }
}


text:
package com.amazonaws.services.simpleworkflow.model;

import java.io.Serializable;

/**
 *

 * Specifies the runId of a workflow execution.
 *

 */
public class Run implements Serializable, Cloneable {

    /**
     * The runId of a workflow execution. This ID is generated
     * by the service and can be used to uniquely identify the workflow
     * execution within a domain.
     *

     * Constraints:

     * Length: 1 - 64

     */
    private String runId;

    /**
     * The runId of a workflow execution. This ID is generated
     * by the service and can be used to uniquely identify the workflow
     * execution within a domain.
     *

     * Constraints:

     * Length: 1 - 64

     *
     * @return The runId of a workflow execution. This ID is generated
     *         by the service and can be used to uniquely identify the workflow
     *         execution within a domain.
     */
    public String getRunId() {
        return runId;
    }

    /**
     * The runId of a workflow execution. This ID is generated
     * by the service and can be used to uniquely identify the workflow
     * execution within a domain.
     *

     * Constraints:

     * Length: 1 - 64

     *
     * @param runId The runId of a workflow execution. This ID is generated
     *         by the service and can be used to uniquely identify the workflow
     *         execution within a domain.
     */
    public void setRunId(String runId) {
        this.runId = runId;
    }

    /**
     * The runId of a workflow execution. This ID is generated
     * by the service and can be used to uniquely identify the workflow
     * execution within a domain.
     *

     * Returns a reference to this object so that method calls can be chained together.
     *

     * Constraints:

     * Length: 1 - 64

     *
     * @param runId The runId of a workflow execution. This ID is generated
     *         by the service and can be used to uniquely identify the workflow
     *         execution within a domain.
     *
     * @return A reference to this updated object so that method calls can be chained
     *         together.
     */
    public Run withRunId(String runId) {
        this.runId = runId;
        return this;
    }

    /**
     * Returns a string representation of this object; useful for testing and
     * debugging.
     *
     * @return A string representation of this object.
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        if (getRunId() != null) sb.append("RunId: " + getRunId() );
        sb.append("}");
        return sb.toString();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int hashCode = 1;

        hashCode = prime * hashCode + ((getRunId() == null) ? 0 : getRunId().hashCode());
        return hashCode;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;

        if (obj instanceof Run == false) return false;
        Run other = (Run)obj;

        if (other.getRunId() == null ^ this.getRunId() == null) return false;
        if (other.getRunId() != null && other.getRunId().equals(this.getRunId()) == false) return false;
        return true;
    }

    @Override
    public Run clone() {
        try {
            return (Run) super.clone();

        } catch (CloneNotSupportedException e) {
            throw new IllegalStateException(
                    "Got a CloneNotSupportedException from Object.clone() "
                    + "even though we're Cloneable!",
                    e);
        }

    }

}


text:
//
//  RCDLiveMessageBaseCell.h
//  RongIMKit
//
//  Created by xugang on 15/1/28.
//  Copyright (c) 2015年 RongCloud. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <RongIMLib/RongIMLib.h>
#import "RCDLiveMessageModel.h"
#import "RCDLiveMessageCellNotificationModel.h"
#import "RCDLiveMessageCellDelegate.h"
#import "RCDLiveTipLabel.h"

/*!
 消息发送状态更新的Notification
 */
UIKIT_EXTERN NSString *const RCDLiveNotificationMessageBaseCellUpdateSendingStatus;

/*!
 消息Cell基类

 @discussion 消息Cell基类包含了所有消息Cell的必要信息。
 消息Cell基类针对用户头像是否显示,主要可以分为两类的:
 一是提醒类的Cell,不显示用户信息,如:RCDLiveTipMessageCell和RCUnknownMessageCell;
 二是展示类的Cell,显示用户信息和内容,如:RCDLiveMessageCell以及RCDLiveMessageCell的子类。
 */
@interface RCDLiveMessageBaseCell : UICollectionViewCell

/*!
 消息Cell点击回调
 */
@property(nonatomic, weak) id<RCDLiveMessageCellDelegate> delegate;

/*!
 显示时间的Label
 */
@property(strong, nonatomic) RCDLiveTipLabel *messageTimeLabel;

/*!
 消息Cell的数据模型
 */
@property(strong, nonatomic) RCDLiveMessageModel *model;

/*!
 Cell显示的View
 */
@property(strong, nonatomic) UIView *baseContentView;

/*!
 消息的方向
 */
@property(nonatomic) RCMessageDirection messageDirection;

/*!
 时间Label是否显示
 */
@property(nonatomic, readonly) BOOL isDisplayMessageTime;

/*!
 是否显示阅读状态
 */
@property(nonatomic) BOOL isDisplayReadStatus;

/*!
 初始化消息Cell

 @param frame 显示的Frame
 @return 消息Cell基类对象
 */
- (instancetype)initWithFrame:(CGRect)frame;

/*!
 设置当前消息Cell的数据模型

 @param model 消息Cell的数据模型
 */
- (void)setDataModel:(RCDLiveMessageModel *)model;

/*!
 消息发送状态更新的监听回调

 @param notification 消息发送状态更新的Notification
 */
- (void)messageCellUpdateSendingStatusEvent:(NSNotification *)notification;

@end


text:
#ifndef SYSTEM_H
#define SYSTEM_H
#include "integrator.h"
#include "analysisManager.h"

using namespace std;

namespace PSim {

/**
 * @class system
 * @author Sawyer Hopkins
 * @date 06/27/15
 * @file system.h
 * @brief Frontend wrapper for running simulations.
 */
class system {

private:

	/********************************************//**
	 *-----------------SYSTEM VARIABLES---------------
	 ***********************************************/

	//Information about the system.
	systemState state;

	//Settings flags
	double cycleHour;
	int seedSize;

	//System entities.
	particle** particles;
	//Particle entities
	vector<tuple<int,int>> particleHashIndex;
	vector<tuple<int,int>> cellStartEnd;
	double* sortedParticles;
	double* particleForce;

	//System integrator.
	PSim::IIntegrator* integrator;
	PSim::defaultForceManager* sysForces;

	/********************************************//**
	 *-------------------SYSTEM INIT------------------
	 ***********************************************/

	/**
	 * @brief Creates an initial uniform distribution of particles.
	 * @param r The radius of the particles
	 * @param m The mass of the particles.
	 */
	void initParticles(double r, double m);
	/**
	 * @brief Creates a maxwell distribution of velocities for the system temperature.
	 * @param gen The random generator the initalize particles.
	 * @param distribution The distribution for the particles.
	 */
	void maxwellVelocityInit(std::mt19937* gen,
			std::uniform_real_distribution<double>* distribution);
	/**
	 * @brief Fixes any particle overlap in the random initalization.
	 * @param gen The random generator the initalize particles.
	 * @param distribution The distribution for the particles.
	 */
	void initCheck(std::mt19937* gen,
			std::uniform_real_distribution<double>* distribution);
	/**
	 * @brief Get input for working directory. Create if needed.
	 * @return The working directory
	 */
	static std::string dirPrompt();
	/**
	 * @brief Check that the provided path is a valid directory.
	 * @param path Directory path
	 * @return True is the path is valid.
	 */
	static bool checkDir(std::string path);

	/********************************************//**
	 *-----------------SYSTEM HANDLING----------------
	 ***********************************************/

	/**
	 * @brief Updates the cells that the particles are located in.
	 * @return
	 */
	void pushParticleForce();
	void iterateParticleInteractions(int index, int hash);

	/********************************************//**
	 *----------------REFACTORING DUMP---------------
	 ***********************************************/

	void verifyPath();
	void estimateCompletion(PSim::timer* tmr);
	void writeToStream(string path, double value);
	void setSystemConstants(config* cfg,
			PSim::IIntegrator* sysInt, PSim::defaultForceManager* sysFcs);

public:

	//Header Version.
	static const int version = 1;

	//Trial name
	std::string trialName;

	//Analysis system
	PSim::IAnalysisManager* analysis;

	/********************************************//**
	 *---------------SYSTEM CONSTRUCTION--------------
	 ***********************************************/

	/**
	 * @brief Constructs the particle system.
	 * @return Nothing.
	 */
	system(config* cfg, PSim::IIntegrator* sysInt,
			PSim::defaultForceManager* sysFcs, std::string tName = "");
	/**
	 * @brief Destructs the particle system.
	 * @return Nothing.
	 */
	~system();

	/********************************************//**
	 *-----------------SYSTEM GETTERS-----------------
	 ***********************************************/

	/**
	 * @brief Gets the number of particles in the system.
	 * @return Number of particles.
	 */
	const int getNParticles() const {
		return state.nParticles;
	}
	/**
	 * @brief Gets the length of the system box.
	 * @return length of the system box.
	 */
	const int getBoxSize() const {
		return state.boxSize;
	}
	/**
	 * @brief Gets the length of a system cell.
	 * @return cellSize.
	 */
	const int getCellSize() const {
		return state.cellSize;
	}

	/********************************************//**
	 *-----------------SYSTEM HANDLING----------------
	 ***********************************************/

	/**
	 * @brief Runs the system.
	 * @param endTime When to stop running the simulation.
	 */
	void run(double endTime);
	void hashParticles();
	void sortParticles();
	void clearCells() { std::fill(cellStartEnd.begin(), cellStartEnd.end(), tuple<int,int>(0xffffffff, 0xffffffff)); };
	void reorderParticles();
	void updateInteractions();

	/********************************************//**
	 *------------------SYSTEM OUTPUT-----------------
	 ***********************************************/

	/**
	 * @brief Writes the position of a particle.
	 * @param index The index of the particle to write.
	 */
	void writePosition(int index) {
		particles[index]->writePosition();
	}
	/**
	 * @brief Write the initial system parameters.
	 */
	void writeSystemInit();

	/********************************************//**
	 *-----------------SYSTEM RECOVERY----------------
	 ***********************************************/

	/**
	 * @brief Find the number of line in a file.
	 */
	int particlesInFile(std::string sysState, std::string timeStamp);
	/**
	 * @brief Read in the sysConfig file.
	 */
	void readSettings(config* cfg);
	/**
	 * @brief Load a system with particle data from file.
	 */
	int readParticles(std::string sysState, std::string timeStamp);
	/**
	 * @brief Attempt to create the correct directory for rewind.
	 */
	void createRewindDir();

	/********************************************//**
	 *-----------------SYSTEM ANALYSIS----------------
	 ***********************************************/

	/**
	 * @return Gets the default analysis interface for the system.
	 */
	PSim::IAnalysisManager* defaultAnalysisInterface() { return new PSim::analysisManager(trialName, &state); }
	/**
	 * @brief Runs the tests and analysis provided in the input string.
	 * @param tests
	 */
	void analysisManager(std::queue<std::string>* tests) { analysis->postAnalysis(tests, particles, &state); }
	/**
	 *
	 * @brief Sets a new time step. Use with caution.
	 *
	 */
	double setdTime(double dt) {
		double old = state.dTime;
		state.dTime = dt;
		return old;
	}
	/**
	 *
	 * @brief Sets a new temperature parameter. Use with caution.
	 *
	 */
	double setSysTemp(double val) {
		double old = state.temp;
		state.temp = val;
		return old;
	}
	/********************************************//**
	 *---------------VERSION CONTROL-----------------
	 ***********************************************/

	/**
	 * @brief Gets the flagged version of config.h for debugging.
	 * @return
	 */
	int getConfigVersion() {
		return config::version;
	}
	/**
	 * @brief Gets the flagged version of error.h for debugging.
	 * @return
	 */
	int getErrorVersion() {
		return PSim::error::version;
	}
	/**
	 * @brief Gets the flagged version of force.h before debugging.
	 * @return
	 */
	int getForceVersion() {
		return PSim::IForce::version;
	}
	/**
	 * @brief Gets the flagged version of particle.h for debugging.
	 * @return
	 */
	int getParticleVersion() {
		return PSim::particle::version;
	}
	/**
	 * @brief Gets the flagged version of timer.h for debugging.
	 * @return
	 */
	int getTimerVersion() {
		return PSim::timer::version;
	}
	/**
	 * @brief Gets the flagged version of utilities.h for debugging.
	 * @return
	 */
	int getUtilitiesVersion() {
		return PSim::util::version;
	}
	/**
	 * @brief Gets the flagged version of the integrator for debugging..
	 * @return
	 */
	int getIntegratorVersion() {
		return PSim::IIntegrator::version;
	}
	/**
	 * @brief Gets the flagged version of system.h for debugging.
	 * @return
	 */
	int getSystemVersion() {
		return version;
	}

};

}

#endif // SYSTEM_H


text:
package strategyPattern;

import java.util.Comparator;

public class PersonComparatorByName implements Comparator<Person> {
    @Override
    public int compare(Person firstPerson, Person secondPerson) {
        if (Integer.compare(firstPerson.getName().length(), secondPerson.getName().length()) == 0) {
            return firstPerson.getName().compareToIgnoreCase(secondPerson.getName());
        }
        return Integer.compare(firstPerson.getName().length(), secondPerson.getName().length());
    }
}


text:
<!DOCTYPE html>
<html>
<title>Service Workers: caches</title>
    <head>
        <link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-global-scope-caches">
        <script src="/resources/testharness.js"></script>
        <script src="/resources/testharnessreport.js"></script>

    </head>
    <body>

<!--

`self.caches` must return the `[CacheStorage][1]` object that is the global
asynchronous map object for the `[ServiceWorkerGlobalScope][2]` execution
context containing the cache objects keyed by the name of the caches. Caches
are always enumerable via `self.caches` in insertion order (per [ECMAScript 6
Map objects][3].)

[1]: #cache-storage-interface
[2]: #service-worker-global-scope-interface
[3]: http://goo.gl/gNnDPO

-->

    <script>
        test(function() {
            // not_implemented();
        }, "There are no tests for section caches so far.");
    </script>

    </body>
</html>


text:
// © 2016 Steve McCoy under the MIT license. See LICENSE for details.

/*
Package tmx provides a struct for parsing the Tiled map editor's TMX map format. See
http://doc.mapeditor.org/reference/tmx-map-format/ .
*/
package tmx

import (
	"bufio"
	"bytes"
	"compress/gzip"
	"compress/zlib"
	"encoding/base64"
	"encoding/binary"
	"encoding/xml"
	"io"
	"strconv"
	"strings"
)

func Decode(r io.Reader) (*Map, error) {
	m := new(Map)
	x := xml.NewDecoder(r)
	err := x.Decode(m)
	if err != nil {
		return nil, err
	}

	for i := range m.Layers {
		err = m.Layers[i].decodeIDs()
		if err != nil {
			return nil, err
		}
	}

	return m, nil
}

type Map struct {
	XMLName         xml.Name `xml:"map"`
	Version         string   `xml:"version,attr"`
	Orientation     string   `xml:"orientation,attr"`
	Width           int      `xml:"width,attr"`
	Height          int      `xml:"height,attr"`
	TileWidth       int      `xml:"tilewidth,attr"`
	TileHeight      int      `xml:"tileheight,attr"`
	BackgroundColor string   `xml:"backgroundcolor,attr"`

	Properties   []Property    `xml:"properties>property"`
	Tilesets     []Tileset     `xml:"tileset"`
	Layers       []Layer       `xml:"layer"`
	ObjectGroups []ObjectGroup `xml:"objectgroup"`
	ImageLayers  []ImageLayer  `xml:"imagelayer"`
}

type Tileset struct {
	FirstGID   int32  `xml:"firstgid,attr"`
	Source     string `xml:"source,attr"`
	Name       string `xml:"name,attr"`
	TileWidth  int    `xml:"tilewidth,attr"`
	TileHeight int    `xml:"tileheight,attr"`
	Spacing    int    `xml:"spacing,attr"`
	Margin     int    `xml:"margin,attr"`

	TileOffset   TileOffset `xml:"tileoffset"`
	Properties   []Property `xml:"properties>property"`
	Image        Image      `xml:"image"`
	TerrainTypes []Terrain  `xml:"terraintypes>terrain"`
}

type TileOffset struct {
	X int `xml:"x,attr"`
	Y int `xml:"y,attr"`
}

type Image struct {
	Format string `xml:"format,attr"`
	Source string `xml:"source,attr"`
	Trans  string `xml:"trans,attr"`
	Width  int    `xml:"width,attr"`
	Height int    `xml:"height,attr"`

	Data Data `xml:"data"`
}

type Terrain struct {
	Name string `xml:"name,attr"`
	Tile int    `xml:"tile,attr"`

	Properties []Property `xml:"properties>property"`
}

type Tile struct {
	ID          int32   `xml:"id,attr"`
	Terrain     string  `xml:"terrain,attr"`
	Probability float32 `xml:"probability,attr"`

	Properties []Property `xml:"properties>property"`
	Image      Image      `xml:"image"`
}

type Layer struct {
	Name    string  `xml:"name,attr"`
	Opacity float32 `xml:"opacity,attr"`
	Visible bool    `xml:"visible,attr"`

	Properties []Property `xml:"properties>property"`
	Data       Data       `xml:"data"`

	// The GID of each tile, in order. Use this instead of raw Data, which is cleaned up by Decode.
	GIDs []int32 `xml:"-"`
}

func (l *Layer) decodeIDs() error {
	d := &l.Data
	if d.Encoding == "csv" {
		r := bufio.NewScanner(strings.NewReader(d.Text))
		for r.Scan() {
			line := r.Text()
			parts := strings.Split(line, ",")
			for _, p := range parts {
				if p == "" {
					continue
				}
				n, err := strconv.ParseInt(p, 10, 32)
				if err != nil {
					return err
				}
				l.GIDs = append(l.GIDs, int32(n))
			}
		}
	} else if d.Encoding == "base64" {
		raw, err := base64.StdEncoding.DecodeString(strings.TrimSpace(d.Text))
		if err != nil {
			return err
		}
		var r io.Reader = bytes.NewReader(raw)
		if d.Compression == "zlib" {
			r, err = zlib.NewReader(r)
		} else if d.Compression == "gzip" {
			r, err = gzip.NewReader(r)
		}
		if err != nil {
			return err
		}
		for {
			var n int32
			err = binary.Read(r, binary.LittleEndian, &n)
			if err == io.EOF {
				break
			}
			if err != nil {
				return err
			}
			l.GIDs = append(l.GIDs, n)
		}
	} else {
		for i := range d.Tiles {
			l.GIDs = append(l.GIDs, d.Tiles[i].GID)
		}
	}

	l.Data = Data{}
	return nil
}

type Data struct {
	Encoding    string `xml:"encoding,attr"`
	Compression string `xml:"compression,attr"`

	Text  string       `xml:",chardata"`
	Tiles []SingleTile `xml:"tile"`
}

type SingleTile struct {
	GID int32 `xml:"gid,attr"`
}

type ObjectGroup struct {
	Name    string  `xml:"name,attr"`
	Color   string  `xml:"color,attr"`
	Opacity float32 `xml:"opacity,attr"`
	Visible bool    `xml:"visible,attr"`

	Properties []Property `xml:"properties>property"`
	Objects    []Object   `xml:"object"`
}

type Object struct {
	Name     string  `xml:"name,attr"`
	Type     string  `xml:"type,attr"`
	X        int     `xml:"x,attr"`
	Y        int     `xml:"y,attr"`
	Width    int     `xml:"width,attr"`
	Height   int     `xml:"height,attr"`
	Rotation float32 `xml:"rotation,attr"`
	GID      int32   `xml:"gid,attr"`
	Visible  bool    `xml:"visible,attr"`

	Properties []Property `xml:"properties>property"`
	Ellipse    *Ellipse   `xml:"ellipse"`
	Polygon    string     `xml:"polygon>points"`
	Polylines  string     `xml:"polyline>points"`
}

type Ellipse struct{}

type ImageLayer struct {
	Name    string  `xml:"name,attr"`
	Opacity float32 `xml:"opacity,attr"`
	Visible bool    `xml:"visible,attr"`

	Properties []Property `xml:"properties>property"`
	Image      Image      `xml:"image"`
}

type Property struct {
	Name  string `xml:"name,attr"`
	Value string `xml:"value,attr"`
}


text:
"""
conference.py -- Udacity conference server-side Python App Engine API;
    uses Google Cloud Endpoints

$Id: conference.py,v 1.25 2014/05/24 23:42:19 wesc Exp wesc $

created by wesc on 2014 apr 21

"""

__author__ = 'wesc+api@google.com (Wesley Chun)'

from datetime import datetime, time
import json
import os
import time

import endpoints
from protorpc import messages
from protorpc import message_types
from protorpc import remote

from google.appengine.api import urlfetch
from google.appengine.ext import ndb
from google.appengine.api import memcache
from google.appengine.api import taskqueue

from models import Profile
from models import ProfileMiniForm
from models import ProfileForm
from models import TeeShirtSize

from utils import getUserId

from settings import WEB_CLIENT_ID

from models import Conference
from models import ConferenceForm

from models import ConferenceForms
from models import ConferenceQueryForm
from models import ConferenceQueryForms

from models import BooleanMessage
from models import ConflictException

from models import StringMessage

from models import Session
from models import SessionForm
from models import SessionForms
from models import SpeakerProperty
from models import SpeakerForm
from models import Speaker
from models import SessionType

from models import TeeShirtSizeForm

CONF_GET_REQUEST = endpoints.ResourceContainer(
    message_types.VoidMessage,
    websafeConferenceKey=messages.StringField(1),
)

SESSION_BYTYPE_GET_REQUEST = endpoints.ResourceContainer(
    message_types.VoidMessage,
    websafeConferenceKey=messages.StringField(1),
    typeOfSession=messages.StringField(2),
)

SESSION_BYSPEAKER_GET_REQUEST = endpoints.ResourceContainer(
    message_types.VoidMessage,
    websafeSpeakerKey=messages.StringField(1),
)

CONF_PUT_REQUEST = endpoints.ResourceContainer(
    ConferenceForm,
    websafeConferenceKey=messages.StringField(1),
)

SESSION_POST_REQUEST = endpoints.ResourceContainer(
    SessionForm,
    websafeConferenceKey=messages.StringField(1),
)

DEFAULTS = {
    "city": "Default City",
    "maxAttendees": 0,
    "seatsAvailable": 0,
    "topics": ["Default", "Topic"],
}

OPERATORS = {
    'EQ':   '=',
    'GT':   '>',
    'GTEQ': '>=',
    'LT':   '<',
    'LTEQ': '<=',
    'NE':   '!='
}

FIELDS = {
    'CITY': 'city',
    'TOPIC': 'topics',
    'MONTH': 'month',
    'MAX_ATTENDEES': 'maxAttendees',
}

EMAIL_SCOPE = endpoints.EMAIL_SCOPE
API_EXPLORER_CLIENT_ID = endpoints.API_EXPLORER_CLIENT_ID

MEMCACHE_ANNOUNCEMENTS_KEY = 'RECENT ANNOUNCEMENTS'
MEMCACHE_SPEAKERS_KEY = 'FEATURED SPEAKERS'

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@endpoints.api(name='conference',
               version='v1',
               allowed_client_ids=[WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID],
               scopes=[EMAIL_SCOPE])
class ConferenceApi(remote.Service):

    """Conference API v0.1"""

# - - - Profile objects - - - - - - - - - - - - - - - - - - -

    def _copyProfileToForm(self, prof):
        """Copy relevant fields from Profile to ProfileForm."""
        # copy relevant fields from Profile to ProfileForm
        pf = ProfileForm()
        for field in pf.all_fields():
            if hasattr(prof, field.name):
                # convert t-shirt string to Enum; just copy others
                if field.name == 'teeShirtSize':
                    setattr(
                        pf, field.name, getattr(TeeShirtSize, getattr(prof, field.name)))  # noqa
                else:
                    setattr(pf, field.name, getattr(prof, field.name))
        pf.check_initialized()
        return pf

    def _getProfileFromUser(self):
        """Return user Profile from datastore, creating new one if non-existent."""  # noqa
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')

        # Get user id by calling getUserId(user)
        user_id = getUserId(user)

        # Create a new key of kind Profile from the id.
        p_key = ndb.Key(Profile, user_id)

        # Get the entity from datastore by using get() on the key
        profile = p_key.get()

        # If profile doesn't exist, we create a new one
        if not profile:
            profile = Profile(
                key=p_key,
                displayName=user.nickname(),
                mainEmail=user.email(),
                teeShirtSize=str(TeeShirtSize.NOT_SPECIFIED),
            )
            # Save the profile to datastore
            profile.put()

        return profile      # return Profile

    def _doProfile(self, save_request=None):
        """Get user Profile and return to user, possibly updating it first."""
        # get user Profile
        prof = self._getProfileFromUser()

        # if saveProfile(), process user-modifyable fields
        if save_request:
            for field in ('displayName', 'teeShirtSize'):
                if hasattr(save_request, field):
                    val = getattr(save_request, field)
                    if val:
                        setattr(prof, field, str(val))
            # Put the modified profile to datastore
            prof.put()

        # return ProfileForm
        return self._copyProfileToForm(prof)

    @endpoints.method(message_types.VoidMessage, ProfileForm,
                      path='profile', http_method='GET', name='getProfile')
    def getProfile(self, request):
        """Return user profile."""
        return self._doProfile()

    @endpoints.method(ProfileMiniForm, ProfileForm,
                      path='profile', http_method='POST', name='saveProfile')
    def saveProfile(self, request):
        """Update & return user profile."""
        return self._doProfile(request)

# - - - Conference objects - - - - - - - - - - - - - - - - -

    def _copyConferenceToForm(self, conf, displayName):
        """Copy relevant fields from Conference to ConferenceForm."""
        cf = ConferenceForm()
        for field in cf.all_fields():
            if hasattr(conf, field.name):
                # convert Date to date string; just copy others
                if field.name.endswith('Date'):
                    setattr(cf, field.name, str(getattr(conf, field.name)))
                else:
                    setattr(cf, field.name, getattr(conf, field.name))
            elif field.name == "websafeKey":
                setattr(cf, field.name, conf.key.urlsafe())
        if displayName:
            setattr(cf, 'organizerDisplayName', displayName)
        cf.check_initialized()
        return cf

    def _createConferenceObject(self, request):
        """Create a Conference object, returning ConferenceForm/request."""  # noqa
        # preload necessary data items
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')
        user_id = getUserId(user)

        if not request.name:
            raise endpoints.BadRequestException(
                "Conference 'name' field required")

        # copy ConferenceForm/ProtoRPC Message into dict
        data = {field.name: getattr(request, field.name)
                for field in request.all_fields()}
        del data['websafeKey']
        del data['organizerDisplayName']

        # add default values for those missing (both data model & outbound
        # Message)
        for df in DEFAULTS:
            if data[df] in (None, []):
                data[df] = DEFAULTS[df]
                setattr(request, df, DEFAULTS[df])

        # convert dates from strings to Date objects; set month based on
        # start_date
        if data['startDate']:
            data['startDate'] = datetime.strptime(
                data['startDate'][:10], "%Y-%m-%d").date()
            data['month'] = data['startDate'].month
        else:
            data['month'] = 0
        if data['endDate']:
            data['endDate'] = datetime.strptime(
                data['endDate'][:10], "%Y-%m-%d").date()

        # set seatsAvailable to be same as maxAttendees on creation
        # both for data model & outbound Message
        if data["maxAttendees"] > 0:
            data["seatsAvailable"] = data["maxAttendees"]
            setattr(request, "seatsAvailable", data["maxAttendees"])

        # make Profile Key from user ID
        p_key = ndb.Key(Profile, user_id)
        # allocate new Conference ID with Profile key as parent
        c_id = Conference.allocate_ids(size=1, parent=p_key)[0]
        # make Conference key from ID
        c_key = ndb.Key(Conference, c_id, parent=p_key)
        data['key'] = c_key
        data['organizerUserId'] = request.organizerUserId = user_id

        # create Conference & return (modified) ConferenceForm
        Conference(**data).put()

        # Send confirmation email to the conference creator
        taskqueue.add(params={'email': user.email(),
                              'conferenceInfo': repr(request)},
                      url='/tasks/send_confirmation_email'
                      )

        return request

    @ndb.transactional()
    def _updateConferenceObject(self, request):
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')
        user_id = getUserId(user)

        # copy ConferenceForm/ProtoRPC Message into dict
        data = {field.name: getattr(request, field.name)
                for field in request.all_fields()}

        # update existing conference
        conf = ndb.Key(urlsafe=request.websafeConferenceKey).get()
        # check that conference exists
        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % request.websafeConferenceKey)  # noqa

        # check that user is owner
        if user_id != conf.organizerUserId:
            raise endpoints.ForbiddenException(
                'Only the owner can update the conference.')

        # Not getting all the fields, so don't create a new object; just
        # copy relevant fields from ConferenceForm to Conference object
        for field in request.all_fields():
            data = getattr(request, field.name)
            # only copy fields where we get data
            if data not in (None, []):
                # special handling for dates (convert string to Date)
                if field.name in ('startDate', 'endDate'):
                    data = datetime.strptime(data, "%Y-%m-%d").date()
                    if field.name == 'startDate':
                        conf.month = data.month
                # write to Conference object
                setattr(conf, field.name, data)
        conf.put()
        prof = ndb.Key(Profile, user_id).get()
        return self._copyConferenceToForm(conf, getattr(prof, 'displayName'))

    @endpoints.method(ConferenceForm, ConferenceForm, path='conference',
                      http_method='POST', name='createConference')
    def createConference(self, request):
        """Create new conference."""
        return self._createConferenceObject(request)

    @endpoints.method(CONF_PUT_REQUEST, ConferenceForm,
                      path='conference/{websafeConferenceKey}',
                      http_method='PUT', name='updateConference')
    def updateConference(self, request):
        """Update conference w/provided fields & return w/updated info."""
        return self._updateConferenceObject(request)

    def _getQuery(self, request):
        """Return formatted query from the submitted filters."""
        q = Conference.query()
        inequality_filter, filters = self._formatFilters(request.filters)

        # If exists, sort on inequality filter first
        if not inequality_filter:
            q = q.order(Conference.name)
        else:
            q = q.order(ndb.GenericProperty(inequality_filter))
            q = q.order(Conference.name)

        for filtr in filters:
            if filtr["field"] in ["month", "maxAttendees"]:
                filtr["value"] = int(filtr["value"])
            formatted_query = ndb.query.FilterNode(
                filtr["field"], filtr["operator"], filtr["value"])
            q = q.filter(formatted_query)
        return q

    def _formatFilters(self, filters):
        """Parse, check validity and format user supplied filters."""
        formatted_filters = []
        inequality_field = None

        for f in filters:
            filtr = {field.name: getattr(f, field.name)
                     for field in f.all_fields()}

            try:
                filtr["field"] = FIELDS[filtr["field"]]
                filtr["operator"] = OPERATORS[filtr["operator"]]
            except KeyError:
                raise endpoints.BadRequestException(
                    "Filter contains invalid field or operator.")

            # Every operation except "=" is an inequality
            if filtr["operator"] != "=":
                # check if inequality operation has been used in previous filters
                # disallow the filter if inequality was performed on a different field before
                # track the field on which the inequality operation is
                # performed
                if inequality_field and inequality_field != filtr["field"]:
                    raise endpoints.BadRequestException(
                        "Inequality filter is allowed on only one field.")
                else:
                    inequality_field = filtr["field"]

            formatted_filters.append(filtr)
        return (inequality_field, formatted_filters)

    @endpoints.method(ConferenceQueryForms, ConferenceForms,
                      path='queryConferences',
                      http_method='POST',
                      name='queryConferences')
    def queryConferences(self, request):
        """Query for conferences."""
        conferences = self._getQuery(request)

        # return individual ConferenceForm object per Conference
        return ConferenceForms(
            items=[self._copyConferenceToForm(conf, "")
                   for conf in conferences]
        )

    @endpoints.method(CONF_GET_REQUEST, ConferenceForm,
                      path='conference/{websafeConferenceKey}',
                      http_method='GET', name='getConference')
    def getConference(self, request):
        """Return requested conference (by websafeConferenceKey)."""
        # get Conference object from request; bail if not found
        conf = ndb.Key(urlsafe=request.websafeConferenceKey).get()
        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % request.websafeConferenceKey)  # noqa
        prof = conf.key.parent().get()
        # return ConferenceForm
        return self._copyConferenceToForm(conf, getattr(prof, 'displayName'))

    @endpoints.method(message_types.VoidMessage, ConferenceForms,
                      path='getConferencesCreated',
                      http_method='POST', name='getConferencesCreated')
    def getConferencesCreated(self, request):
        """Return conferences created by user."""
        # make sure user is authed
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')

        # make profile key
        p_key = ndb.Key(Profile, getUserId(user))
        # create ancestor query for this user
        conferences = Conference.query(ancestor=p_key)
        # get the user profile and display name
        prof = p_key.get()

        displayName = getattr(prof, 'displayName')
        # return set of ConferenceForm objects per Conference
        return ConferenceForms(
            items=[self._copyConferenceToForm(
                conf, displayName) for conf in conferences]
        )

    @endpoints.method(message_types.VoidMessage, ConferenceForms,
                      path='filterPlayground',
                      http_method='GET', name='filterPlayground')
    def filterPlayground(self, request):
        q = Conference.query()

        # simple filter usage:
        # q = q.filter(Conference.city == "Paris")

        # advanced filter building and usage
        # field = "city"
        # operator = "="
        # value = "London"
        # f = ndb.query.FilterNode(field, operator, value)
        # q = q.filter(f)

        q = q.filter(Conference.city == "London")
        q = q.filter(Conference.maxAttendees > 10)

        q = q.order(Conference.name)

        return ConferenceForms(
            items=[self._copyConferenceToForm(conf, "") for conf in q]
        )

# - - - Registration - - - - - - - - - - - - - - - - - - - -

    @ndb.transactional(xg=True)
    def _conferenceRegistration(self, request, reg=True):
        """Register or unregister user for selected conference."""
        retval = None
        prof = self._getProfileFromUser()  # get user Profile

        # check if conf exists given websafeConfKey
        # get conference; check that it exists
        wsck = request.websafeConferenceKey
        conf = ndb.Key(urlsafe=wsck).get()
        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % wsck)

        # register
        if reg:
            # check if user already registered otherwise add
            if wsck in prof.conferenceKeysToAttend:
                raise ConflictException(
                    "You have already registered for this conference")

            # check if seats avail
            if conf.seatsAvailable <= 0:
                raise ConflictException(
                    "There are no seats available.")

            # register user, take away one seat
            prof.conferenceKeysToAttend.append(wsck)
            conf.seatsAvailable -= 1
            retval = True

        # unregister
        else:
            # check if user already registered
            if wsck in prof.conferenceKeysToAttend:

                # unregister user, add back one seat
                prof.conferenceKeysToAttend.remove(wsck)
                conf.seatsAvailable += 1
                retval = True
            else:
                retval = False

        # write things back to the datastore & return
        prof.put()
        conf.put()
        return BooleanMessage(data=retval)

    @endpoints.method(CONF_GET_REQUEST, BooleanMessage,
                      path='conference/{websafeConferenceKey}',
                      http_method='POST', name='registerForConference')
    def registerForConference(self, request):
        """Register user for selected conference."""
        return self._conferenceRegistration(request)

    @endpoints.method(CONF_GET_REQUEST, BooleanMessage,
                      path='unregisterFromConference /{websafeConferenceKey}',
                      http_method='POST', name='unregisterFromConference')
    def unregisterFromConference(self, request):
        """Register user for selected conference."""
        return self._conferenceRegistration(request, False)

    @endpoints.method(message_types.VoidMessage, ConferenceForms,
                      path='conferences/attending',
                      http_method='GET', name='getConferencesToAttend')
    def getConferencesToAttend(self, request):
        """Get list of conferences that user has registered for."""
        # step 1: get user profile
        prof = self._getProfileFromUser()

        # step 2: get conferenceKeysToAttend from profile.
        wscks = prof.conferenceKeysToAttend

        # step 3: fetch conferences from datastore.
        ds_keys = [ndb.Key(urlsafe=wsck) for wsck in wscks]

        conferences = ndb.get_multi(ds_keys)

        # return set of ConferenceForm objects per Conference
        return ConferenceForms(items=[self._copyConferenceToForm(conf, "")
                                      for conf in conferences]
                               )

# - - - Announcements - - - - - - - - - - - - - - - - - - - -

    @staticmethod
    def _cacheAnnouncement():
        """Create Announcement & assign to memcache; used by
        memcache cron job.
        """
        confs = Conference.query(ndb.AND(
            Conference.seatsAvailable <= 5,
            Conference.seatsAvailable > 0)
        ).fetch(projection=[Conference.name])

        if confs:
            # If there are almost sold out conferences,
            # format announcement and set it in memcache
            announcement = '%s %s' % (
                'Last chance to attend! The following conferences '
                'are nearly sold out:',
                ', '.join(conf.name for conf in confs))
            memcache.set(MEMCACHE_ANNOUNCEMENTS_KEY, announcement)
        else:
            # If there are no sold out conferences,
            # delete the memcache announcements entry
            announcement = ""
            memcache.delete(MEMCACHE_ANNOUNCEMENTS_KEY)

        return announcement

    @endpoints.method(message_types.VoidMessage, StringMessage,
                      path='conference/announcement/get',
                      http_method='GET', name='getAnnouncement')
    def getAnnouncement(self, request):
        """Return Announcement from memcache."""
        announcement = memcache.get(MEMCACHE_ANNOUNCEMENTS_KEY)
        if not announcement:
            announcement = ''
        return StringMessage(data=announcement)

# - - - Task 1: Session objects - - - - - - - - - - - - - - - - -

    def _getSpeaker(self, email):
        # Create a new key of kind Speaker from the id.
        s_key = ndb.Key(Speaker, email)

        # Get the entity from datastore by using get() on the key
        speaker = s_key.get()

        # If speaker doesn't exist, we create a new one
        if not speaker:
            speaker = Speaker(
                key=s_key,
                email=email,  # e-mail is enough, no name to store
            )
            # Save the speaker to datastore
            speaker.put()

        return speaker     # return Speaker

    def _addSessionToSpeaker(self, session_key, speakerForm):
        """Append session key to Speaker entity given in the parameter as SpeakerForm entity"""  # noqa
        speakerObj = self._getSpeaker(speakerForm.email)
        speakerObj.sessionKeysToAttend.append(session_key.urlsafe())
        speakerObj.put()
        # Return the speaker websafe key
        return speakerObj.key.urlsafe()

    def _copySessionToForm(self, sess):
        """Copy relevant fields from Session to SessionForm."""
        sf = SessionForm()
        for field in sf.all_fields():
            if hasattr(sess, field.name):
                if field.name == 'speaker':
                    sf.speaker = SpeakerForm(
                        name=sess.speaker.name,
                        email=sess.speaker.email,
                        websafeSpeakerKey=sess.speaker.websafeSpeakerKey,
                    )

                # convert sessionType string to Enum
                elif field.name == 'sessionType':
                    setattr(
                        sf,
                        field.name,
                        getattr(SessionType, getattr(sess, field.name))
                    )
                # convert Date to date string
                elif field.name == 'date':
                    setattr(sf, field.name, str(getattr(sess, field.name)))
                # just copy others
                else:
                    setattr(sf, field.name, getattr(sess, field.name))
            # get the websafe session key
            elif field.name == 'websafeKey':
                setattr(sf, field.name, sess.key.urlsafe())
        sf.check_initialized()
        return sf

    def _createSessionObject(self, request):
        """Create a Session object, returning SessionForm/request."""
        # get the user
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')
        user_id = getUserId(user)

        # get Conference Key from websafeConferenceKey
        c_key = ndb.Key(urlsafe=request.websafeConferenceKey)
        # get the actual Conference object
        conf = c_key.get()

        # check that conference exists
        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % request.websafeConferenceKey)  # noqa

        # check that user is owner
        if user_id != conf.organizerUserId:
            raise endpoints.ForbiddenException(
                'Only the owner can update the conference.')

        # Check that name was given
        if not request.name:
            raise endpoints.BadRequestException(
                "Session 'name' field required")

        # copy SessionForm/ProtoRPC Message into dict
        data = {field.name: getattr(request, field.name)
                for field in request.all_fields()}

        # convert dates from ISO format strings to Date objects;
        # takes the first 10 characters of ISO format string.
        if data['date']:
            data['date'] = datetime.strptime(
                data['date'][:10], "%Y-%m-%d").date()

        if data['startTime']:
            # If start time was given we want to be sure it's in military
            # format
            startTimeDigits = len(str(data['startTime']))
            if startTimeDigits < 3 or startTimeDigits > 4:
                raise endpoints.BadRequestException(
                    "Start time must be in military notation (3 or 4 digits)")

        if data['sessionType']:
            # Convert enum field to string
            data['sessionType'] = data['sessionType'].name

        # allocate new Session ID with Conference key as parent
        s_id = Session.allocate_ids(size=1, parent=c_key)[0]
        # make Session key from ID
        s_key = ndb.Key(Session, s_id, parent=c_key)
        data['key'] = s_key

        # check whether the e-mail field is an empty string
        if not data['speaker'].email.strip():
            raise endpoints.BadRequestException(
                "Speaker 'e-mail' field cannot be empty"
            )

        # Add the websafe session key to the speaker object
        # and return the websafe speaker key
        wssk = self._addSessionToSpeaker(s_key, data['speaker'])
        speaker = SpeakerProperty(
            name=data['speaker'].name,
            email=data['speaker'].email,
            websafeSpeakerKey=wssk
        )

        # Overwrite the inbound SpeakerForm object with
        # the SpeakerProperty object
        data['speaker'] = speaker

        # Get rid of useless field. Session object has not such fields
        del data['websafeConferenceKey']
        del data['websafeKey']

        # create Session
        Session(**data).put()

        # Set a new featured speaker, if any
        taskqueue.add(
            params={'session': str(s_key.urlsafe())},
            url='/tasks/set_featured_speaker'
        )

        # return SessionForm object
        return self._copySessionToForm(s_key.get())

    @endpoints.method(CONF_GET_REQUEST, SessionForms,
                      path='getConferenceSessions/{websafeConferenceKey}',
                      http_method='GET', name='getConferenceSessions')
    def getConferenceSessions(self, request):
        """Return all the sessions in a given conference."""
        # get Conference object from request; bail if not found
        wsck = request.websafeConferenceKey
        c_key = ndb.Key(urlsafe=wsck)
        conf = c_key.get()
        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % wsck)

        # Get sessions for the given conference
        q = Session.query(ancestor=c_key).order(Session.name).fetch()

        # return set of SessionForm objects
        return SessionForms(
            items=[self._copySessionToForm(sess) for sess in q]
        )

    @endpoints.method(SESSION_POST_REQUEST, SessionForm,
                      path='createSession/{websafeConferenceKey}',
                      http_method='POST', name='createSession')
    def createSession(self, request):
        """Create a conference session."""
        return self._createSessionObject(request)

    @endpoints.method(SESSION_BYTYPE_GET_REQUEST, SessionForms,
                      path='getConferenceSessionsByType/{websafeConferenceKey}/{typeOfSession}',  # noqa
                      http_method='GET', name='getConferenceSessionsByType')
    def getConferenceSessionsByType(self, request):
        """Return conference sessions by type."""
        # get Conference object from request; bail if not found
        wsck = request.websafeConferenceKey
        c_key = ndb.Key(urlsafe=wsck)
        conf = c_key.get()
        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % wsck)

        # Turn the session type into an uppercased string
        sess_type = request.typeOfSession.upper()
        # Get sessions for the given conference, filtered by type
        q = Session.query(ancestor=c_key).\
            filter(Session.sessionType == sess_type).\
            order(Session.name).\
            fetch()

        # return set of SessionForm objects
        return SessionForms(
            items=[self._copySessionToForm(sess)for sess in q]
        )

    @endpoints.method(SESSION_BYSPEAKER_GET_REQUEST, SessionForms,
                      path='getSessionsBySpeaker/{websafeSpeakerKey}',
                      http_method='GET', name='getSessionsBySpeaker')
    def getSessionsBySpeaker(self, request):
        """Get sessions by speaker, across al the conferences."""
        # get Speaker object from request; bail if not found
        wssk = request.websafeSpeakerKey
        speaker_key = ndb.Key(urlsafe=wssk)
        speaker = speaker_key.get()
        if not speaker:
            raise endpoints.NotFoundException(
                'No speaker found with key: %s' % wssk)

        # Get the sessions
        ds_keys = [ndb.Key(urlsafe=wssk) for wssk in speaker.sessionKeysToAttend]  # noqa
        q = ndb.get_multi(ds_keys)

        # return set of SessionForm objects
        return SessionForms(
            items=[self._copySessionToForm(sess)for sess in q]
        )

# - - - Task 2: Wishlist - - - - - - - - - - - - - - - - - - - -

    @endpoints.method(
        endpoints.ResourceContainer(
            message_types.VoidMessage,
            websafeSessionKey=messages.StringField(1),),
        ProfileForm,
        path='addSessionToWishlist/{websafeSessionKey}',
        http_method='POST',
        name='addSessionToWishlist'
    )
    def addSessionToWishlist(self, request):
        """Add a session to the user's wishlist"""
        # get Session object from request; bail if not found
        wssk = request.websafeSessionKey
        sess_key = ndb.Key(urlsafe=wssk)
        session = sess_key.get()
        print session
        if not session:
            raise endpoints.NotFoundException(
                'No session found with key: %s' % wssk)
        elif sess_key.kind() != 'Session':
            raise endpoints.BadRequestException(
                'The websafeKey: %s does not belong to a Session object' % wssk)  # noqa

        # Get the session's ancestor conference
        conference = sess_key.parent().get()

        # get user Profile
        prof = self._getProfileFromUser()

        # Check if user is registered to the conference
        if not conference.key.urlsafe() in prof.conferenceKeysToAttend:
            raise ConflictException(
                'You need to be registered to the conference in order to join a session')  # noqa

        # We don't want to have duplicates
        if wssk in prof.sessionKeysWishlist:
            raise ConflictException(
                'You have already added this session to your wishlist')

        # Add the session key to the user's wishlist
        prof.sessionKeysWishlist.append(wssk)
        prof.put()

        # return ProfileForm
        return self._copyProfileToForm(prof)

    @endpoints.method(
        message_types.VoidMessage,
        SessionForms,
        path='getSessionsInWishlist',
        http_method='GET',
        name='getSessionsInWishlist'
    )
    def getSessionsInWishlist(self, request):
        """Get all the sessions in the user's wishlist"""
        # get user Profile
        prof = self._getProfileFromUser()

        # Get the sessions
        ds_keys = [ndb.Key(urlsafe=wssk) for wssk in prof.sessionKeysWishlist]  # noqa
        q = ndb.get_multi(ds_keys)

        # return set of SessionForm objects
        return SessionForms(
            items=[self._copySessionToForm(sess)for sess in q]
        )

# - - - Task 3: Additional queries - - - - - - - - - - - - - - - - -

    @endpoints.method(
        endpoints.ResourceContainer(
            message_types.VoidMessage,
            date=messages.StringField(1),),
        SessionForms,
        path='getSessionsByDate',
        http_method='GET',
        name='getSessionsByDate'
    )
    def getSessionsByDate(self, request):
        """Get sessions on a given date (ISO format)."""
        date = None

        if request.date:
            try:
                date = datetime.strptime(
                    request.date[:10], "%Y-%m-%d").date()
            except ValueError:
                raise endpoints.BadRequestException(
                    "Session 'date' must be ISO format: YYYY-MM-DD")
        else:
            raise endpoints.BadRequestException(
                "Session 'date' field required")

        # convert dates from ISO format strings to Date objects;
        # takes the first 10 characters of ISO format string.
        q = Session.query(Session.date == date).\
            order(-Session.startTime)

        # return set of SessionForm objects
        return SessionForms(
            items=[self._copySessionToForm(sess)for sess in q]
        )

    @endpoints.method(
        CONF_GET_REQUEST,
        TeeShirtSizeForm,
        path='getTshirtsByConference',
        http_method='GET',
        name='getTshirtsByConference'
    )
    def getTshirtsByConference(self, request):
        """Get the amount of t-shirts, grouped by size, that are needed for the given conference"""  # noqa
        # get Conference object from request; bail if not found
        wsck = request.websafeConferenceKey
        conf = ndb.Key(urlsafe=wsck).get()
        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % request.websafeConferenceKey)  # noqa

        # Get all the people who are meant to attend the given conference
        q = Profile.query().filter(Profile.conferenceKeysToAttend == str(wsck))

        # Init a new TeeShirtSizeForm instance
        tShirts = TeeShirtSizeForm()

        # Loop through users attending the conference and add 1 unit
        # to the corresponging tshirt size group in the TeeShirtSizeForm
        # instance
        for user in q:
            setattr(
                tShirts,
                user.teeShirtSize,
                getattr(tShirts, user.teeShirtSize) + 1
            )

        # return TeeShirtSizeForm object
        return tShirts

    @endpoints.method(
        CONF_GET_REQUEST,
        SessionForms,
        path='getSessionsILike',
        http_method='GET',
        name='getSessionsILike'
    )
    def getSessionsILike(self, request):
        """Get all the sessions that starts before 7pm and
        that are not workshops, for a given conference"""
        # get Conference object from request; bail if not found
        wsck = request.websafeConferenceKey
        c_key = ndb.Key(urlsafe=wsck)
        conf = c_key.get()
        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % wsck)

        # Get sessions which start before 7pm for the given conference
        q = Session.query(ancestor=c_key).\
            filter(Session.startTime < 1900).\
            order(Session.startTime).\
            fetch()

        # Init an empty list where to store filtered sessions
        filteredSessions = []

        # Filter out sessions which type is 'workshop';
        # we have to do it programmatically since datastore
        # doesn't support 2 inequality filters on the same query
        for sess in q:
            if sess.sessionType != 'WORKSHOP':
                filteredSessions.append(self._copySessionToForm(sess))

        # return set of SessionForm objects
        return SessionForms(
            items=filteredSessions
        )

# - - - Task 4: Featured Speaker - - - - - - - - - - - - - - - - -

    @staticmethod
    def _cacheFeaturedSpeaker(websafeSessionKey):
        """Create Featured Speaker & assign to memcache; used by
        memcache cron job."""

        featuredSpeaker = {}

        # Get session
        new_s_key = ndb.Key(urlsafe=websafeSessionKey)
        new_session = new_s_key.get()
        if not new_session:
            raise endpoints.NotFoundException(
                'No session found with key: %s' % websafeSessionKey)

        # Retrieve conference parent's key
        c_key = new_s_key.parent()
        conference = c_key.get()

        # Get all the sessions for the given conference
        q = Session.query(ancestor=c_key).fetch()

        # Set an empty dictionary to hold the new session
        # speaker's websafe key and init it to 0
        new_speakerKey = {}
        new_speakerKey[new_session.speaker.websafeSpeakerKey] = 0

        # check if new speakers are attending more than one
        # session in the same conference
        for session in q:
            if session.speaker.websafeSpeakerKey in new_speakerKey:
                new_speakerKey[session.speaker.websafeSpeakerKey] += 1
                if new_speakerKey[session.speaker.websafeSpeakerKey] > 1:
                    featuredSpeaker['name'] = session.speaker.name
                    featuredSpeaker['email'] = session.speaker.email
                    break

        if any(featuredSpeaker):
            # If there is a featured speaker we put it in the memcache
            speaker = 'Come and listen to the best speakers! %s, %s, %s %s' % (
                featuredSpeaker['name'],
                featuredSpeaker['email'],
                'is going to attend the:',
                conference.name + ' conference!')
            memcache.set(MEMCACHE_SPEAKERS_KEY, speaker)

        return featuredSpeaker

    @endpoints.method(message_types.VoidMessage, StringMessage,
                      path='conference/getFeaturedSpeaker',
                      http_method='GET', name='getFeaturedSpeaker')
    def getFeaturedSpeaker(self, request):
        """Get featured speakers."""
        speaker = memcache.get(MEMCACHE_SPEAKERS_KEY)
        if not speaker:
            speaker = 'There are no featured speakers'
        return StringMessage(data=speaker)

# registers API
api = endpoints.api_server([ConferenceApi])


text:
require 'rails_helper'

describe Friendship do
  let(:friendship) { Friendship.new( user_id: 1, friend_id: 2 ) }

  context ".user_id" do
    it "has a readable attribute" do
      expect(friendship.user_id).to eq 1
    end

    it "is necessary to be saved" do
      expect(friendship.save).to be true
    end

    it "cannot be saved if not present" do
      friendship.user_id = nil
      expect(friendship.save).to be false
    end
  end

  context ".friend_id" do
    it "has a readable attribute" do
      expect(friendship.friend_id).to eq 2
    end

    it "is necessary to be saved" do
      expect(friendship.save).to be true
    end

    it "cannot be saved if not present" do
      friendship.friend_id = nil
      expect(friendship.save).to be false
    end

  end

  context ".confirmed" do
    it "defaults to pending" do
      expect(friendship.confirmed).to eq false
    end

    it "can be changed" do
      friendship.confirmed = true
      expect(friendship.confirmed).to eq true
    end
  end

end


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>org.wildfly.swarm.config.webservices Class Hierarchy (BOM:  * : All 2.1.0.Final API)</title>
<meta name="date" content="2018-08-14">
<link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Thorntail API, 2.1.0.Final

Prev

Next

Frames

No Frames

All Classes

Hierarchy For Package org.wildfly.swarm.config.webservices

Package Hierarchies:

All Packages

Class Hierarchy

java.lang.Object

org.wildfly.swarm.config.webservices.ClientConfig<T>

org.wildfly.swarm.config.webservices.ClientConfig.ClientConfigResources

org.wildfly.swarm.config.webservices.EndpointConfig<T>

org.wildfly.swarm.config.webservices.EndpointConfig.EndpointConfigResources

org.wildfly.swarm.config.webservices.Handler<T>

org.wildfly.swarm.config.webservices.PostHandlerChain<T>

org.wildfly.swarm.config.webservices.PostHandlerChain.PostHandlerChainResources

org.wildfly.swarm.config.webservices.PreHandlerChain<T>

org.wildfly.swarm.config.webservices.PreHandlerChain.PreHandlerChainResources

org.wildfly.swarm.config.webservices.Property<T>

Interface Hierarchy

org.wildfly.swarm.config.webservices.ClientConfigConsumer<T>

org.wildfly.swarm.config.webservices.ClientConfigSupplier<T>

org.wildfly.swarm.config.webservices.EndpointConfigConsumer<T>

org.wildfly.swarm.config.webservices.EndpointConfigSupplier<T>

org.wildfly.swarm.config.webservices.HandlerConsumer<T>

org.wildfly.swarm.config.webservices.HandlerSupplier<T>

org.wildfly.swarm.config.webservices.PostHandlerChainConsumer<T>

org.wildfly.swarm.config.webservices.PostHandlerChainSupplier<T>

org.wildfly.swarm.config.webservices.PreHandlerChainConsumer<T>

org.wildfly.swarm.config.webservices.PreHandlerChainSupplier<T>

org.wildfly.swarm.config.webservices.PropertyConsumer<T>

org.wildfly.swarm.config.webservices.PropertySupplier<T>

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Thorntail API, 2.1.0.Final

Prev

Next

Frames

No Frames

All Classes

Copyright © 2018 JBoss by Red Hat. All rights reserved.


text:
XWikiDoc(function (doc) {
    doc.setParent("RISCOSSPlatformCode.WebHome");
    doc.setCreationDate("0");
    doc.setDate("0");
    doc.setContentUpdateDate("0");
    doc.setTitle("Show in dialog JSX");
});


text:
<?php

namespace Assetic\Test\Filter;

use Assetic\Asset\FileAsset;
use Assetic\Filter\OptiPngFilter;

/**
 * @group integration
 */
class OptiPngFilterTest extends BaseImageFilterTest
{
    private $filter;

    protected function setUp()
    {
        if (!isset($_SERVER['OPTIPNG_BIN'])) {
            $this->markTestSkipped('No OptiPNG configuration.');
        }

        $this->filter = new OptiPngFilter($_SERVER['OPTIPNG_BIN']);
    }

    /**
     * @dataProvider getImages
     */
    public function testFilter($image)
    {
        $asset = new FileAsset($image);
        $asset->load();

        $before = $asset->getContent();
        $this->filter->filterDump($asset);

        $this->assertNotEmpty($asset->getContent(), '->filterDump() sets content');
        $this->assertNotEquals($before, $asset->getContent(), '->filterDump() changes the content');
        $this->assertMimeType('image/png', $asset->getContent(), '->filterDump() creates PNG data');
    }

    public function getImages()
    {
        return array(
            array(__DIR__.'/fixtures/home.gif'),
            array(__DIR__.'/fixtures/home.png'),
        );
    }
}


text:
export default {
  development: {
    driver: 'sqlite3',
    database: 'station_api_dev'
  },

  test: {
    driver: 'sqlite3',
    database: 'station_api_test'
  },

  production: {
    driver: 'sqlite3',
    database: 'station_api_prod'
  }
};


text:
USERNAME

                 Online

        <form action="#" method="get" class="sidebar-form">

                <input type="text" name="q" class="form-control" placeholder="Search..."/>

            <button type='submit' name='search' id='search-btn' class="btn btn-flat"></button>

        </form>

Admin Menu

            @foreach ($menu as $key => $item)
                @include('admin.layouts.menu_item')
            @endforeach


text:
use std::os;
use std::io::process::Command;
use std::finally::Finally;
use std::str;

#[inline(never)]
fn foo() {
    let _v = vec![1i, 2, 3];
    if os::getenv("IS_TEST").is_some() {
        panic!()
    }
}

#[inline(never)]
fn double() {
    (|&mut:| {
        panic!("once");
    }).finally(|| {
        panic!("twice");
    })
}

fn runtest(me: &str) {
    let mut template = Command::new(me);
    template.env("IS_TEST", "1");

    // Make sure that the stack trace is printed
    let p = template.clone().arg("fail").env("RUST_BACKTRACE", "1").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(out.error.as_slice()).unwrap();
    assert!(s.contains("stack backtrace") && s.contains("foo::h"),
            "bad output: {}", s);

    // Make sure the stack trace is *not* printed
    let p = template.clone().arg("fail").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(out.error.as_slice()).unwrap();
    assert!(!s.contains("stack backtrace") && !s.contains("foo::h"),
            "bad output2: {}", s);

    // Make sure a stack trace is printed
    let p = template.clone().arg("double-fail").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(out.error.as_slice()).unwrap();
    // loosened the following from double::h to double:: due to
    // spurious failures on mac, 32bit, optimized
    assert!(s.contains("stack backtrace") && s.contains("double::"),
            "bad output3: {}", s);

    // Make sure a stack trace isn't printed too many times
    let p = template.clone().arg("double-fail")
                                .env("RUST_BACKTRACE", "1").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(out.error.as_slice()).unwrap();
    let mut i = 0;
    for _ in range(0i, 2) {
        i += s.slice_from(i + 10).find_str("stack backtrace").unwrap() + 10;
    }
    assert!(s.slice_from(i + 10).find_str("stack backtrace").is_none(),
            "bad output4: {}", s);
}

fn main() {
    let args = os::args();
    let args = args.as_slice();
    if args.len() >= 2 && args[1].as_slice() == "fail" {
        foo();
    } else if args.len() >= 2 && args[1].as_slice() == "double-fail" {
        double();
    } else {
        runtest(args[0].as_slice());
    }
}


text:
package com.saq.android.asynctasks;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Pair;
import com.saq.android.data.Product;
import com.saq.android.utils.ConnectionUtils;
import com.saq.android.utils.FavoritesManager;
import com.saq.android.utils.StorageUtils;
import com.saq.android.webservices.SAQWebServiceSoapEnveloppeBuilder;
import com.saq.android.webservices.SAQWebServiceSoapEnveloppeBuilder.SAQ_SOAP_ACTION;
import com.saq.android.webservices.SaqWs;
import com.saq.android.webservices.SaqWs.WS_CALL_TYPE;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.net.UnknownHostException;
import org.xmlpull.v1.XmlPullParser;

public abstract class SAQProductDetailsTask extends AsyncTask<String, Integer, Product> {
    protected static final String EN_TAG = "en";
    protected static final String FR_TAG = "fr";
    protected WeakReference<Context> context;
    protected Exception error;
    protected WeakReference<ISAQProductTaskListener> listener;
    protected String productCode;
    protected WS_CALL_TYPE searchType;

    public interface ISAQProductTaskListener {
        void onOperationCancelled(Exception exception);

        void onOperationCompleted(Product product, String... strArr);

        void onOperationStart();
    }

    public SAQProductDetailsTask(WS_CALL_TYPE searchType, ISAQProductTaskListener listener, String code, Context context) {
        this.listener = new WeakReference(listener);
        this.context = new WeakReference(context);
        this.searchType = searchType;
        this.productCode = code;
    }

    protected void onPreExecute() {
        super.onPreExecute();
        if (this.listener != null && this.listener.get() != null) {
            ((ISAQProductTaskListener) this.listener.get()).onOperationStart();
        }
    }

    protected void onPostExecute(Product result) {
        super.onPostExecute(result);
        if (this.listener != null && this.listener.get() != null) {
            ((ISAQProductTaskListener) this.listener.get()).onOperationCompleted(result, new String[0]);
        }
    }

    protected void onCancelled() {
        super.onCancelled();
        if (this.listener != null && this.listener.get() != null) {
            ((ISAQProductTaskListener) this.listener.get()).onOperationCancelled(this.error);
        }
    }

    protected String getXmlString(String code, String langCode) throws Exception {
        String xmlString = XmlPullParser.NO_NAMESPACE;
        if (ConnectionUtils.isNetworkAvailable((Context) this.context.get())) {
            Pair[] parameters = new Pair[2];
            parameters[0] = new Pair(SAQWebServiceSoapEnveloppeBuilder.GET_RESULT_DETAILS_LANG_CODE_TAG, langCode);
            if (this.searchType.equals(WS_CALL_TYPE.FETCH_DETAILS)) {
                parameters[1] = new Pair(SAQWebServiceSoapEnveloppeBuilder.GET_RESULT_DETAILS_PRODUCT_CODE_TAG, this.productCode);
                xmlString = SaqWs.getXmlStringResponseFromServer(SAQWebServiceSoapEnveloppeBuilder.generateSoapEnvelope(SAQ_SOAP_ACTION.GET_PRODUCT_DETAILS, parameters));
            } else if (this.searchType.equals(WS_CALL_TYPE.FETCH_DETAILS_BY_CUP)) {
                parameters[1] = new Pair(SAQWebServiceSoapEnveloppeBuilder.GET_RESULT_DETAILS_FOR_PRODUCT_BY_CUP_TAG, this.productCode);
                xmlString = SaqWs.getXmlStringResponseFromServer(SAQWebServiceSoapEnveloppeBuilder.generateSoapEnvelope(SAQ_SOAP_ACTION.GET_PRODUCT_DETAILS_BY_CUP, parameters));
            }
            return xmlString;
        } else if (FavoritesManager.Instance().isInFavorites((Context) this.context.get(), code) && this.searchType.equals(WS_CALL_TYPE.FETCH_DETAILS)) {
            return getXmlStringForProductDetailsFromFile(code, langCode);
        } else {
            throw new UnknownHostException();
        }
    }

    protected String getXmlFilePathForProduct(String code, String lang) throws Exception {
        return new StringBuilder(String.valueOf(StorageUtils.getFavoritesPath((Context) this.context.get()))).append(this.productCode).append("_").append(lang).append(".xml").toString();
    }

    protected String getXmlStringForProductDetailsFromFile(String code, String lang) throws Exception {
        String xmlString = XmlPullParser.NO_NAMESPACE;
        String path = getXmlFilePathForProduct(code, lang);
        File f = new File(path);
        if (f.exists()) {
            BufferedReader r = new BufferedReader(new InputStreamReader(new DataInputStream(new FileInputStream(f))));
            StringBuilder total = new StringBuilder();
            while (true) {
                String line = r.readLine();
                if (line == null) {
                    return total.toString();
                }
                total.append(line);
            }
        } else {
            throw new Exception("Unable to find file " + path);
        }
    }
}