Made up this extension method for XDocuments to be able to return an Expando object on which the properties of the XML can be navigated. This is still a little bit rough. I found out there is a ElasticObject that probably works a lot better. But this is just a little ‘proof of concept’.
Note that attributes in the XML are not bound in the Expando object.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
using System.Xml.Linq;
namespace Famvdploeg.Com
{
public static class XDocumentExtensions
{
public static dynamic ToExpandoObject(this XDocument document)
{
return ParseNode(document.Root);
}
private static dynamic ParseNode(XElement item)
{
dynamic expando = new ExpandoObject();
var props = expando as IDictionary<string, object>;
/* Properties of current node. Single and Lists are created here dynamic */
IEnumerable<IGrouping<string, XElement>> groupedProperties = item.Elements().Where(element => !element.HasElements).GroupBy(x => x.Name.ToString());
foreach (IGrouping<string, XElement> propertyGroup in groupedProperties)
{
int nrElements = propertyGroup.Count();
if (nrElements == 1)
{
props[propertyGroup.Key.ToValidPropertyName()] = propertyGroup.First().Value;
}
else
{
var multipleValues = new List<string>();
foreach (XElement element in propertyGroup)
{
multipleValues.Add(element.Value);
}
props[propertyGroup.Key.ToValidPropertyName()] = multipleValues;
}
}
/* Children of current node. Single and Lists are created here dynamic */
IEnumerable<IGrouping<string, XElement>> groupedElements = item.Elements().Where(element => element.HasElements).GroupBy(x => x.Name.ToString());
foreach (IGrouping<string, XElement> elementGroup in groupedElements)
{
int nrElements = elementGroup.Count();
if (nrElements == 1)
{
props[elementGroup.Key.ToValidPropertyName()] = ParseNode(elementGroup.First());
}
else
{
var multipleElements = new List<dynamic>();
foreach (XElement element in elementGroup)
{
multipleElements.Add(ParseNode(element));
}
props[elementGroup.Key.ToValidPropertyName()] = multipleElements;
}
}
return expando;
}
}
}
September 26th, 2011
Wytze
This is supposed to be a cheatsheet for some common elements in Grails.
It’s a little bare at the moment but I hope that in time it will be a nice mashup of different Grails elements.
Grails Cheatsheet
Constraints
static constraints = {
propertyName(
blank: false,
nullable: false,
inList: ['a', 'b'], //Or reference property here
matches: '[0-9]+',
minSize: 1,
maxSize: 10,
min: 1,
max: 10,
range: 1..10,
unique: true,
url: true,
email: true,
notEqual: "passwd", //Or reference property here
validator: { val, obj ->
return val != obj.propertyName
},
/* Display Options */
attributes: [year: 2000..2011], //Adds extra attributes to item when rendered.
password: true, //Indicate that this is a password field
widget: 'textarea', //Choose what widget will be used to render this item.
//textField, hiddenField, submitButton, field, textArea, form, actionSubmit, actionSubmitImage, datePicker, renderNoSelectionOption, timeZoneSelect, localeSelect, currencySelect, select, checkBox, radio
display: false //Hide this item when scaffolding
)
}
Persistence Callbacks
- beforeInsert – Executed before an object is initially persisted to the database
- beforeUpdate – Executed before an object is updated
- beforeDelete – Executed before an object is deleted
- beforeValidate – Executed before an object is validated
- afterInsert – Executed after an object is persisted to the database
- afterUpdate – Executed after an object has been updated
- afterDelete – Executed after an object has been deleted
- onLoad – Executed when an object is loaded from the database
Sample:
def beforeInsert() {
doSomething()
}
def beforeUpdate() {
if (isDirty('fieldName')) {
doSomething()
}
}
Showing SQL-queries
Edit the DataSource.groovy file in the Configuration directory and add the following to the hibernate section (preferably in non-production environments):
hibernate {
show_sql = true
}
September 18th, 2011
Wytze
First install tomcat and tomcat on your ubuntu machine if you have not already done so.
sudo apt-get install tomcat6 tomcat6-admin postgresql
Setup the required PostgreSQL database on ubuntu. We will connect to it as a JNDI DataSource later on.
-- Connect to the database from command line
psql -d postgres
CREATE USER userName WITH PASSWORD 'yourPassword';
CREATE DATABASE databaseName;
GRANT ALL PRIVILEGES ON DATABASE databaseName TO userName;
Get the postgreSQL JDBC driver.
cd /usr/share/tomcat6/lib
sudo wget http://jdbc.postgresql.org/download/postgresql-9.1-901.jdbc3.jar
Create a Tomcat Context configuration for your grails webapp.
sudo vi /etc/tomcat6/Catalina/localhost/yourappname.xml
Fill it with something like the following, (adapted to your webapps name / context root of course)
<Context path="/yourContextPath" reloadable="false">
<Resource name="jdbc/yourName" auth="Container"
type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://127.0.0.1:5432/mydb"
username="myuser" password="mypasswd" maxActive="20" maxIdle="10"
maxWait="-1"/>
</Context>
We’re almost there. Update DataSource.groovy
production {
dataSource {
dbCreate = "update"
jndiName = "java:comp/env/jdbc/yourName"
}
}
Awesome! Restart tomcat (sudo /etc/init.d/tomcat6 restart). Build (grails prod war) and deploy (copy file to /var/lib/tomcat6/webapps) your grails webapp and go bananas!
November 30th, 2010
Wytze
Trailing spaces or tabs is something I dislike. Using the combination CTRL+R, CTRL+W you can show the whitespace distribution in VS. But screening the lines one by one is a tedious job. That’s why we are going to use regular expressions. Regular expressions in VS are a bit of an odd duck as the syntax is not nice and Perly.
You can read more about regular expressions in Visual Studio here.
Putting this together we get the following:
Find what: ^{.@}:b+$
Replace with: \1
This will seach those nasty trailing whitespaces and remove them.
{.@} -> Match everything, non-greedy. This is our capturing group.
:b+$ -> Match one or more spaces or tabs before the end of the line.
Optionally:
You can add the following macro to Visual Studio (and bind some keystroke):
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Public Module Famvdploeg
'Remove trailing whitespace from document
Sub RemoveTrailingWhitespace()
DTE.Find.FindReplace(vsFindAction.vsFindActionReplaceAll, "( |\t)+$", vsFindOptions.vsFindOptionsRegularExpression, String.Empty, vsFindTarget.vsFindTargetCurrentDocument, , , )
End Sub
End Module
There are several ways to do this I guess. What I wanted was a default css class which I could apply to an anchor tag and have a specific part of the content loaded in fancybox. This is what I came up with. It is also possible to do this with the ajax property of fancybox itself I suppose.
$(function () {
$("a.ajaxcontent").click(
function (event) {
event.preventDefault();
var url = jQuery(this).attr("href");
$.get(
url,
function (data) {
var content = jQuery(data).find("#content");
$.fancybox(content);
}
);
}
);
});
Although you can use the export tool from microsoft. I just wrote a small C# app to do the same thing. Below is the code.
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.IO;
namespace ExportImages
{
public class Program
{
static void Main(string[] args)
{
Program program = new Program();
program.ExportImages();
}
private void ExportImages()
{
string connectionString = String.Format("Server=<servername>; Database=<databasename>; Integrated Security=SSPI");
using (SqlConnection connection =
new SqlConnection(connectionString))
{
try
{
connection.Open();
SqlDataAdapter data = new SqlDataAdapter(
@"select Id, Thumbnail from Images", connection);
DataSet ds = new DataSet("images");
int recordsFound = data.Fill(ds);
for (int index = 0; index < recordsFound; index++)
{
int id = (int) ds.Tables[0].Rows[index]["Id"];
byte[] imageData = (byte[]) ds.Tables[0].Rows[index]["Thumbnail"];
int imageSize = imageData.GetUpperBound(0);
FileStream fs = new FileStream(@"F:\images\" + id + "_thumbnail.jpg", FileMode.OpenOrCreate, FileAccess.Write);
fs.Write(imageData, 0, imageSize);
fs.Close();
}
}
catch (SqlException e)
{
Console.WriteLine(e.Message);
}
finally
{
if (connection.State != ConnectionState.Closed)
{
connection.Close();
}
}
}
}
}
}
Got some inspiration from this site for the base script: click
I wanted a site to always show the answer ‘Ja’ (Dutch for yes). Which was normally only shown at a specific time. (The question was if you could start drinking beer.
)
Here is the full script:
// ==UserScript==
// @name ishetalbiertijd.user.js
// @namespace http://famvdploeg.com/greasemonkey
// @include http://www.ishetalbiertijd.nl/*
// ==/UserScript==
var $;
// Add jQuery
(function(){
if (typeof unsafeWindow.jQuery == 'undefined') {
var GM_Head = document.getElementsByTagName('head')[0] || document.documentElement,
GM_JQ = document.createElement('script');
GM_JQ.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js';
GM_JQ.type = 'text/javascript';
GM_JQ.async = true;
GM_Head.insertBefore(GM_JQ, GM_Head.firstChild);
}
GM_wait();
})();
// Check if jQuery's loaded
function GM_wait() {
if (typeof unsafeWindow.jQuery == 'undefined') {
window.setTimeout(GM_wait, 100);
} else {
$ = unsafeWindow.jQuery.noConflict(true);
letsJQuery();
}
}
// All your GM code must be inside this function
function letsJQuery() {
//@require does not work for us...
$('span#answer').text('Jaaa!');
$('#datum').replaceWith('<span style="font-size: 200%; font-weight:bold; color:white">Het kan nu!</span>');
}
1. Use xsd.exe to extract an xsd file from an xml feed.
Download a private xml feed for example from “http://api.twitter.com/1/statuses/user_timeline.xml” and store it to local disk. Use xsd.exe to generate the xsd.
2. Generate the classes from the xsd file you just generated.
3. Add the generated classes to your C# project.
4. Time for some fetching here is a short example:
// encode the username/password
string user = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://api.twitter.com/1/statuses/user_timeline.xml");
// set the method to GET
request.Method = "GET";
request.ServicePoint.Expect100Continue = false;
// set the authorisation levels
request.Headers.Add("Authorization", "Basic " + user);
request.ContentType = "application/x-www-form-urlencoded";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
XmlSerializer serializer = new XmlSerializer(typeof(statuses));
statuses s = serializer.Deserialize(response.GetResponseStream()) as statuses;
listBox1.Items.Clear();
foreach (statusesStatus status in s.status)
{
listBox1.Items.Add(status.text);
}
}
Sometimes you need to get a GUID for an entry in Active Directory. There are several tools available to do this. This is just one example how you could approach this.
To go the network where you can search/browse AD.

Perform a search and modify the columns you want to view. Look for a Distinguished Name property and add it. We will use it to retrieve the GUID.

Create a simple vbs script to retrieve the GUID and write it to a text file.
Set objFSO = CreateObject("Scripting.FileSystemObject")
ForWriting = 2
Set file = objFSO.OpenTextFile("C:\Windows\Temp\guid.txt", ForWriting, true)
Set sampleUser = GetObject("LDAP://CN=Wytze van der Ploeg,OU=kantoor,DC=vincis,DC=nl")
file.WriteLine("User: " & sampleUser.Name & " " & sampleUser.Guid)
file.Close
Done.
1. Download the jackrabbit jca from http://jackrabbit.apache.org/downloads.html
2. Deploy it on glassfish
3. Create a new Resource Adapter Configuration (Create a new Thread-pool first if you want)
4. Create a new Connector Connection Pool with the new Resource Adapter Configuration
Add the following properties:
homeDir <full path to where your repository is located>
configFile <full path to where your repository config (repository.xml) is located>
5. Create the connector resource and name it 'jcr/repository' for example.
You can now access your repository in the code. Below is a sample.
package com.famvdploeg.jackrabbit;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
/**
*
* @author wytze
*/
@Stateless
public class JackrabbitManager {
@Resource(mappedName="jcr/repository", type=javax.jcr.Repository.class)
private Repository repository;
public String getFromRepo() {
try {
Session session = repository.login(new SimpleCredentials("username", "password".toCharArray()));
Node root = session.getRootNode();
Node hello = root.addNode("hello");
hello.setProperty("message", "Hello, World!");
session.save();
// Retrieve content
Node node = root.getNode("hello");
System.out.println(node.getPath());
System.out.println(node.getProperty("message").getString());
root.getNode("hello").remove();
return "Created and removed!";
} catch (Exception ex) {
return ex.getMessage();
}
}
}
A possible Java EE 6 Servlet which you can use for WebDAV support. You will need jackrabbit-jcr-server for the base servlet. You can get it by building the source package with maven.
package com.famvdploeg.jackrabbit;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.jcr.Repository;
import javax.servlet.annotation.WebServlet;
import javax.servlet.annotation.WebInitParam;
/**
*
* @author wytze
*/
@WebServlet(
name = "webdav",
urlPatterns = "/repository/*",
initParams = {
@WebInitParam(name = "resource-path-prefix", value = "/repository"),
@WebInitParam(name = "missing-auth-mapping", value = "admin:admin"),
@WebInitParam(name = "resource-config", value = "/WEB-INF/config.xml")
}
)
public class SimpleWebdavServlet extends org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet {
@EJB
private RepositoryFactory repositoryFactory;
private Repository repository;
@PostConstruct
public void postConstruct() {
repository = repositoryFactory.getRepository();
}
@Override
public Repository getRepository() {
return repository;
}
}
Possible extended configuration of the repository:
<!-- Store all items larger than 256 bytes in the FileDataStore -->
<DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
<param name="path" value="${rep.home}/repository/datastore"/>
<param name="minRecordLength" value="256"/>
</DataStore>