<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>developer.vz.net</title>
	<atom:link href="http://developer.vz.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://developer.vz.net</link>
	<description>where the VZ-Networks developers blog</description>
	<lastBuildDate>Fri, 16 Mar 2012 18:09:18 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Writing a Play 2.0 Module</title>
		<link>http://developer.vz.net/2012/03/16/writing-a-play-2-0-module/</link>
		<comments>http://developer.vz.net/2012/03/16/writing-a-play-2-0-module/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 18:09:18 +0000</pubDate>
		<dc:creator>James Roper</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[play framework]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=3218</guid>
		<description><![CDATA[The intro Hot off the press, Play 2.0 has arrived, and has been welcomed into the arms of a fast paced community that loves new things.  The day it was released, we started a new project here, and on that &#8230; <a href="http://developer.vz.net/2012/03/16/writing-a-play-2-0-module/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h2 style="font-weight: bold;">The intro</h2>
<p>Hot off the press, <a href="http://www.playframework.org/documentation/2.0/Home">Play 2.0</a> has arrived, and has been welcomed into the arms of a fast paced community that loves new things.  The day it was released, we started a new project here, and on that particular day and on this particular project we felt particularly daring.  So we decided to use Play 2.0 for our project.  New is an understatement for Play 2.0, it&#8217;s not just an incremental improvement on Play 1.x, many parts of it have been completely rewritten.  There is still much work to do, and one of the blaring gaps that has yet to be filled is modules.  At the time of writing, there is <a href="http://www.playframework.org/modules">no official listing</a> or repository of modules for Play 2.0, in stark contrast to the rich ecosystem of modules for Play 1.x.  Furthermore, there is no documentation on how to write a module.  So, given that modules tend to be very useful, and we were starting a new project, we very quickly ran into the need to write our own module, which we did, the <a href="https://github.com/vznet/play-mongo-jackson-mapper">MongoDB Jackson Mapper Play 2.0 Module</a>.  To help the rest of the community of early Play 2.0 adopters, I&#8217;ve decided to write a (very) short guide on writing Play 2.0 modules.</p>
<h2 style="font-weight: bold;">The disclaimer</h2>
<p>So did I mention that there was no documentation on writing modules, and very little in the way of example code to copy from?  What I&#8217;ve written may well be not the right way to do things.  But with no documentation, how am I to know?  All I know is that it&#8217;s working for us, and that&#8217;s good enough for me.  So if you happen to know what the right way to write Play 2.0 modules is, don&#8217;t bother commenting on this telling me that I&#8217;m wrong.  Just write the damn documentation!</p>
<h2 style="font-weight: bold;">The setup</h2>
<p>In play 1.x, writing a module usually starts with running <code>play new-module</code>. Slight problem here:</p>
<pre>$ play new-module
       _            _
 _ __ | | __ _ _  _| |
| '_ \| |/ _' | || |_|
|  __/|_|\____|\__ (_)
|_|            |__/ 

play! 2.0, http://www.playframework.org

This is not a play application!

Use `play new` to create a new Play application in the current directory,
or go to an existing application and launch the development console using `play`.

You can also browse the complete documentation at http://www.playframework.org.</pre>
<p>Ok, so that doesn&#8217;t work.  Looks like there&#8217;s no way to create a new play module.  So, I decided to simply write a vanilla SBT project.  I won&#8217;t go into the details of how to set a new SBT project up, but here&#8217;s the play specific bits that you&#8217;ll need:</p>
<pre>resolvers ++= Seq(
    DefaultMavenRepository,
    Resolver.url("Play", url("http://download.playframework.org/ivy-releases/"))(Resolver.ivyStylePatterns),
    "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/",
    "Typesafe Other Repository" at "http://repo.typesafe.com/typesafe/repo/"
)

libraryDependencies += "play" %% "play" % "2.0"

libraryDependencies += "play" %% "play-test" % "2.0" % "test"</pre>
<p>Now do whatever you need to do to open it up in your favourite IDE/editor (I personally use IntelliJ IDEA, so I use the <a href="https://github.com/mpeltonen/sbt-idea">sbt-idea plugin</a>).</p>
<h2 style="font-weight: bold;">The code</h2>
<p>It&#8217;s worth first noting that the module that I wanted to write only had to load a MongoDB connection pool, according to configuration supplied in <code>application.conf</code>, and manage the lifecycle of that pool.  The trait that needed to be implemented to do this is <code>play.api.Plugin</code>.  It has three methods, <code>onStart()</code>, <code>onStop()</code> and <code>enabled()</code>.  If you&#8217;re looking for information on how to do things like intercept HTTP calls and define custom routes, then I suspect it&#8217;s easy to do (probably by just defining a routes file in your plugin), but I didn&#8217;t need to do that so I&#8217;m not going to pretend that I know how.</p>
<p>There&#8217;s not really much to say now, my plugin looks something like this:</p>
<pre>class MongoDBPlugin(val app: Application) extends Plugin {
  private lazy val (mongo, db, mapper) = {
    // insert code here to initialise from application config
  }

  override def onStart() {
    // trigger lazy loading of the mongo field
    mongo
  }

  override def onStop() {
    mongo.close()
  }

  override def enabled() = !app.configuration.getString("mongodb.jackson.mapper")
      .filter(_ == "disabled").isDefined
}</pre>
<p>The <a href="https://github.com/vznet/play-mongo-jackson-mapper/blob/master/src/main/scala/play/modules/mongodb/jackson/MongoDB.scala">actual code</a> does a fair bit more than this, but none of that is specific to how to write a plugin.</p>
<h2 style="font-weight: bold;">The finishing touch</h2>
<p>So I&#8217;ve written my plugin, there&#8217;s now one thing left to do&#8230; tell play framework about it!  This is done by defining a <code>play.plugins</code> file in the the root of the classpath (in the resources folder):</p>
<pre>1000:play.modules.mongodb.jackson.MongoDBPlugin</pre>
<p>The leading integer defines the priority of the plugin to be loaded.  The example I saw used 1000, so I decided to use that too.</p>
<h2 style="font-weight: bold;">The resolution</h2>
<p>Now all I have to do to use this module is add it as a dependency.  Play will automatically pick it up, and it will be automatically started and stopped as necessary.  Happy hacking, and if you&#8217;re starting a Play 2.0 project, and want to use MongoDB, why not try the <a href="http://github.com/vznet/play-mongo-jackson-mapper">MongoDB Jackson Mapper Module</a>!<br />
<img src="http://t.jazzy.id.au/vz-db-pm" alt="" width="1" height="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2012/03/16/writing-a-play-2-0-module/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>VZ sponsort Front-Trends Conference 2012</title>
		<link>http://developer.vz.net/2012/03/06/front-trends-conference/</link>
		<comments>http://developer.vz.net/2012/03/06/front-trends-conference/#comments</comments>
		<pubDate>Tue, 06 Mar 2012 10:52:26 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Daily Business]]></category>
		<category><![CDATA[Features]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=3209</guid>
		<description><![CDATA[Ich freue mich sehr darüber, bekannt geben zu könne, dass VZ euch als Goldsponsor (gemeinsam mit weiteren Sponsoren) in diesem Jahr die Front-Trends Conference 2012 präsentieren wird. Die Front-Trends Conference findet vom 26.-27. April 2012 in Warschau statt und versammelt erneut das Who-is-who &#8230; <a href="http://developer.vz.net/2012/03/06/front-trends-conference/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ich freue mich sehr darüber, bekannt geben zu könne, dass VZ euch als Goldsponsor (gemeinsam mit weiteren Sponsoren) in diesem Jahr die Front-Trends Conference 2012 präsentieren wird.</p>
<p>Die <strong>Front-Trends Conference </strong>findet vom <strong>26.-27. April 2012</strong> in Warschau statt und versammelt erneut das Who-is-who der Front-Trend-Developer.</p>
<p><a href="http://developer.vz.net/2012/03/06/front-trends-conference/logo/" rel="attachment wp-att-3210"><img class="alignright size-thumbnail wp-image-3210" title="logo" src="http://developer.vz.net/wp-content/uploads/2012/03/logo-150x150.png" alt="" width="150" height="150" /></a> &#8221;<em>THIS IS A GATHERING FOR FRONT-END LOVERS TO DISCOVER THE CURRENT TRENDS TO BUILD A PROFESSIONAL CAREER OUT OF INNOVATIVE<br />
</em><strong>CONFERENCE TOPICS:</strong> <em>HTML5 UX JAVASCRIPT WEB DESIGN CSS3 MOBILE AND MORE</em>&#8221;</p>
<p>Ein Blick in die Liste der Speaker sollte jedem Frontend Enthusiasten verdeutlichen, dass es sich um ein absolutes Top Event handelt und so schicken wir von den VZ Netzwerken in diesem Jahr nicht nur Entwickler, sondern auch gleich noch ein &#8220;Sponsorship&#8221; nach Warschau. Yeah.</p>
<p><strong>Let&#8217;s have a beer (or two).</strong><br />
Fahrt ihr auch nach Warschau? Wen treffen wir?</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2012/03/06/front-trends-conference/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Extending Guice</title>
		<link>http://developer.vz.net/2012/02/08/extending-guice-2/</link>
		<comments>http://developer.vz.net/2012/02/08/extending-guice-2/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 14:10:38 +0000</pubDate>
		<dc:creator>James Roper</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[guice]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=3175</guid>
		<description><![CDATA[Guice is a framework that I had been looking forward to trying out for a while, but until recently I never had the opportunity.  Previously I had mostly used Spring (with a dash of PicoContainer), so when I got the &#8230; <a href="http://developer.vz.net/2012/02/08/extending-guice-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a title="Google Guice home page" href="http://code.google.com/p/google-guice/">Guice</a> is a framework that I had been looking forward to trying out for a while, but until recently I never had the opportunity.  Previously I had mostly used <a title="Spring Framework home page" href="http://www.springsource.org/">Spring</a> (with a dash of <a title="PicoContainer home page" href="http://picocontainer.org/">PicoContainer</a>), so when I got the opportunity to start using Guice, I naturally had a number of my favourite Spring features in mind as I started using it.  Very quickly I found myself wanting an equivalent of Springs <a title="DisposableBean javadoc" href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/beans/factory/DisposableBean.html"><code>DisposableBean</code></a>.  Guice is focussed on doing one thing and doing it well, and that thing is dependency injection.  Lifecycle management doesn&#8217;t really come into that, so I am not surprised that Guice doesn&#8217;t offer native support for disposing of beans.  There is one Guice extension out there, <a title="Guiceyfruit home page" href="http://code.google.com/p/guiceyfruit/">Guiceyfruit</a>, that does offer reasonably complete per scope lifecycle support, however Guiceyfruit requires using a fork of Guice, which didn&#8217;t particularly appeal to me.  Besides, Guice is very simple, so I imagined that providing my own simple extensions to it would also be simple.  I was right.</p>
<p>Though, to be honest, while the extensions themselves are simple, it wasn&#8217;t that simple to work out how to write them.  On my first attempt, I gave up after Googling and trying things out myself for an hour.  On my second attempt, I almost gave up with <a href="https://twitter.com/#%21/jroper/status/146629860209594370">this tweet</a>.  But, I stuck with it, and eventually made my breakthrough. The answer was in <a title="InjectionListener javadocs" href="http://google-guice.googlecode.com/git/javadoc/com/google/inject/spi/InjectionListener.html"><code>InjectionListener</code></a>. This listener is called on every component that Guice manages, including both components that Guice instantiates itself, and components that are provided as instances to Guice.</p>
<h2><strong>Supporting Disposables</strong></h2>
<p>So, I had my disposable interface:</p>
<pre>public interface Disposable {
  void dispose();
}</pre>
<p>and I wanted any component that implemented this interface to have their <code>dispose()</code> method called when my application shut down.  Naturally I had to maintain a list of components to dispose of:</p>
<pre>final List&lt;Disposable&gt; disposables = Collections.synchronizedList(new ArrayList());</pre>
<p>Thread safety must be taken into consideration, but since I only expected this list to be accessed when my application was starting up and shutting down, a simple synchronized list was suffcient, no need to worry about performant concurrent access.</p>
<p>My <code>InjectionListener</code> is very simple, it just adds disposables to this list after they&#8217;ve been injected:</p>
<pre>final InjectionListener injectionListener = new InjectionListener&lt;Disposable&gt;() {
  public void afterInjection(Disposable injectee) {
    disposables.add(injectee);
  }
};</pre>
<p><code>InjectionListener</code>&#8216;s are registered by registering a <a title="TypeListener javadocs" href="http://google-guice.googlecode.com/git/javadoc/com/google/inject/spi/TypeListener.html"><code>TypeListener</code></a> that listens for events on types that Guice encounters.  My type listener checks if the type is <code>Disposable</code> (this actually isn&#8217;t necessary because we will register it using a matcher that matches only Disposable types, but it is defensive to do the check), and if so registers the <code>InjectionListener</code>:</p>
<pre>TypeListener disposableListener = new TypeListener {
  public &lt;I&gt; void hear(TypeLiteral&lt;I&gt; type, TypeEncounter&lt;I&gt; encounter) {
    if (Disposable.class.isAssignableFrom(type.getRawType())) {
      TypeEncounter&lt;Disposable&gt; disposableEncounter = (TypeEncounter&lt;Disposable&gt;) encounter;
      disposableEncounter.register(injectionListener);
    }
  }
}</pre>
<p>Now I can register my <code>TypeListener</code>.  This is done from a module:</p>
<pre>bindListener(new AbstractMatcher&lt;TypeLiteral&lt;?&gt;&gt;() {
      public boolean matches(TypeLiteral&lt;?&gt; typeLiteral) {
        return Disposable.class.isAssignableFrom(typeLiteral.getRawType());
      }
    }, disposableListener);</pre>
<p>The last thing I need to do is bind my collection of disposables, so that when my app shuts down, I can dispose of them:</p>
<pre>bind((TypeLiteral) TypeLiteral.get(Types.listOf(Disposable.class)))
                .toInstance(disposables);</pre>
<p>So now when my app shuts down, I can look up the list of disposables and dispose of them:</p>
<pre>for (Disposable disposable : ((List&lt;Disposable&gt;) injector.getInstance(
    Key.get(Types.listOf(Disposable.class)))) {
  disposable.dispose();
}</pre>
<p>If you decide to use this code in your own app, please be very wary of a potential memory leak. Any beans that are not singleton scoped will be added to the disposable list each time they are requested (per scope).  For my purposes, all my beans that required being disposed of were singleton scoped, so I didn&#8217;t have to worry about this.</p>
<h2><strong>Supporting annotation based method invocation scheduling</strong></h2>
<p>Happy that I now had a very simple extension with very little code for supporting automatic disposing of beans, I decided to try something a little more complex&#8230; scheduling. My app contains a number of simple scheduled tasks, and the amount of boilerplate for scheduling each of these was too much for my liking. My aim was to able to do something like this:</p>
<pre>@Schedule(delay = 5L, timeUnit = TimeUnit.MINUTES, initialDelay = 1L)
def cleanUpExpiredData() {
  ...
}</pre>
<p>(Yep, this app has a mixture of Scala and Java.) So, I started with my annotation:</p>
<pre>@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Schedule {
    long delay();
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    long initialDelay() default 0;
}</pre>
<p>The main difference this time is that I&#8217;m not listening for events on a particular type, but rather I want to check all types to see if they have a <code>@Schedule</code> annotated method. This is a little more involved, so I&#8217;m going to have a scheduler service that does this checking and the scheduling. Additionally it will make use of the disposable support that I just implemented:</p>
<pre>public class SchedulerService implements Disposable {
  private final ScheduledExcecutorService executor = Executors.newSingleThreadScheduledExecutor();

  public boolean hasScheduledMethod(Class clazz) {
    for (Method method : clazz.getMethods()) {
      Schedule schedule = method.getAnnotation(Schedule.class);
      if (schedule != null) {
        return true;
      }
    }
    return false;
  }

  public void schedule(Object target) {
    for (final Method method : target.getClass().getMethods()) {
      Schedule schedule = method.getAnnotation(Schedule.class);
      if (schedule != null) {
        schedule(target, method, schedule);
      }
    }
  }

  private void schedule(final Object target, final Method method, Schedule schedule) {
    executor.scheduleWithFixedDelay(new Runnable() {
      public void run() {
        method.invoke(target);
      }, schedule.initialDelay(), schedule.delay(), schedule.timeUnit());
  }

  public void dispose() {
    executor.shutdown();
  }
}</pre>
<p>Now in my module I instantiate one of these services:</p>
<pre>final SchedulerService schedulerService = new SchedulerService();</pre>
<p>I then implement my <code>InjectionListener</code>:</p>
<pre>final InjectionListener injectionListener = new InjectionListener() {
  public void afterInjection(Object injectee) {
    schedulerService.schedule(injectee);
  }
}</pre>
<p>and my <code>TypeListener</code>:</p>
<pre>TypeListener typeListener = new TypeListener() {
  public &lt;I&gt; void hear(TypeLiteral&lt;I&gt; type, TypeEncounter&lt;I&gt; encounter) {
    if (schedulerService.hasScheduledMethod(type.getRawType()))  {
      encounter.register(injectionListener);
    }
  }
}</pre>
<p>And then all I have to do is register my type listener, and also my scheduler service (so that it gets disposed properly):</p>
<pre>  bindListener(Matchers.any(), typeListener);
  bind(SchedulerService.class).toInstance(schedulerService);</pre>
<h2><strong>Conclusion</strong></h2>
<p>Although Guice doesn&#8217;t come with as much as Spring does out of the box, it is very simple to extend to meet your own requirements. If I were needing many more container like features, then maybe Spring would be a better tool for the job, but when I&#8217;m just after a dependency injection framework with a little sugar on top, Guice is a very nice and much lighter weight solution.<br />
<img src="http://t.jazzy.id.au/vz-db-eg" alt="" width="1" height="1" /></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2012/02/08/extending-guice-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sharing some love.</title>
		<link>http://developer.vz.net/2012/01/30/sharing-some-love/</link>
		<comments>http://developer.vz.net/2012/01/30/sharing-some-love/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 15:59:27 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[Daily Business]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=3190</guid>
		<description><![CDATA[Don&#8217;t be surprised but we had an awesome year. So we decided to give a little back and support some of our favourite tools and open source projects: Eclipse I don&#8217;t think we need a description here ;-) http://www.eclipse.org/ 500€ &#8230; <a href="http://developer.vz.net/2012/01/30/sharing-some-love/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Don&#8217;t be surprised but we had an awesome year. So we decided to give a little back and support some of our favourite tools and open source projects:</p>
<table>
<tbody>
<tr>
<td><img class=" wp-image-3191 alignleft" style="border-style: initial; border-color: initial; border-image: initial; border-width: 0px;" title="eclipse" src="http://developer.vz.net/wp-content/uploads/2012/01/eclipse.png" alt="" width="171" height="91" /></td>
<td><strong>Eclipse</strong><br />
I don&#8217;t think we need a description here ;-)<br />
<a href="http://www.eclipse.org/" target="_blank">http://www.eclipse.org/</a></td>
<td>500€</td>
</tr>
<tr>
<td></td>
<td><strong>CumulusServer</strong><br />
&#8220;CumulusServer is a complete open source and cross-platform RTMFP server extensible by way of scripting.&#8221;<br />
<a href="https://github.com/OpenRTMFP/Cumulus" target="_blank">https://github.com/OpenRTMFP/Cumulus</a></td>
<td>500€</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Thanks to the developers and keep up the good work.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2012/01/30/sharing-some-love/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Jackson annotations with MongoDB</title>
		<link>http://developer.vz.net/2011/12/01/jackson-annotations-with-mongodb/</link>
		<comments>http://developer.vz.net/2011/12/01/jackson-annotations-with-mongodb/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 16:17:00 +0000</pubDate>
		<dc:creator>James Roper</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=3150</guid>
		<description><![CDATA[At VZ we are currently busy testing a new storage backend for the VZ feed.  We&#8217;ve pushed the existing backend to its limits and while so far it has served us well, we are finding that for what we want &#8230; <a href="http://developer.vz.net/2011/12/01/jackson-annotations-with-mongodb/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>At VZ we are currently busy testing a new storage backend for the VZ feed.  We&#8217;ve pushed the existing backend to its limits and while so far it has served us well, we are finding that for what we want to do going forward, it just isn&#8217;t the right match for our requirements.  So we&#8217;ve spent some time investigating what the best backend will be, and we are now in the testing stage with <a title="MongoDB home page" href="http://www.mongodb.org/">MongoDB</a>, loading it with our feed data and hammering it with load tests.  So far so good.</p>
<p>The backend of our feed service is implemented in Java, and talks JSON back to clients.  If you log in to VZ and use your favourite browsers developer console to see XHR traffic, you can see the JSON that the feed service returns.  This JSON is generated from POJOs using <a title="Jackson home page" href="http://jackson.codehaus.org/">Jackson</a>, a very simple yet powerful, performant and flexible framework for serialising POJOs to JSON.</p>
<p>Looking carefully at the JSON, you&#8217;ll notice that the feed data contains more than just a list of messages, there is a mixture of objects whose data is clearly generated on the fly by the feed service, and other objects that the feed service doesn&#8217;t really care about, it just receives them from the services that generate them, and passes them to the client as is.  For example, information about a particular photo, or a gadget, or a status update, or a new friend.  This data is represented by many different POJOs in the feed, and in some cases specific processing is done on them, but mostly the feed receives them from the various services that generates them, and passes them back to the client untouched.</p>
<p>All these POJOs have Jackson annotations on them, and we know that they work well with Jackson.  With our old storage backend, we simply serialised them to JSON to store them.  One of the reasons for going with MongoDB is that we wanted to be able to easily query our data, to get statistics and a better understanding of how the service was being used.  What we wanted to avoid though was having to either rewrite the POJOs, or make MongoDB equivalent copies of them, in order to store them in MongoDB.  What we really wanted to do is reuse the Jackson annotations on them so that we could store them as is in MongoDB.</p>
<p>A google search revealed that there already was <a href="http://techblog.gitgis.com/2011/07/mongo-java-driver-with-jackson.html">a mapper out there</a> by Grzegorz Godlewski that did this, however this mapper had a few problems in our eyes.  For one, it required a fork of the Mongo Java Driver, and there was no indication that this fork would ever be pulled back into the stable driver.  It also said that it was experimental and not production ready, and we weren&#8217;t about to trust our feed with an experimental technology that didn&#8217;t have a clear future.  It is worth saying though that Grzegorz&#8217;s mapper is quite innovative, it serialises/deserialises objects directly to/from the BSON that MongoDB speaks with the client.  This would make it the most performant mapper out there.  But we didn&#8217;t feel that the technology was mature enough for our use case.</p>
<p>However, as Grzegorz pointed out, plugging in a custom parser/generator to Jackson is a simple thing to do, so we decided to implement our own mapper that parsed/generated the MongoDB map like <code>DBObject</code>&#8216;s.  In addition to this, we implemented a very lightweight interface that wraps the MongoDB <code>DBCollection</code>, called <code>JacksonDBCollection</code>.  This provides all the same methods that <code>DBCollection</code> provides, except that where appropriate, it replaces <code>DBObject</code> method parameters and return types with strongly typed POJO versions.  <code>DBObject</code>&#8216;s still get used for querying, because you can&#8217;t express all queries using POJOs, however when you just want to use equality in your queries, you can use your POJO as the query.</p>
<h1>It&#8217;s open source!</h1>
<p>We&#8217;re pleased to announce that we&#8217;ve made this library available as an open source library. You can download the source code, and contribute to it yourself, at <a href="https://github.com/vznet/mongo-jackson-mapper">GitHub</a>.  If you don&#8217;t want the source code, but just want to start using it in your project now, you can get it from the central maven repository:</p>
<pre>&lt;dependency&gt;
    &lt;groupId&gt;net.vz.mongodb.jackson&lt;/groupId&gt;
    &lt;artifactId&gt;mongo-jackson-mapper&lt;/artifactId&gt;
    &lt;version&gt;1.0&lt;/version&gt;
&lt;/dependency&gt;</pre>
<h1>The details</h1>
<p>To give you a taste of what this framework looks like, I&#8217;ll show some coding examples.  Here is how to create a <code>JacksonDBCollection</code>:</p>
<pre>JacksonDBCollection&lt;MyPojo, String&gt; coll = JacksonDBCollection.wrap(
    dbCollection, MyPojo.class, String.class);</pre>
<p>The two type parameters are the type of the POJO that is being mapped, and the type of the ID of the POJO.  The reason we require the type of the ID of the POJO is for strongly typed querying by ID, and strongly typed retrieval of generated IDs.  Here is what my POJO looks like:</p>
<pre>public class MyPojo {
  @ObjectId @Id public String id;
  public Integer someNumber;
  public List&lt;String&gt; someList;
}</pre>
<p>Maybe not the best Java coding style with public mutable fields, Jackson is flexible enough to support almost anything, this keeps it simple for this blog post.  In the feed, we&#8217;re using immutable objects with private final fields, and <code>@JsonCreator</code> annotated constructors.</p>
<p>One issue that we encountered while implementing this is how to handle <code>ObjectId</code>&#8216;s.  If you declare an object to have a type of <code>ObjectId</code>, it works without a problem.  But this is a POJO mapper, and some people may not want to have an ObjectId type in their POJO, particularly if they are reusing the POJO for the web.  So we added an annotation, <code>@ObjectId</code>, that can be put on any <code>String</code> or <code>byte[]</code> property, that tells the mapper to serialise/deserialise this property to/from <code>ObjectId</code>.</p>
<p>You&#8217;ll also see the use of the <code>@javax.persistence.Id</code> annotation.  This is really just a short hand that we implemented for <code>@JsonProperty("_id")</code>, which has the added advantage of not having to use the Jackson views feature if you want to use the same POJO for the web and don&#8217;t want the name of the property to be <code>_id</code>. You could just as easily make the field name <code>_id</code> with no extra annotations.</p>
<p>Inserting an object is simple:</p>
<pre>MyPojo pojo = new MyPojo();
pojo.someNumber = 10;
pojo.someList = Arrays.asList("foo", "bar");
WriteResult&lt;MyPojo, String&gt; result = coll.insert(pojo);</pre>
<p>or with write concerns:</p>
<pre>WriteResult&lt;MyPojo, String&gt; result = coll.insert(pojo, WriteConcern.MAJORITY);</pre>
<p>We are letting MongoDB generate the ID for us here, which begs an important question, how do we find out what the ID it generated was? With the MongoDB Java Mapper, it sets the ID on the object you passed in. This is not practical with Jackson, because you may be using a custom serialiser, or <code>@Creator</code> annotated factory method/constructor, in the case of the VZ feed our objects were immutable, making it impossible to do that. We supported this by implementing our own <code>WriteResult</code> class, which aside from wrapping all the methods from the MongoDB Java Driver <code>WriteResult</code>, provides a few methods such as <code>getSavedId()</code> and <code>getSavedObject()</code>, which deserialises the id/object so you may obtain the ID:</p>
<pre>String id = result.getSavedId();</pre>
<p>Now using that ID we can load the object again:</p>
<pre>MyPojo saved = coll.findOneById(id);</pre>
<p>Equality based querying can be done using the POJO as a template:</p>
<pre>MyPojo query = new MyPojo();
query.someNumber = 10;
for (MyPojo item: coll.find(query)) {
    System.out.println(item.id);
}</pre>
<p>And loading partial objects can also be done using the POJO as a template, by setting any fields you want loaded to be something that isn&#8217;t null:</p>
<pre>MyPojo query = new MyPojo();
query.someNumber = 10;
MyPojo template = new MyPojo();
template.someNumber = 1;
template.id = "not null"
for (MyPojo item: coll.find(query, template)) {
    System.out.println(item.id);
    assert(item.someList == null);
}</pre>
<p>And when this isn&#8217;t enough, you can fall back to normal <code>DBObject</code>&#8216;s for both the query and the template:</p>
<pre>for (MyPop item: coll.find(new DBObject().add("someNumber", new DBObject().add("$gt", 5))) {
    System.out.println(item.id);
}</pre>
<p>There are more examples for some more advanced use cases, for example using custom views, on the <a href="http://vznet.github.com/mongo-jackson-mapper">GitHub project page</a>.</p>
<h1>Summary</h1>
<p>So here we have a new POJO mapper for MongoDB that you can use, and due to the fact that it uses Jackson, it has a head start in being very powerful, flexible and performant. Some of our plans for future features include:</p>
<ul>
<li><code>@Reference</code> annotation support, loading dehydrated referenced objects containing just the ID, with convenience methods for hydrating these objects</li>
<li>Schema migration features, where the <code>JacksonDBCollection</code> can return option tuples containing either the old or the new object type based on what was detected</li>
</ul>
<p>If you have any other features you&#8217;d like to see, please raise an issue in the GitHub project!</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/12/01/jackson-annotations-with-mongodb/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>You did what in Scala?</title>
		<link>http://developer.vz.net/2011/11/17/you-did-what-in-scala/</link>
		<comments>http://developer.vz.net/2011/11/17/you-did-what-in-scala/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 12:40:29 +0000</pubDate>
		<dc:creator>James Roper</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=3137</guid>
		<description><![CDATA[This morning when I got into work, the first thing that anyone said to me was &#8220;you did what in Scala?&#8221;  Not the usual greeting I get in the morning&#8230; clearly I had stirred something up.  I knew exactly what &#8230; <a href="http://developer.vz.net/2011/11/17/you-did-what-in-scala/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This morning when I got into work, the first thing that anyone said to me was &#8220;you did what in Scala?&#8221;  Not the usual greeting I get in the morning&#8230; clearly I had stirred something up.  I knew exactly what this person was talking about, the evening before I committed some code, and then tweeted <a title="My tweet about Scala" href="https://twitter.com/jroper/status/136506911544721408">this</a>:</p>
<blockquote><p>Just added scala for the first time to an existing Java project. Not too shaby.</p></blockquote>
<p>As soon as I saw the build passed on our CI server, I went home, but it caught the attention of my product manager, and he was very intrigued.  What I had in fact done was started writing unit tests for an existing Java service that I was working on in Scala.  Why did I do this?  A number of reasons:</p>
<ol>
<li>I&#8217;ve been meaning to learn Scala for at least a year.</li>
<li>I&#8217;ve seen Scala unit tests before, and they look very cool, they&#8217;re very good at minimising boilerplate, and very easy to read and understand.</li>
<li>At VZ, we are free to make sensible technology choices.  This ranges from what libraries we use, to what databases we use, to what languages we use.  Nothing is off limits, as long as we can provide a good argument as to why it&#8217;s better than the alternatives.  And when we do that, our managers trust us.</li>
</ol>
<p>My product manager of course had no problems with me using Scala, we have another project here that uses Scala and he thought I meant I had done some work on that, and was interested in knowing why.  After explaining that I had actually added Scala to the project I was supposed to be working on, he was completely fine, and that&#8217;s one of the things I love about working for VZ, we have the freedom to make our own decisions.</p>
<p>For those that are not familiar with Scala, here is a quick overview of how I introduced Scala into my existing Java project.</p>
<p>First, I did my research.  What unit testing frameworks are there in Scala?  You&#8217;ll quickly find that there are two popular frameworks, one called <a title="Scala specs" href="http://code.google.com/p/specs/">specs</a>, and another called <a title="ScalaTest" href="http://www.scalatest.org/">ScalaTest</a>.  ScalaTest supports a number of different testing styles, including TDD and BDD, while specs only supports BDD.  I only wanted BDD, so both were equal to me at this point.  Further research showed that specs has good integration with my favourite mocking framework, <a title="Mockito" href="http://code.google.com/p/mockito/">Mockito</a>, so I went with specs.  I suggest you do your own research for your own purposes, my comparison here is far from complete.</p>
<p>Next, since I&#8217;m using Maven, I needed to add Scala to my maven project.  I found a blog post that explained how to <a title="How to add Scala to your maven java project in 4 steps" href="http://stuq.nl/weblog/2008-11-26/4-steps-to-add-scala-to-your-maven-java-projects">add Scala to a maven project in 4 steps</a>, and I was able to build my project in no time.  I also added a dependency on the specs library, and configured the Maven surefire plugin to run any classes ending in Test or Spec, as per the instructions for <a title="Running specs in Maven with JUnit" href="http://code.google.com/p/specs/wiki/RunningSpecs#Run_your_specifications_with_JUnit4_and_Maven">integrating with Maven and JUnit</a> in the specs documentation.  I use <a title="IntelliJ IDEA" href="http://www.jetbrains.com/idea/">IntelliJ IDEA</a> as my IDE, so I searched for a Scala plugin in my preferences, found one, installed it, and after a restart IDEA had Scala support.  The IDEA instructions say that you need to install the Scala SDK, but since I was using Maven, I could just add the scala compiler as a provided maven dependency, then go to the Scala compiler preferences and point IDEA at that dependency.</p>
<p>Finally I had to write my tests.  Below is the first test that I wrote.  If you&#8217;re a Scala guru, I&#8217;m sure you&#8217;ll see things that I could have done simpler or that I haven&#8217;t followed conventions for, so I&#8217;m happy for you point them out to me, I&#8217;m still learning.</p>
<pre>class WorkResultHandlerSpec extends SpecificationWithJUnit with Mockito {
  "Work result handler" should {
    val tracker = mock[WorkResultTracker]
    val handlerChain = mock[HandlerChain]
    val workUnit = WorkUnit.builder(JobType.TEST_MESSAGE, null).build
    val job = Job.builder(JobType.TEST_MESSAGE).build
    var handler = new WorkResultHandler(tracker)

    "call handler chain only once" in {
      handler.handle(job, workUnit, handlerChain)
      there was one(handlerChain).passToNextHandler(job, workUnit)
    }

    "pass the result to the tracker" in {
      val workResult = WorkResult.success
      handlerChain.passToNextHandler(job, workUnit) returns workResult
      handler.handle(job, workUnit, handlerChain)
      there was one(tracker).trackWorkResult(JobType.TEST_MESSAGE, workResult)
    }

    "return the result" in {
      val workResult = WorkResult.success
      handlerChain.passToNextHandler(job, workUnit) returns workResult
      handler.handle(job, workUnit, handlerChain) mustEq workResult
    }

    "track an exception as a failure" in {
      handlerChain.passToNextHandler(job, workUnit) throws new RuntimeException("Something bad happened")
      val workResult = handler.handle(job, workUnit, handlerChain)
      workResult.getStatus.isSuccess must_== false
      workResult.getMessage mustEq "Something bad happened"
      there was one(tracker).trackWorkResult(JobType.TEST_MESSAGE, workResult)
    }
  }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/11/17/you-did-what-in-scala/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>We&#8217;re hiring!</title>
		<link>http://developer.vz.net/2011/11/11/we-are-hiring/</link>
		<comments>http://developer.vz.net/2011/11/11/we-are-hiring/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 17:04:56 +0000</pubDate>
		<dc:creator>iNes</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=3124</guid>
		<description><![CDATA[Programmieren mit aktueller Technologie in einem hochmotivierten, agilen Team mitten im Herzen von Berlin?! Aber sowas von! Wir stellen ein: GWT-/ Java-Experten Frontend Developer Senior Backend-Developer Alle aktuellen Ausschreibungen gibt&#8217;s unter: http://developer.vz.net/jobs/]]></description>
			<content:encoded><![CDATA[<p>Programmieren mit aktueller Technologie in einem hochmotivierten, agilen Team mitten im Herzen von Berlin?!</p>
<p>Aber sowas von!</p>
<p>Wir stellen ein:</p>
<ul>
<li><a title="GWT-/ Java-Experten" href="http://t3n.de/jobs/job/gwt-java-experten-mw-in-festanstellung-o-freelancer/" target="_blank">GWT-/ Java-Experten</a></li>
<li><a title="Frontend Developer" href="http://t3n.de/jobs/job/frontend-developer-mw-in-festanstellung-o-als-freelancer/" target="_blank">Frontend Developer</a></li>
<li><a title="Senior Backend-Developer" href="http://jobs.studivz.net/jobdetail.php?job_id=170" target="_blank">Senior Backend-Developer</a></li>
</ul>
<p>Alle aktuellen Ausschreibungen gibt&#8217;s unter: <a title="http://developer.vz.net/jobs/" href="http://developer.vz.net/jobs/">http://developer.vz.net/jobs/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/11/11/we-are-hiring/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Testing permutations of configurations</title>
		<link>http://developer.vz.net/2011/11/11/testing-permutations-of-configurations/</link>
		<comments>http://developer.vz.net/2011/11/11/testing-permutations-of-configurations/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 16:31:15 +0000</pubDate>
		<dc:creator>James Roper</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=3090</guid>
		<description><![CDATA[Permutations are an every day part of VZ development.  Most obviously, we have three different platforms, each with different names, different base URLs, different wordings and of course different colours.  But then we also have two different languages that we &#8230; <a href="http://developer.vz.net/2011/11/11/testing-permutations-of-configurations/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Permutations are an every day part of VZ development.  Most obviously, we have three different platforms, each with different names, different base URLs, different wordings and of course different colours.  But then we also have two different languages that we currently support, English and German.  On top of that we often do AB testing, where we&#8217;ll have different variants of the same feature displayed or implemented in slightly different ways, and we present the different ways to different users and then gather metrics to see which ways the users seem to prefer.  Finally, there are times where you have different functions, but the functions share much of their functionality.  You end up with a massive list of permutations of different ways the code can be executed, too many to ever test manually, and too many to write and maintain individual tests for.</p>
<p>The service that I&#8217;ve been spending a lot of time on at VZ is what we call the &#8220;notificator&#8221;.  It is responsible for generating all the HTML emails that the platform sends, from registration emails through to new message notifications, event invites, photo comments etc.  Each notification type shares a lot of its functionality with the other notification types, the emails all look very similar, and sometimes only differ by what resource keys are used to generate their wording.</p>
<p>There are many bugs that could be introduced in this system.  Here are some examples of things that I want to and can automatically test:</p>
<ul>
<li>All generated HTML is valid markup</li>
<li>All keys that the templates use exist in our resource bundles.  When a key doesn&#8217;t exist, text like this ends up in the email: <code>???new.comment.action???</code></li>
<li>All URLs in links and images are absolute URLs and are to the right platform</li>
<li>Standard headers and titles in emails are correct</li>
</ul>
<p>There are also many specific things for each notification type that I want to test.  The requirements I have mean that I can&#8217;t just run the tests for one notification type, or for one language, or for one platform, or for one AB testing variant.  I have to run the tests for every permutation of these.  Writing these tests manually would be a nightmare.  Fortunately, JUnit has a few features that can help us here.</p>
<h1>Setting up configurations</h1>
<p>Before we go into the details of how to use JUnit to help, we need to set up representations of our configurations. This can be most easily done using enums. For language, variants and platforms, we can use quite simple enums:</p>
<pre>public enum Language {
  GERMAN("de"), ENGLISH("en");
  public final String abbreviation;
  Language(String abbreviation) {
    this.abbreviation = abbreviation;
  }
}
public enum Variant {
  SMALL_PROFILE_PICS, LARGE_PROFILE_PICS
}
public enum Platform {
  SCHUELERVZ("http://www.schuelervz.net"), STUDIVZ("http://www.studivz.net"), FREUNDEVZ("http://www.freundevz.net");
  public final String baseUrl;
  Platform(String baseUrl) {
    this.baseUrl = baseUrl;
  }
}</pre>
<p>Sometimes these enums might already exist in some form in your code already, or you&#8217;ll have to make them up specifically for the tests. Using ones specific to your tests have the advantage that you can add meta data that is important to the tests to them, as I&#8217;ve done above with the base URLs for the platforms.</p>
<p>For the notification types, I wanted a bit more functionality, for example, code to run notification type specific assertions. There are many ways this could be implemented, I decided to do it using anonymous classes in an enum, implementing a method that accepts a jsoup Document to run assertions on:</p>
<pre>public enum NotificationType {
  NEW_MESSAGE(new MessageData("Test Subject", "Test content")) {
    public void runAssertions(Document body) {
      assertThat("Test Subject", equalTo(body.getElementById("subject").text()));
      assertThat("Test content", equalTo(body.getElementById("content").text()));
    }
  },
  GRUSCHEL(new GruschelData()),
  ...
  public final Object testData;
  NotificationType(Object testData) {
    this.testData = testData;
  }
  public void runAssertions(Document body) {
  }
}</pre>
<h1>Using JUnit parameters</h1>
<p>Now that I&#8217;ve got the different configurations, I can write a test that JUnit will run for every permutation of configurations. For my first attempt, I&#8217;m going to use JUnit parameters. This is by far the simplest way to do things. The first thing to do is declare the runner for the test class:</p>
<pre>@RunWith(Parameterized.class)
public class EmailGenerationTest {</pre>
<p>Now I can set up my permutations. The way the JUnit parameterized runner works is you annotate a method with <code>@Parameterized.Parameters</code>, and that method must return a collection of object arrays, each nested array being the set of arguments to pass to the tests constructor for each permutation. I&#8217;m going to implement this like so:</p>
<pre>private final Variant variant;
private final NotificationType type;
private final Platform platform;
private final Language language;
public EmailGenerationTest(Variant variant, NotificationType type, Platform platform, Language language) {
  this.variant = variant;
  this.type = type;
  this.platform = platform;
  this.language = language;
}
@Parameterized.Parameters
public static Collection&lt;Object[]&gt; generateParameters() {
  Collection&lt;Object[]&gt; params = new ArrayList&lt;Object[]&gt;();
  for (Variant variant: Variant.values()) {
    for (NotificationType type: NotificationType.values()) {
      for (Platform platform: Platform.values()) {
        for (Language language: Language.values()) {
          params.add(new Object[] {variant, type, platform, language});
        }
      }
    }
  }
  return params;
}</pre>
<p>Finally I can write my tests. Each test method that I write will be run once for each permutation of parameters that I have generated.</p>
<pre>@Test
public void noResourceKeysShouldBeMissing() {
  String html = ...// code to generate email given the parameters
  assertThat(html, not(containsString("???")));
}
@Test
public void notificationSpecificAssertionsShouldPass() {
  Document body = ...// code to generate jsoup document of the email given the parameters
  type.runAssertions(body);
}
...</pre>
<p>This works very nicely, I can add new notification types, variants, languages and platforms, and I only have to change my tests in one place specific to that configuration.  I can also add new general tests to one place, and they get run for every permutation. However, there is one problem. JUnit names each set of parameters with a sequential number. Working out which number relates to which permutation can be difficult, especially considering that we are dynamically generating the parameters.  Here&#8217;s an example of what such a test run looks like in IntelliJ IDEA:</p>
<p><a href="http://developer.vz.net/2011/11/11/testing-permutations-of-configurations/parameterised/" rel="attachment wp-att-3095"><img class="aligncenter size-full wp-image-3095" src="http://developer.vz.net/wp-content/uploads/2011/11/parameterised.jpg" alt="Parameterised test run in IntelliJ IDEA" width="499" height="312" /></a>You can see that I don&#8217;t get much information. Maven test runners are also similarly unhelpful. However, there is another strategy you can use to make sure you have the right information about failures.</p>
<h1>Custom suites</h1>
<p>This method is quite involved, if you only have a handful of permutations, it&#8217;s certianly not worth it. In my case I have many hundreds of permutations, and so it&#8217;s invaluable. The idea is that for each configuration type, we have a custom test suite. These get nested together to form our permutations. What we can do with these is give each a name according to which configuration parameter it&#8217;s for, and so we can easily work out which permutation of configurations failed. To start off with, I&#8217;m going to write an abstract runner that simply has a name and a list of child runners.  This will be the building block for my tree of runners.</p>
<pre>public static class NamedParentRunner extends ParentRunner&lt;Runner&gt; {
  private final List&lt;Runner&gt; runners;
  private final String name;
  protected NamedParentRunner(Class&lt;?&gt; klass, List&lt;Runner&gt; runners, String name) throws InitializationError {
    super(klass);
    this.runners = runners;
    this.name = name;
  }
  protected List&lt;Runner&gt; getChildren() {
    return runners;
  }
  protected Description describeChild(Runner child) {
    return child.getDescription();
  }
  protected void runChild(Runner child, RunNotifier notifier) {
    child.run(notifier);
  }
  protected String getName() {
    return name;
  }
}</pre>
<p>Now I&#8217;m going to write a test runner that will instantiate each test and run the methods on it.  I&#8217;ll extend the existing JUnit class runner because I don&#8217;t want to reimplement all the logic to do with looking up methods:</p>
<pre>private static class TestRunner extends BlockJUnit4ClassRunner {
  private final Variant variant;
  private final NotificationType type;
  private final Platform platform;
  private final Language language;
  private TestRunner(Class&lt;?&gt; klass, Variant variant, NotificationType type,
      Platform platform, Language language) throws InitializationError {
    super(klass);
    this.variant = variant;
    this.type = type;
    this.platform = platform;
    this.language = language;
  }
  public Object createTest() throws Exception {
    return new EmailGenerationTest(variant, type, platform, language);
  }
  protected String getName() {
    return language.name();
  }
  protected String testName(final FrameworkMethod method) {
    return String.format(method.getName() + "[%s-%s-%s-%s]",
        variant.name(), type.name(), platform.name(), language.name());
  }
  protected void validateConstructor(List&lt;Throwable&gt; errors) {
  }
  protected Statement classBlock(RunNotifier notifier) {
    return childrenInvoker(notifier);
  }
}</pre>
<p>Note that the name of this runner is the language, it is going to be the inner most runner and the language is going to be used as the inner most list.  The <code>createTest()</code> method is the most important to implement here, it actually instantiates the test class with the right config.  <code>testName()</code> is also very important, it should uniquely identify the test with its config, and it&#8217;s what things like maven will display as the name of the test.  Naming it appropiately will allow you to easily see which config the test failed under.</p>
<p>Now I&#8217;m going to write my custom runner that I will pass to the<code> @TestRunner</code> annototation, it will build up a tree of nested <code>NamedParentRunner</code>&#8216;s.</p>
<pre>public static class EmailGenerationRunner extends Suite {
  public EmailGenerationRunner(Class&lt;?&gt; klass) throws InitializationError {
    super(klass, createChildren(klass));
  }
  private static List&lt;Runner&gt; createChildren(Class&lt;?&gt; klass) throws InitializationError {
    List&lt;Runner&gt; variants = new ArrayList&lt;Runner&gt;();
    for (Variant variant : Variant.values()) {
      List&lt;Runner&gt; types = new ArrayList&lt;Runner&gt;();
      for (NotificationType type : NotificationType.values()) {
        List&lt;Runner&gt; platforms = new ArrayList&lt;Runner&gt;();
        for (Platform platform : Platform.values()) {
          List&lt;Runner&gt; languages = new ArrayList&lt;Runner&gt;();
          for (Language language : Language.values()) {
            languages.add(new TestRunner(klass, variant, type, platform, language));
          }
          platforms.add(new NamedParentRunner(klass, languages, platform.name()));
        }
        types.add(new NamedParentRunner(klass, platforms, type.name()));
      }
      variants.add(new NamedParentRunner(klass, types, variant.name()));
    }
    return variants;
  }
}</pre>
<p>This is a fair bit more code than our initial attempt, and is also a lot of code for a single test class. But when you consider that this single test is running hundreds of sub tests that test the core functionality of my appliaction, it&#8217;s not so bad. And the results are really quite nice. This is now what it looks like in IDEA, I get a tree of permutations and can click to expand them to see what passed and what failed:<a href="http://developer.vz.net/2011/11/11/testing-permutations-of-configurations/custom-suite-1/" rel="attachment wp-att-3098"><img class="aligncenter size-full wp-image-3098" src="http://developer.vz.net/wp-content/uploads/2011/11/custom-suite-1.jpg" alt="Custom suite test run in IntelliJ IDEA" width="511" height="314" /></a>So now we&#8217;ve seen some quite advanced methods for testing many permutations of configurations over the same code in JUnit. Since implementing this in notificator, I&#8217;ve been able to much more confidently make major refactorings of my templates, as well as add new notification types without having to worry about manually checking every platform, language and variant combination. I hope this will help you in the same way.</p>
<p>You can download the above example code from <a title="GitHub testing permutations example code" href="https://github.com/jroper/testing-permutations">GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/11/11/testing-permutations-of-configurations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit testing Java mail code</title>
		<link>http://developer.vz.net/2011/11/08/unit-testing-java-mail-code/</link>
		<comments>http://developer.vz.net/2011/11/08/unit-testing-java-mail-code/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 10:39:34 +0000</pubDate>
		<dc:creator>James Roper</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=3080</guid>
		<description><![CDATA[GreenMail is a mail testing tool that has been around for a long time, but I&#8217;m surprised by how few people actually know about it.  I&#8217;ve found it very useful on many occasions for testing my mail sending code, both &#8230; <a href="http://developer.vz.net/2011/11/08/unit-testing-java-mail-code/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a title="GreenMail home page" href="http://www.icegreen.com/greenmail/">GreenMail</a> is a mail testing tool that has been around for a long time, but I&#8217;m surprised by how few people actually know about it.  I&#8217;ve found it very useful on many occasions for testing my mail sending code, both in integration/acceptance style tests, and also in unit tests.  In this post I&#8217;m going to give a short introduction to using GreenMail with JUnit, and then I&#8217;ll add a number of advanced tips that I&#8217;ve learned from my experience to help you effectively test your code. For my examples I&#8217;m going to be testing a class that I&#8217;ve written called <code>MailSender</code>.</p>
<h2>Using GreenMail with JUnit</h2>
<p>GreenMail starts as a server listening on ports for SMTP/POP/IMAP connections, these are naturally handled by background threads. In order to use GreenMail in unit testing, you need to start it up before each test and shut it down again after.  GreenMail is incredibly fast to startup and shutdown so there&#8217;s no worries about performance of your tests here.</p>
<pre>private static final int SMTP_TEST_PORT = 3025;
private GreenMail greenMail;
private MailSender mailSender;

@Before
public void setUp() throws Exception {
    greenMail = new GreenMail(new ServerSetup(SMTP_TEST_PORT, null, "smtp"));
    greenMail.start();
    mailSender = new MailSender("localhost", SMTP_TEST_PORT);
}
@After
public void tearDown() throws Exception {
    greenMail.stop();
}</pre>
<p>Now I&#8217;m ready to write my tests.  Here&#8217;s an example test:</p>
<pre>@Test
public void sendShouldSetTheRightText() throws Exception {
    mailSender.send("Hello World!");
    assertThat((String) greenMail.getReceivedMessages()[0].getContent(),
        equalTo("Hello World!"));
}</pre>
<p>The <code>getReceivedMessages()</code> method returns an array of <code>javax.mail.internet.MimeMessage</code>, each of which contains all the mime information from each sent email. Note that in this case, I&#8217;m assuming that everything is happening synchronously, which it is. Sometimes though (particularly in integration tests) mail is put onto a queue and sent asynchronously. GreenMail offers a handy method for dealing with this, <code>waitForIncomingMail()</code>, which accepts a timeout and a number of emails you want to wait for, and returns a boolean letting you know whether the mail you were waiting for arrived.</p>
<h2>Selecting a good port</h2>
<p>The above code works fine if you know that port 3025 is free. But you don&#8217;t always know that, particularly if you&#8217;re running your tests on a CI server, that CI server may be running another job that is trying to use the same port. I&#8217;ve found the following code useful for picking a good port:</p>
<pre>private static int findAvailablePort(int min, int max) {
    for (int port = min; port &lt; max; port++) {
        try {
            new ServerSocket(port).close();
            return port;
        } catch (IOException e) {
            // Must already be taken
        }
    }
    throw new IllegalStateException("Could not find available port in range "
            + min + " to " + max);
}</pre>
<p>I can now specify a range of ports and my code will choose one that is free.</p>
<h2>Checking who the mail was actually sent to</h2>
<p>As you know, mime headers can often lie. Just like the header on a letter might be different to the name on the envelope, the To header set in a mime header might be different to that sent to the SMTP server. This is also known as bccing, and it may be the case that your code uses this. If that is the case, you can&#8217;t run assertions on the To field to ensure that the email was actually sent to the right person (although, due to <a href="https://sourceforge.net/tracker/?func=detail&amp;aid=2943790&amp;group_id=159695&amp;atid=812857">this bug</a> in GreenMail you actually can, but you can&#8217;t know whether they <em>weren&#8217;t</em> added to the To header by your code). However, GreenMail provides a way to get mail that was actually delivered to a particular user. The first thing you need to do is get a reference to the object for that user, this is most easily done by setting their password, I do this in the <code>setUp()</code> method:</p>
<pre>greenMailUser = greenMail.setUser("recipient@example.org", null);</pre>
<p>Now when it comes to writing my tests, I can look up that users inbox and find the messages that are in it:</p>
<pre>MailFolder inbox = greenMail.getManagers().getImapHostManager().getInbox(greenMailUser);
List&lt;StoredMessage&gt; messages = inbox.getMessages();
if (!messages.isEmpty()) {
    messages.get(0).getMimeMessage();
    ...
} else {
    fail("No email for user arrived")
}</pre>
<h2>Checking the envelope from address</h2>
<p>A similar issue to bccing is telling the SMTP server that you&#8217;re sending from a different email address to the email address you put in the mime headers. This is also known as the envelope from or bounce address, and it&#8217;s typically used for error reporting, for example, to tell the sender that the mailbox doesn&#8217;t exist. This can be set in Java by creating an instance of <code>com.sun.mail.smtp.SMTPMessage</code> instead of <code>MimeMessage</code> and setting it using the <code>setEnvelopeFrom()</code> method. This is not a mime header that we can just check, however SMTP servers are required to put this address into the email in the mime header <code>Return-Path</code>. GreenMail does this to. So to assert that the correct envelope from address was set:</p>
<pre>String returnPathHeader = message.getHeader("Return-Path", ",");
assertThat(returnPathHeader, notNullValue());
InternetAddress returnPath = InternetAddress.parse(returnPathHeader)[0];
assertThat(returnPath.getAddress(), equalTo("bounce-notify@example.org"));</pre>
<p>That concludes my post on using GreenMail, if you have any other helpful tips for using GreenMail, please share them as comments here!</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/11/08/unit-testing-java-mail-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Voldemort backups</title>
		<link>http://developer.vz.net/2011/11/04/voldemort-backups/</link>
		<comments>http://developer.vz.net/2011/11/04/voldemort-backups/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 16:40:08 +0000</pubDate>
		<dc:creator>James Roper</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[Datenbank]]></category>
		<category><![CDATA[Voldemort]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=3071</guid>
		<description><![CDATA[At VZnet we use a number of different storage technologies, including both relational and NoSQL databases.  One database that powers a number of our services is Voldemort.  Voldemort is an open source key value store written by LinkedIn.  Some of &#8230; <a href="http://developer.vz.net/2011/11/04/voldemort-backups/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>At VZnet we use a number of different storage technologies, including both relational and <a title="NoSQL databases" href="http://nosql-database.org/">NoSQL</a> databases.  One database that powers a number of our services is <a title="Voldemort homepage" href="http://project-voldemort.com/">Voldemort</a>.  Voldemort is an open source key value store written by <a title="LinkedIn" href="http://www.linkedin.com/">LinkedIn</a>.  Some of the features that we really like about it is its very high scalability and its automatic partitioning and replication of data across storage nodes.</p>
<p>When I talk about backing up Voldemort, many might question whether that is really needed.  Data is already replicated across nodes, if one node dies or becomes corrupted, the data should safely exist somewhere else in the system.  This is true, with data replication you don&#8217;t need to worry about backing up for the purposes of protecting yourself against hardware failure.  However, that&#8217;s not the only reason why you might want to backup.</p>
<p>All software contains bugs, and our services at VZnet are no exception.  Voldemort itself is also no exception.  We can do our best to eliminate bugs through testing, but they will always pop up and we need to be prepared to deal with that.  One type of bug that could occur is a bug that corrupts data.  What if we pushed an update that, though it passed the tests, contained a race condition that under load results in the wrong data being associated with the wrong keys.  Replication won&#8217;t help you there, Voldemort will, by design, replicate the data corruption your code has caused across its nodes.  There are many other places where replication won&#8217;t help you, like if all your storage nodes use the same SAN and your SAN overheats destroying all its disks, or a dangerously under-skilled business owner decides to try to query the <del>database</del> er&#8230; key-value store and in the process deletes all your data.  But potential corruption due to bugs in our code was the issue that we were most worried about.</p>
<p>So, how do we go about backing up a Voldemort datastore?  The first question that needs to be answered is how Voldemort is storing its data.  Voldemort has pluggable back-end storage support, with the primary two back-ends available being MySQL and the Java implementation of <a title="Oracle Berkeley DB download page" href="http://www.oracle.com/technetwork/database/berkeleydb/downloads/index.html">Berkeley-DB</a> (BDB).  We&#8217;re using BDB, so the next question we need to ask is how do we backup a BDB database?  Some answers on forums on the web point out that since BDB is an append only database, backups can be done safely by just copying its files.  This is only partially true.  BDB is an append only database, however it also has a clean up thread.  The clean up thread periodically scans through the database and removes outdated entries from the database and compacts the files.  This stops the database from constantly growing every time a record is updated.  It also means that if you copy the files while the clean up thread is running, you risk having a corrupt backup.</p>
<p>Fortunately, the Java BDB implementation comes with a <a title="DbBackup javadocs" href="http://download.oracle.com/docs/cd/E17277_02/html/java/com/sleepycat/je/util/DbBackup.html">tool</a> that can be used to assist with backups.  In short, the tool pauses the clean up thread, finishes the current file that is being appended to, and then gives you a list of files that you can backup.  It supports incremental backups too, which is great for large databases.</p>
<p>My first naive attempt to use this tool was to write a small Java program that ran independent of Voldemort.  This was a failure, because an external process can&#8217;t pause the clean up thread, nor can it even access the database because Voldemort has it locked.  So I needed to implement something into Voldemort.  Controlling this feature is most sensibly done using the Voldemort admin tool, which I found very easy to extend.  The result can be found in the <strong>bdb-backup</strong> branch of <a title="Voldemort fork for BDB backups" href="https://github.com/jroper/voldemort/tree/bdb_backup">my fork of Voldemort</a> on GitHub.  I&#8217;ve initiated a <a title="BDB native backups pull request" href="https://github.com/voldemort/voldemort/pull/54">pull request</a> and hopefully the folks at LinkedIn will be happy to accept it.</p>
<p>The feature can be used by passing a new <code>--native-backup</code> command line option, information about how to use this is built into the admin clients help.  Using this new feature you can now create guaranteed consistent backups of your BDB Voldemort nodes, and you can rest assured knowing that you can recover from the many data corruption issues that replication won&#8217;t save you from.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/11/04/voldemort-backups/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Browser Update-Zyklen in Graphen</title>
		<link>http://developer.vz.net/2011/10/21/browser-update-zyklen-in-graphen/</link>
		<comments>http://developer.vz.net/2011/10/21/browser-update-zyklen-in-graphen/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 14:06:18 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[stats]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=2969</guid>
		<description><![CDATA[Nachdem wir letzte Woche schon einen kleinen Ausschnitt aus unseren Browserstatistiken zum Firefox 7 gepostet haben, hier noch 3 weitere interessante Graphen: Firefox 3.6 bis Firefox 7.0 (01.11.2009 bis 01.10.2011) Chrome 11 bis Chrome 14 (17.05.2011 bis 17.10.2011, der grüne &#8230; <a href="http://developer.vz.net/2011/10/21/browser-update-zyklen-in-graphen/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Nachdem wir letzte Woche schon einen kleinen Ausschnitt aus unseren <a href="http://developer.vz.net/2011/10/12/firefox-7-auto-update/" title="Firefox 7 Auto-Update">Browserstatistiken zum Firefox 7</a> gepostet haben, hier noch 3 weitere interessante Graphen:</p>
<p>Firefox 3.6 bis Firefox 7.0 (01.11.2009 bis 01.10.2011)<br />
<a href="http://developer.vz.net/wp-content/uploads/2011/10/firefox.png"><img class="alignnone size-full wp-image-2980" title="firefox" src="http://developer.vz.net/wp-content/uploads/2011/10/firefox.png" alt="" width="848" height="287" /></a></p>
<p>Chrome 11 bis Chrome 14 (17.05.2011 bis 17.10.2011, der grüne Graph aka &#8220;Unknown Chrome&#8221; ist dem Chrome 13 zuzurechnen)<br />
<a href="http://developer.vz.net/wp-content/uploads/2011/10/chrome.png"><img class="alignnone size-full wp-image-2981" title="chrome" src="http://developer.vz.net/wp-content/uploads/2011/10/chrome.png" alt="" width="845" height="288" /></a></p>
<p>Internet Explorer 6 bis Internet Explorer 9 (1.10.2009 bis 1.10.2011)<br />
<a href="http://developer.vz.net/wp-content/uploads/2011/10/ie.png" target="_blank"><img class="alignnone size-full wp-image-2982" title="ie" src="http://developer.vz.net/wp-content/uploads/2011/10/ie.png" alt="" width="856" height="289" /></a></p>
<p>Was denkt ihr: Machen die schnellen Release-Zyklen Sinn, oder sorgen die nur für Verwirrung beim Nutzer?</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/10/21/browser-update-zyklen-in-graphen/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Firefox 7 Auto-Update</title>
		<link>http://developer.vz.net/2011/10/12/firefox-7-auto-update/</link>
		<comments>http://developer.vz.net/2011/10/12/firefox-7-auto-update/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 12:15:14 +0000</pubDate>
		<dc:creator>Nils Juenemann</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[browser]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=2949</guid>
		<description><![CDATA[Spannend wie schnell Mozilla das automatische Updates zum Endnutzer bringt. In zwei Wochen wurden so gut wie alle Nutzer automatisch auf die neue Version migriert. Wird Zeit, dass die verbleibenden Browser ähnliche Mechanismen etablieren und es damit den Nutzern und &#8230; <a href="http://developer.vz.net/2011/10/12/firefox-7-auto-update/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">Spannend wie schnell Mozilla das automatische Updates zum Endnutzer bringt. In zwei Wochen wurden so gut wie alle Nutzer automatisch auf die neue Version migriert. Wird Zeit, dass die verbleibenden Browser ähnliche Mechanismen etablieren und es damit den Nutzern und auch den Web-Entwicklern einfacher machen.</p>
<p><a href="http://developer.vz.net/wp-content/uploads/2011/10/Bildschirmfoto-2011-10-11-um-15.11.38.png" target="_blank"><img class="aligncenter size-full wp-image-2950" title="Firefox 7" src="http://developer.vz.net/wp-content/uploads/2011/10/Bildschirmfoto-2011-10-11-um-15.11.38.png" alt="" width="848" height="275" /></a>(In der Grafik sind _nicht alle_ Browser abgebildet)</p>
<p>Wir unterstützen mit unserer neusten Version (<a href="http://code.google.com/intl/de-DE/webtoolkit/">GWT</a> basierend) folgende Browser:</p>
<ul>
<li>Firefox 3.6+</li>
<li>Chrome 11+</li>
<li>Internet Explorer 7+</li>
<li>Opera 11.5</li>
<li>Safari 5+</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/10/12/firefox-7-auto-update/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Slides zur GEEKcon vom 5. April</title>
		<link>http://developer.vz.net/2011/04/26/slides-zur-geekcon-vom-5-april/</link>
		<comments>http://developer.vz.net/2011/04/26/slides-zur-geekcon-vom-5-april/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 08:32:50 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[GEEKcon]]></category>
		<category><![CDATA[Resources]]></category>

		<guid isPermaLink="false">http://developer.vz.net/?p=2930</guid>
		<description><![CDATA[To get the latest presentations from our GEEKcon events you can follow our profile on slideshare http://www.slideshare.net/GEEKcon Slides from April 5th: &#8220;Differenzial Analyse in der Praxis, Wie man mit Hilfe von Differenzial Analyse die Zufälligkeit von Werten analysiert&#8221; by Florian &#8230; <a href="http://developer.vz.net/2011/04/26/slides-zur-geekcon-vom-5-april/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>To get the latest presentations from our GEEKcon events you can follow our profile on slideshare <a href="http://www.slideshare.net/GEEKcon">http://www.slideshare.net/GEEKcon</a></p>
<p>Slides from April 5th:</p>
<p>&#8220;<strong>Differenzial Analyse in der Praxis</strong>, Wie man mit Hilfe von Differenzial Analyse die Zufälligkeit von Werten analysiert&#8221; by Florian Walther<br />
<a href="http://www.slideshare.net/GEEKcon/differenzial-analyse-in-der-praxis-florian-walther">http://www.slideshare.net/GEEKcon/differenzial-analyse-in-der-praxis-florian-walther </a></p>
<p>&#8220;<strong>Webdocumentaries</strong> &#8211; Die Technik hinter interaktiven Domumentationen im Netz&#8221; by Jan Petzold<br />
<a href="http://www.slideshare.net/GEEKcon/webdocumentaries-die-technik-hinter-interaktiven-dokumentationen-im-netz-jan-petzold">http://www.slideshare.net/GEEKcon/webdocumentaries-die-technik-hinter-interaktiven-dokumentationen-im-netz-jan-petzold </a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/04/26/slides-zur-geekcon-vom-5-april/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GEEKcon am 5. April 2011</title>
		<link>http://developer.vz.net/2011/03/31/geekcon-am-5-april-2011/</link>
		<comments>http://developer.vz.net/2011/03/31/geekcon-am-5-april-2011/#comments</comments>
		<pubDate>Thu, 31 Mar 2011 11:14:50 +0000</pubDate>
		<dc:creator>sebastian</dc:creator>
				<category><![CDATA[Dates]]></category>
		<category><![CDATA[GEEKcon]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2859</guid>
		<description><![CDATA[Wir laden zur nächsten GEEKcon ein. Die Veranstaltung ist kostenlos und für Getränke ist gesorgt. 5. April 2011 Ab 18:30 Uhr öffnet der Roadrunner’s Club seine Pforten. Die Vorträge beginnen um 19:15 Uhr. Agenda &#160; Multimediale Kommunikation mit dem Plauderkasten Tom &#8230; <a href="http://developer.vz.net/2011/03/31/geekcon-am-5-april-2011/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Wir laden zur nächsten GEEKcon ein. Die Veranstaltung ist <strong>kostenlos</strong> und für Getränke ist gesorgt.</p>
<ul>
<li>5. April 2011</li>
<li>Ab 18:30 Uhr öffnet der <a href="http://www.roadrunners-paradise.de/anfahrt.php">Roadrunner’s Club</a> seine Pforten.</li>
<li>Die Vorträge beginnen um 19:15 Uhr.</li>
</ul>
<p><strong>Agenda</strong></p>
<p>&nbsp;</p>
<ul>
<li><strong>Multimediale Kommunikation mit dem Plauderkasten</strong> Tom Hensel (VZnet Netzwerke)</li>
<li><strong>Automatisierungstechnologien für die Infrastruktur mit Chef</strong> von Frederic Jaeckel (SoundCloud)</li>
<li><strong>WebDocumentaries: Die Technik hinter interaktiven Dokumentationen im Netz</strong> von Jan Petzold (Deutsche Welle)</li>
</ul>
<p>&nbsp;</p>
<p>PS:</p>
<p>Die GEEKcon ist eine Veranstaltungsreihe, mit dem Ziel gemeinsam über neue Technologien, aktuelle Projekte und Probleme und innovative Lösungsansätze im Bereich Software- und Webentwicklung zu diskutieren. Alle zwei Monate treffen sich Entwickler, Anwender, Unternehmer und sonstige Web-Interessierte im Roadrunner’s Club in Berlin Prenzlauer Berg zum Gedanken- und Ideenaustausch.</p>
<p>Die GEEKcon steht allen offen, die sich für die Zukunft des Internets interessieren und diese mitgestalten wollen: vom Anfänger bis zum Experten, vom Entwickler bis zum Blogger. Organisiert wird die Veranstaltung von den VZ-Netzwerken.</p>
<p>Zur GEEKcon laden wir in der Regel drei Referenten ein, ihr Thema in einem etwa 20 minütigen Vortrag zu präsentieren. Im Anschluss daran können wir bei dem einem oder anderem Bierchen gemeinsam diskutieren, Leute treffen, Kontakte knüpfen und Jobs finden.</p>
<p>Herzlich Willkommen sind auch all jene, die die GEEKcon nutzen möchten, um eigene Projekte und Produkte vorzustellen. Vorträge können mit Angabe eines Themas unter <strong>geekcon@vz.net</strong> bei uns eingereicht werden.</p>
<p><a href="http://maps.google.de/maps?f=q&amp;source=embed&amp;hl=de&amp;geocode=&amp;q=Roadrunners+Club+ausgehen+%26+genie%C3%9Fen:+Diskotheken+und+Clubs,+Saarbr%C3%BCcker+Stra%C3%9Fe,+Berlin&amp;aq=0&amp;sll=52.462608,13.244639&amp;sspn=0.225077,0.617294&amp;ie=UTF8&amp;hq=Roadrunners+Club+ausgehen+%26+genie%C3%9Fen:+Diskotheken+und+Clubs,&amp;hnear=Saarbr%C3%BCcker+Stra%C3%9Fe,+Berlin&amp;ll=52.530517,13.413577&amp;spn=0.004569,0.00912&amp;z=16&amp;iwloc=A">Größere Kartenansicht</a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/03/31/geekcon-am-5-april-2011/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Update profile picture from an OpenSocial App</title>
		<link>http://developer.vz.net/2011/03/30/update-profile-picture-from-an-opensocial-app/</link>
		<comments>http://developer.vz.net/2011/03/30/update-profile-picture-from-an-opensocial-app/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 07:19:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[OpenSocial]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2852</guid>
		<description><![CDATA[This week we released the possibility to change the current VIEWER&#8217;s profile picture from within any OpenSocial app through the OpenSocial JavaScript API: var person = opensocial.newPerson({thumbnailUrl : 'BASE64_ENCODED_PHOTO'}); opensocial.requestUpdateViewer(person, function(response) { // response is either true or false  }); &#8230; <a href="http://developer.vz.net/2011/03/30/update-profile-picture-from-an-opensocial-app/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This week we released the possibility to change the current VIEWER&#8217;s profile picture from within any OpenSocial app through the OpenSocial JavaScript API:</p>
<blockquote>
<pre>var person = opensocial.newPerson({thumbnailUrl : 'BASE64_ENCODED_PHOTO'});
opensocial.requestUpdateViewer(person, function(response) {
   // response is either true or false 
});</pre>
</blockquote>
<p>When the requestUpdateViewer method is called we will ask the user if he really wants to change his profile picture to the new one. The user&#8217;s decision will be passed as a parameter to the callback function. As a developer you have to pass the new picture in the thumbnailUrl field of the <a href="http://developer.studivz.net/wiki/index.php/Opensocial.Person_(v0.9)" target="_blank">opensocial.Person</a> object. The content of this field is just the base64 encoded image in a valid <a href="http://en.wikipedia.org/wiki/Data_URI_scheme" target="_blank">Data-URL</a> format.</p>
<p>For more information see <a href="http://developer.studivz.net/wiki/index.php/Opensocial_(v0.9)#opensocial.requestUpdateViewer" target="_blank">http://developer.studivz.net/wiki/index.php/Opensocial_(v0.9)#opensocial.requestUpdateViewer</a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/03/30/update-profile-picture-from-an-opensocial-app/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VZnet @ IPC 2011 Spring</title>
		<link>http://developer.vz.net/2011/03/30/vznet-ipc-2011-spring/</link>
		<comments>http://developer.vz.net/2011/03/30/vznet-ipc-2011-spring/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 06:54:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Conference]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2847</guid>
		<description><![CDATA[We are happy to announce that we will take part at this years International PHP Conference (May 29 &#8211; June 1 in Berlin) with the following talk: Mashing up JavaScript – Advanced Techniques for modern Web Apps Bastian Hofmann,VZnet Netzwerke &#8230; <a href="http://developer.vz.net/2011/03/30/vznet-ipc-2011-spring/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We are happy to announce that we will take part at this years International PHP Conference (May 29 &#8211; June 1 in Berlin) with the following talk:</p>
<blockquote>
<h3>Mashing up JavaScript – Advanced Techniques for modern Web Apps</h3>
<p>Bastian Hofmann,VZnet Netzwerke Ltd.</p>
<div>2011-05-31 | 02:15 PM &#8211; 03:15 PM</div>
<p>Nowadays many modern web applications are solely relying on JavaScript to render their frontend. But if you want to create mashups, load data from many different places or include external widgets into your site, you are quickly running into boundaries because of browser and security restrictions. In this presentation I will talk about techniques helping you with such problems.</p></blockquote>
<p>For more information, tickets etc see <a href="http://phpconference.com/2011spring" target="_blank">http://phpconference.com/2011spring</a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/03/30/vznet-ipc-2011-spring/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Gadgets: Daily Active Users and Monthly Active Users Statistics now in Sandbox</title>
		<link>http://developer.vz.net/2011/02/24/gadgets-daily-active-users-and-monthly-active-users-statistics-now-in-sandbox/</link>
		<comments>http://developer.vz.net/2011/02/24/gadgets-daily-active-users-and-monthly-active-users-statistics-now-in-sandbox/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 10:45:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[OpenSocial]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2835</guid>
		<description><![CDATA[Next to installations and un-installations we have been tracking the actual activity within OpenSocial apps for several months now. And starting today these statistics about daily active users (DAU) and monthly active users (MAU) are also accessible for every gadget &#8230; <a href="http://developer.vz.net/2011/02/24/gadgets-daily-active-users-and-monthly-active-users-statistics-now-in-sandbox/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Next to installations and un-installations we have been tracking the actual activity within OpenSocial apps for several months now. And starting today these statistics about daily active users (DAU) and monthly active users (MAU) are also accessible for every gadget developer easily in the statistics section of their gadget:</p>
<p><a rel="attachment wp-att-2836" href="http://developer.studivz.net/2011/02/24/gadgets-daily-active-users-and-monthly-active-users-statistics-now-in-sandbox/bildschirmfoto-2011-02-24-um-10-49-39/"><img class="aligncenter size-full wp-image-2836" title="DAU &amp; MAU in Sandbox" src="http://developer.studivz.net/wp-content/uploads/2011/02/Bildschirmfoto-2011-02-24-um-10.49.39.png" alt="" width="613" height="436" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/02/24/gadgets-daily-active-users-and-monthly-active-users-statistics-now-in-sandbox/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Desktop Notifications meets Plauderkasten</title>
		<link>http://developer.vz.net/2011/02/03/desktopnotifications-meets-plauderkasten/</link>
		<comments>http://developer.vz.net/2011/02/03/desktopnotifications-meets-plauderkasten/#comments</comments>
		<pubDate>Thu, 03 Feb 2011 12:46:32 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Plauderkasten]]></category>
		<category><![CDATA[notifications]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2775</guid>
		<description><![CDATA[Der eine oder andere von Euch wird es im Chrome schon gesehen haben: Wir testen seit Anfang des Jahres Desktop Notifications für den Plauderkasten! Das Ganze basiert auf dem “WebNotifications Standard Draft” des W3C und wurde bisher leider nur im &#8230; <a href="http://developer.vz.net/2011/02/03/desktopnotifications-meets-plauderkasten/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Der eine oder andere von Euch wird es im Chrome schon gesehen haben: </p>
<p>Wir testen seit Anfang des Jahres Desktop Notifications für den Plauderkasten! Das Ganze basiert auf dem “<a href="http://dev.w3.org/2006/webapi/WebNotifications/publish/">WebNotifications Standard Draft</a>” des W3C und wurde bisher leider nur im Chrome implementiert. Seit ein paar Tagen nutzt Google Mail das Feature auch. Hier wird man als eingeloggter Nutzer über neue Mails oder Chatnachrichten informiert.</p>
<p>Wie funktioniert das Ganze?<br />
Der Standard beschreibt eine API, die der Browser bereitstellt und welche mittels JavaScript angesprochen werden kann. Ist das ganze korrekt implementiert werden die Desktophinweise (“Notifications”) entsprechend den gewünschten Werten dargestellt. Das war’s eigentlich auch schon. ;-)</p>
<p>Ein wenig Code dazu:<br />
<code>//gather permission through user input<br />
window.webkitNotifications.requestPermission();<br />
</code></p>
<p><code>//create and show notification<br />
notificationObject = window.webkitNotifications.createNotification(image_url, name, message);<br />
notificationObject.show();<br />
</code></p>
<p>Aus Nutzersicht:<br />
Initial muss man Desktop Notifications domainspezifisch aktivieren. Das geht momentan über den Plauderkasten-Einstellungsdialog. Den findet ihr beim geöffneten Plauderkasten links oben mit einem Klick auf den Schraubenschlüssel.</p>
<p><a rel="attachment wp-att-2781" href="http://developer.studivz.net/2011/02/03/desktopnotifications-meets-plauderkasten/plauderkasten-settingsdialog/"><img class="alignnone size-medium wp-image-2781" title="Plauderkasten SettingsDialog" src="http://developer.studivz.net/wp-content/uploads/2011/02/Plauderkasten-SettingsDialog-300x154.png" alt="" width="300" height="154" /></a></p>
<p>Ein weiterer Klick auf &#8220;Aktivieren&#8221; erzeugt im Chrome die Abfrage zum freischalten der Domain.</p>
<p><a rel="attachment wp-att-2780" href="http://developer.studivz.net/2011/02/03/desktopnotifications-meets-plauderkasten/plauderkasten-requestnotificationpermission/"><img class="alignnone size-full wp-image-2780" title="Plauderkasten RequestNotificationPermission" src="http://developer.studivz.net/wp-content/uploads/2011/02/Plauderkasten-RequestNotificationPermission.png" alt="" width="731" height="52" /></a></p>
<p>Nach einem weiteren Klick auf &#8220;zulassen&#8221; ist wird die Berechtigung im Broswer gespeichert und ihr solltet die erste Notification sehen.</p>
<p><a rel="attachment wp-att-2779" href="http://developer.studivz.net/2011/02/03/desktopnotifications-meets-plauderkasten/plauderkasten-notification/"><img class="alignnone size-medium wp-image-2779" title="Plauderkasten Notification" src="http://developer.studivz.net/wp-content/uploads/2011/02/Plauderkasten-Notification-300x74.png" alt="" width="300" height="74" /></a></p>
<p>Bei neuen Nachrichten von Personen, mit denen ihr euch gerade nicht unterhaltet, sollten nun Desktop Notifications auftauchen. Diese enthalten Namen und Nutzerbild des Absenders, sowie die Nachricht. Dazu muss der Plauderkasten allerdings momentan noch geöffnet sein (man kann ihn ja im Hintergrund auflassen ;-)).</p>
<p>Wir hoffen, dass auch die anderen Browserhersteller auf den Zug aufspringen und diesen Standard weiter vorrantreiben.</p>
<p>Quellen und weitere Links:<br />
<a href="http://dev.w3.org/2006/webapi/WebNotifications/publish/">http://dev.w3.org/2006/webapi/WebNotifications/publish/</a><br />
<a href="http://dev.chromium.org/developers/design-documents/desktop-notifications/api-specification">http://dev.chromium.org/developers/design-documents/desktop-notifications/api-specification</a><br />
<a href="http://dev.chromium.org/developers/design-documents/desktop-notifications">http://dev.chromium.org/developers/design-documents/desktop-notifications</a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/02/03/desktopnotifications-meets-plauderkasten/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>VZnet at Confoo Conference</title>
		<link>http://developer.vz.net/2011/01/21/vznet-at-confoo-conference/</link>
		<comments>http://developer.vz.net/2011/01/21/vznet-at-confoo-conference/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 15:00:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Dates]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Conference]]></category>
		<category><![CDATA[OpenID]]></category>
		<category><![CDATA[OpenSocial]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2756</guid>
		<description><![CDATA[VZnet is taking part at this year&#8217;s Confoo Conference in Montreal, Canada (March 9th &#8211; March 11th) with the following two talks: Distributed Identities with OpenID English session The era of many separated logins and identities in the web is &#8230; <a href="http://developer.vz.net/2011/01/21/vznet-at-confoo-conference/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>VZnet is taking part at this year&#8217;s <a href="http://confoo.ca/en" target="_blank">Confoo Conference</a> in Montreal, Canada (March 9th &#8211; March 11th) with the following two talks:</p>
<blockquote>
<h2>Distributed Identities with OpenID</h2>
<div>English session</div>
<div>The era of many separated logins and identities in the web is slowly coming to an end. Currently many of the big players are spurring this on with their own proprietary solutions, but open standards are starting to get more support as well with OpenID being the most promising one. In this session I will show how OpenID works for users and developers, where it currently fails and how OpenID is planned to evolve in the future.</div>
<div>Speaker: Bastian Hofmann</div>
<div><a href="http://confoo.ca/en/2011/session/distributed-identities-with-openid" target="_blank">http://confoo.ca/en/2011/session/distributed-identities-with-openid</a></div>
<div>
<h2>How to create social apps for millions of users</h2>
<div>English session</div>
</div>
<div>Social apps have become very popular in the last years. In this session I will show you how to create an OpenSocial app which can be used by over 900 million users on many social networks around the world. After introducing you to the main concepts behind OpenSocial I will demonstrate live that it is easier than you think to develop a rich social app. Additionally to the basics like accessing the user&#8217;s social graph or integration with external APIs, I will also highlight features that will help you with a quick viral distribution, tight integration into the user&#8217;s social experience and access through mobile devices.</div>
<div>Speaker: Bastian Hofmann</div>
<div><a href="http://confoo.ca/en/2011/session/how-to-create-social-apps-for-millions-of-users" target="_blank">http://confoo.ca/en/2011/session/how-to-create-social-apps-for-millions-of-users</a></div>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/01/21/vznet-at-confoo-conference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GEEKcon am 8. Februar 2011</title>
		<link>http://developer.vz.net/2011/01/21/geekcon-am-8-februar-2011/</link>
		<comments>http://developer.vz.net/2011/01/21/geekcon-am-8-februar-2011/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 14:47:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[GEEKcon]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2751</guid>
		<description><![CDATA[8. Februar 2011 Ab 18:30 Uhr öffnet der Roadrunner’s Club seine Pforten. Die Vorträge beginnen um 19:00 Uhr. UPDATE Die Referenten stehen jetzt fest: Der kleinste Computer-Cluster der Welt von Tim Lossen (wooga) User Centered Prozesse von Choukri Bijjou (VZ-Netzwerke) &#8230; <a href="http://developer.vz.net/2011/01/21/geekcon-am-8-februar-2011/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<ul>
<li>8. Februar 2011</li>
<li>Ab 18:30 Uhr öffnet der <a href="http://www.roadrunners-paradise.de/anfahrt.php">Roadrunner’s Club</a> seine Pforten.</li>
<li>Die Vorträge beginnen um 19:00 Uhr.</li>
</ul>
<p><strong>UPDATE</strong> Die Referenten stehen jetzt fest:</p>
<ul>
<li><strong>Der kleinste Computer-Cluster der Welt </strong> von Tim Lossen (<a href="http://www.wooga.com/">wooga</a>)</li>
<li><strong>User Centered Prozesse</strong> von Choukri Bijjou (<a href="http://www.vz.net">VZ-Netzwerke</a>)</li>
<li><strong>Google Web Toolkit</strong> von Raphael Bauer und Dominic Jansen (beide <a href="http://www.vz.net">VZ-Netzwerke</a>)</li>
</ul>
<p>Die GEEKcon ist eine Veranstaltungsreihe, mit dem Ziel gemeinsam über  neue Technologien, aktuelle Projekte und Probleme und innovative  Lösungsansätze im Bereich Software- und Webentwicklung zu diskutieren.  Alle zwei Monate treffen sich Entwickler, Anwender, Unternehmer und  sonstige Web-Interessierte im Roadrunner’s Club in Berlin Prenzlauer  Berg zum Gedanken- und Ideenaustausch.</p>
<p>Die GEEKcon steht allen offen, die sich für die Zukunft des Internets  interessieren und diese mitgestalten wollen: vom Anfänger bis zum  Experten, vom Entwickler bis zum Blogger. Organisiert wird die  Veranstaltung von den VZ-Netzwerken.</p>
<p>Zur GEEKcon laden wir in der Regel drei Referenten ein, ihr Thema in  einem etwa 30 minütigen Vortrag zu präsentieren. Im Anschluss daran  können wir bei dem einem oder anderem Bierchen gemeinsam diskutieren,  Leute treffen, Kontakte knüpfen und Jobs finden. Herzlich Willkommen  sind auch all jene, die die GEEKcon nutzen möchten, um eigene Projekte  und Produkte vorzustellen.</p>
<p>Vorträge können mit Angabe eines Themas unter <strong>geekcon@vz.net</strong> bei uns eingereicht werden.</p>
<p>Die Veranstaltung ist kostenlos und für Getränke ist gesorgt.<br />
<a href="http://maps.google.de/maps?f=q&amp;source=embed&amp;hl=de&amp;geocode=&amp;q=Roadrunners+Club+ausgehen+%26+genie%C3%9Fen:+Diskotheken+und+Clubs,+Saarbr%C3%BCcker+Stra%C3%9Fe,+Berlin&amp;aq=0&amp;sll=52.462608,13.244639&amp;sspn=0.225077,0.617294&amp;ie=UTF8&amp;hq=Roadrunners+Club+ausgehen+%26+genie%C3%9Fen:+Diskotheken+und+Clubs,&amp;hnear=Saarbr%C3%BCcker+Stra%C3%9Fe,+Berlin&amp;ll=52.530517,13.413577&amp;spn=0.004569,0.00912&amp;z=16&amp;iwloc=A">Größere Kartenansicht</a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2011/01/21/geekcon-am-8-februar-2011/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Changes in our OpenSocial app release process</title>
		<link>http://developer.vz.net/2010/12/14/changes-in-our-opensocial-app-release-process/</link>
		<comments>http://developer.vz.net/2010/12/14/changes-in-our-opensocial-app-release-process/#comments</comments>
		<pubDate>Tue, 14 Dec 2010 12:36:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[OpenSocial]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2601</guid>
		<description><![CDATA[On december 14th, we released several smaller changes in the release process for apps in our developer sandbox: Revisions that have been requested for testing can be un-qued (&#8220;cancel testing&#8221;), so developers can edit the code again without being reviewed &#8230; <a href="http://developer.vz.net/2010/12/14/changes-in-our-opensocial-app-release-process/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>On december 14th, we released several smaller changes in the release process for apps in our developer sandbox:</p>
<ul>
<li>Revisions that have been requested for testing can be un-qued (&#8220;cancel testing&#8221;), so developers can edit the code again without being reviewed immediately or influencing the currently productive revision.</li>
</ul>
<ul>
<li>After a revision&#8217;s approval, developers gain the possibility to put revisions online by themselves. So switching between approved revisions works using &#8220;set online&#8221;. Revisions marked as buggy by the developer flip back to development mode, if they weren&#8217;t productive already.</li>
</ul>
<ul>
<li>If an administrator sets a gadget offline due to bugs or security issues, you can set the gadget online again by uploading a new revision and passing through the review process or contacting our developer support team.</li>
</ul>

<a href='http://developer.vz.net/2010/12/14/changes-in-our-opensocial-app-release-process/sandbox_1-2/' title='Request for testing'><img width="150" height="150" src="http://developer.vz.net/wp-content/uploads/2010/12/sandbox_11-150x150.png" class="attachment-thumbnail" alt="Request for testing" title="Request for testing" /></a>
<a href='http://developer.vz.net/2010/12/14/changes-in-our-opensocial-app-release-process/sandbox_2-2/' title='Approved Revisions'><img width="150" height="150" src="http://developer.vz.net/wp-content/uploads/2010/12/sandbox_21-150x150.png" class="attachment-thumbnail" alt="Approved Revisions" title="Approved Revisions" /></a>
<a href='http://developer.vz.net/2010/12/14/changes-in-our-opensocial-app-release-process/sandbox_3-2/' title='Offline Gadget'><img width="150" height="150" src="http://developer.vz.net/wp-content/uploads/2010/12/sandbox_31-150x150.png" class="attachment-thumbnail" alt="Offline Gadget" title="Offline Gadget" /></a>

]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/12/14/changes-in-our-opensocial-app-release-process/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>VZnet supports OExchange and OpenGraph Specification</title>
		<link>http://developer.vz.net/2010/11/26/vznet-supports-oexchange-and-opengraph-specification/</link>
		<comments>http://developer.vz.net/2010/11/26/vznet-supports-oexchange-and-opengraph-specification/#comments</comments>
		<pubDate>Fri, 26 Nov 2010 16:34:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[OExhange]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2531</guid>
		<description><![CDATA[On October 11th, we launched together with a complete overhaul of our sharing functionality (Zeigen) support for the OExchange specification. OExchange makes it possible to share any URL-based content with any service on the web. It defines: A common way &#8230; <a href="http://developer.vz.net/2010/11/26/vznet-supports-oexchange-and-opengraph-specification/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>On October 11th, we launched together with a complete overhaul of our sharing functionality (Zeigen) support for the <a href="http://www.oexchange.org/" target="_blank">OExchange</a> specification. OExchange makes it possible to share any URL-based content with any service on the web. It defines:</p>
<dl>
<dd>
<ul>
<li> A common way for services to receive content, removing any and all service-specific integration requirements</li>
<li> A discovery feature so services can publish themselves and  their endpoints, making it possible to integrate with services you  didn&#8217;t even know about at development time</li>
<li> A decentralized, user-centric model for saving preferred services, making sharing more personal</li>
</ul>
</dd>
</dl>
<p>Shared pages can be posted by the user into his feed or sent as a private message. Since yesterday you can now also not only add a title and description for the page you are sharing, but also a thumbnail which will be integrated into your feed post or message. This is possible by either adding this meta information as a OExchange query parameter to the VZ sharing endpoint or by implementing <a href="http://opengraphprotocol.org/" target="_blank">OpenGraph</a> Meta Tags into your site.</p>
<p><a rel="attachment wp-att-2586" href="http://developer.studivz.net/2010/11/26/vznet-supports-oexchange-and-opengraph-specification/bildschirmfoto-2010-11-19-um-12-06-55/"><img class="alignnone size-full wp-image-2586" src="http://developer.studivz.net/wp-content/uploads/2010/11/Bildschirmfoto-2010-11-19-um-12.06.55.png" alt="" width="356" height="385" /></a><a rel="attachment wp-att-2585" href="http://developer.studivz.net/2010/11/26/vznet-supports-oexchange-and-opengraph-specification/bildschirmfoto-2010-11-19-um-12-07-08/"><img class="alignnone size-full wp-image-2585" src="http://developer.studivz.net/wp-content/uploads/2010/11/Bildschirmfoto-2010-11-19-um-12.07.08.png" alt="" width="297" height="391" /></a></p>
<p>You can find more detailed information in our developer wiki at <a href="http://developer.studivz.net/wiki/index.php/Bookmarking" target="_blank">http://developer.studivz.net/wiki/index.php/Bookmarking</a>. Or you can have a look at <a title="http://www.oexchange.org/" rel="nofollow" href="http://www.oexchange.org/">http://www.oexchange.org/</a> where you can find the complete specification as well as some tools that help you with testing OExchange endpoints as well as your implementation.</p>
<p>To make the implementation as easy as possible we are also now providing a simple and lightweight JavaScript library, which you can include into your site. You will finde more information about this library and further code examples at <a href="http://developer.studivz.net/wiki/index.php/JS-Library" target="_blank">http://developer.studivz.net/wiki/index.php/JS-Library</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/11/26/vznet-supports-oexchange-and-opengraph-specification/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>GEEKcon am 7. Dezember</title>
		<link>http://developer.vz.net/2010/11/23/geekcon-am-7-dezember/</link>
		<comments>http://developer.vz.net/2010/11/23/geekcon-am-7-dezember/#comments</comments>
		<pubDate>Tue, 23 Nov 2010 13:07:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[GEEKcon]]></category>
		<category><![CDATA[GeekNight]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2593</guid>
		<description><![CDATA[Die VZ-GeekNight erfindet sich neu und wird zur GEEKcon. Wir von VZnet wollen im regelmäßigem Abstand gemeinsam mit Gleichgesinnten neue Technologien, aktuelle Probleme und Lösungsansätze in lockerer Atmosphäre diskutieren. Die erste GEEKcon findet am 7. Dezember 2010 im Roadrunner&#8217;s Club &#8230; <a href="http://developer.vz.net/2010/11/23/geekcon-am-7-dezember/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Die VZ-GeekNight erfindet sich neu und wird zur GEEKcon.</strong></p>
<p>Wir von VZnet wollen im regelmäßigem Abstand gemeinsam mit  Gleichgesinnten neue Technologien, aktuelle Probleme und Lösungsansätze  in lockerer Atmosphäre diskutieren.<strong> </strong></p>
<p>Die erste GEEKcon findet am</p>
<p><strong> 7. Dezember 2010</strong> im <a href="http://www.roadrunners-paradise.de/" target="_blank">Roadrunner&#8217;s Club</a> (<a href="http://maps.google.de/maps/place?cid=3012540198658535383&amp;q=roadrunners+club+berlin&amp;hl=de&amp;gl=de" target="_blank">Google Places Link</a>), Berlin statt.</p>
<p>Ab 19:00 Uhr laden wir alle Interessierten ein, bei Getränken, Talk und Diskussion den Abend mit uns zu verbringen.</p>
<p><strong>Agenda</strong></p>
<ul>
<li>19.00 Uhr: Eröffnung, Jan Lohmer und Sebastian Jerie</li>
<li>19.15 Uhr: VZ-ID, präsentiert von Bastian Hofman und Axel Tölke (VZnet Netzwerke)</li>
<li>20.15 Uhr: The communication revolution, präsentiert von Dr. Johannes Mainusch (XING AG)</li>
<li>21.15 Uhr: Fraud Detection bei VZ, präsentiert von Dr. Falk-Florian Henrich (VZnet Netzwerke)</li>
</ul>
<p>Mehr Informationen erfahrt ihr auf dem GEEKcon Profil ( <a href="http://www.studivz.net/geekcon" target="_blank">studiVZ</a> / <a href="http://www.meinvz.net/geekcon" target="_blank">meinVZ</a> ).</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/11/23/geekcon-am-7-dezember/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenSocial Apps entwickeln mit ASP.NET (Autor: Dariusz Parys, Microsoft Deutschland GmbH)</title>
		<link>http://developer.vz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/</link>
		<comments>http://developer.vz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/#comments</comments>
		<pubDate>Fri, 19 Nov 2010 11:01:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Apps]]></category>
		<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2537</guid>
		<description><![CDATA[Soziale Netzwerke sind beliebter denn je. Ob Facebook, MySpace oder StudiVZ, jedes dieser Netzwerke hat eine enorme Benutzerzahl, gerade deswegen sind diese Plattformen auch für Entwickler interessant geworden. Eine funktional interessante Anwendung findet oft schnell mehrere Tausend Benutzer und so &#8230; <a href="http://developer.vz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><!-- P { margin-bottom: 0.21cm; }A:link {  } --><a rel="attachment wp-att-2542" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/farmville/"><img class="size-medium wp-image-2542 alignleft" src="http://developer.studivz.net/wp-content/uploads/2010/11/farmville-300x232.png" alt="" width="300" height="232" /></a>Soziale Netzwerke sind beliebter denn je. Ob <a href="http://www.facebook.com/">Facebook</a>, <a href="http://www.myspace.com/">MySpace</a> oder <a href="http://www.studivz.net/">StudiVZ</a>, jedes dieser Netzwerke hat eine enorme Benutzerzahl, gerade deswegen sind diese Plattformen auch für Entwickler interessant geworden. Eine funktional interessante Anwendung findet oft schnell mehrere Tausend Benutzer und so manche Softwareschmiede ist zu Ruhm und Reichtum gekommen (z.B. Zynga mit <a href="http://www.farmville.com/">Farmville</a> ).</p>
<p>Egal was die persönlichen Beweggründe sind Anwendungen für Soziale Netzwerke zu schreiben, es gibt für all diese Netzwerke eine Hürde: Die API der Plattform.</p>
<p>StudiVZ ist hier den Weg der Standardisierung gegangen. StudiVZ setzt bei der Plattform API ganz auf die <a href="http://www.opensocial.org/">OpenSocial API</a> mit einigen speziellen VZ Erweiterungen. Für Entwickler hat die OpenSocial API den Vorteil das die Apps im Prinzip einfacher auf andere Plattformen, die ebenfalls die OpenSocial API implementieren, portiert werden können.</p>
<h2>Anwendungen für StudiVZ Entwickeln</h2>
<p><a></a>Gadgets spielen eine zentrale Rolle in der Anwendungsentwicklung für StudiVZ. Gadgets sind XML Dokumente die als Manifest für die Anwendungen fungieren. Im XML definiert man die API die verwendet wird, die Features die von der Plattform benötigt werden und die Views die verwendet werden. Die Inhalte sind ebenfalls in diesem XML definiert und bestehen in der Regel aus HTML, CSS und JavaScript. Durch die Definition der Inhalte für einen View lassen sich unterschiedliche Darstellungen realisieren. Zum Beispiel kann ein Gadget sich auf der Profil Seite anders darstellen als auf der Gruppenseite und auch so komplett andere Funktionalität mitbringen.</p>
<h2>Ein praktisches Beispiel</h2>
<p>Im folgenden werde ich eine Web Anwendung schreiben und diese mittels eines Gadgets in die StudiVZ Plattform integrieren. Als Tool verwenden wir <a href="http://www.asp.net/webmatrix">WebMatrix</a>, eine kostenlose komplette Entwicklungsumgebung mit Editor, Webserver und Datenbank. Das ganze lässt sich elegant über den <a href="http://go.microsoft.com/fwlink/?LinkId=195938">Web Plattform Installer</a> auf dem Entwickler Rechner installieren und man kann loslegen.</p>
<p>Link: <a href="http://go.microsoft.com/fwlink/?LinkId=195938">Installation von WebMatrix durch den Web Platform Installer</a></p>
<p>Neben PHP unterstützt WebMatrix ASP.NET Web Pages welche ich zur Erstellung der Seite wähle. Die Idee für das Szenario ist fiktiv und einfach, zeigt aber grundsätzlich alle wichtigen Konzepte.</p>
<p>Die Anwendung soll eine Petitionsliste für die Erhaltung des Internets darstellen. Die letzten 5 Unterschriften werden angezeigt und man kann sich direkt in die Liste eintragen. Wenn man sich Einträgt wird automatisch an die StudiVZ Pinnwand eine Nachricht erstellt mit dem Wortlaut “{name} hat sich in die Petition zum Erhalt des Internets unterschrieben!”</p>
<h2>Die Schritte zur StudiVZ Petitions App</h2>
<p>Die folgenden Schritte sind Notwendig um die Anwendung zu realisieren:</p>
<ol>
<li>Beantragung eines Developer Accounts bei 	StudiVZ</li>
<li>Erstellen der Petitionslisten Web 	Anwendung</li>
<li>Publizieren der Anwendung bei einem 	Hoster</li>
<li>Erstellen des Gadgets</li>
<li>Hochladen des Gadgets und Testen</li>
</ol>
<h2>Beantragung eines Developer Accounts bei StudiVZ</h2>
<p>Um einen Entwickleraccount zu beantragen muss man natürlich bei StudiVZ registriert sein. Genauer gesagt langt es wenn man in einem der VZ Netzwerke registriert ist. Ich habe mich bei MeinVZ.net registriert und dort dann auf der Seite <a href="http://www.meinvz.net/developer">http://www.meinvz.net/developer</a> einen Antrag gestellt.</p>
<p><a rel="attachment wp-att-2555" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/studivz-developer-antrag/"><img class="alignnone size-medium wp-image-2555" src="http://developer.studivz.net/wp-content/uploads/2010/11/studivz-developer-antrag-300x137.png" alt="" width="300" height="137" /></a></p>
<p>Wer sich jetzt frägt wer Zsuirad ist der mag doch einfach das Wort Rückwärts lesen. Eigentlich hätte ich keinen Alter Ego Account anlegen müssen, die Developer Sandbox bietet bereits eine Reihe an Accounts die man zum Testen der App benutzen kann. Praktisch. Der Link führt einen zu einem weiteren Fragebogen, ausfüllen und warten bis man eine Bestätigung bekommt (Dieser Schritt kann auch mal 1 oder 2 Tage dauern).</p>
<h2>Erstellen der Petitions Anwendung</h2>
<p>Die Petitions Anwendung erstellen wir in WebMatrix. Dazu wähle ich aus den Projekt-Templates entsprechend das Empty Site Projekt und lege eine neue Datei mit dem Namen Petition.cshtml an.</p>
<p><a rel="attachment wp-att-2558" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/webmatrix-start-screen/"><img class="alignnone size-full wp-image-2558" src="http://developer.studivz.net/wp-content/uploads/2010/11/webmatrix-start-screen.png" alt="" width="692" height="504" /></a></p>
<p><a rel="attachment wp-att-2547" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/webmatrix-anwendung-erstellen/"><img class="alignnone size-full wp-image-2547" src="http://developer.studivz.net/wp-content/uploads/2010/11/webmatrix-anwendung-erstellen.png" alt="" width="691" height="503" /></a></p>
<p><a rel="attachment wp-att-2549" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/webmatrix-editor-workspace/"><img class="alignnone size-full wp-image-2549" src="http://developer.studivz.net/wp-content/uploads/2010/11/webmatrix-editor-workspace.png" alt="" width="691" height="503" /></a></p>
<p>Danach wechsel ich in den Database Workspace und lege eine neue Datenbank an und erstelle dort die Tabelle Signed. Die Tabelle enthält eine automatisch generierte Id, den Namen und das Datum der Signatur.</p>
<p><a rel="attachment wp-att-2548" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/webmatrix-create-database/"><img class="alignnone size-full wp-image-2548" src="http://developer.studivz.net/wp-content/uploads/2010/11/webmatrix-create-database.png" alt="" width="691" height="503" /></a></p>
<p><a rel="attachment wp-att-2556" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/webmatrix-database-schema-editor/"><img class="alignnone size-full wp-image-2556" src="http://developer.studivz.net/wp-content/uploads/2010/11/webmatrix-database-schema-editor.png" alt="" width="691" height="503" /></a></p>
<p>Der Grundstein ist gelegt. Nun kann die Anwendung mit Leben sprich Code gefüllt werden.</p>
<pre style='color:#000000;background:#ffffff'>   <span style='color:#008c00'>1</span><span style='color:#800080'>:</span> @<span style='color:#800080'>{</span>
   <span style='color:#008c00'>2</span><span style='color:#800080'>:</span>     <span style='color:#800000;font-weight:bold'>var</span> db <span style='color:#808030'>=</span> Database<span style='color:#808030'>.</span>Open<span style='color:#808030'>(</span><span style='color:#0000e6'>"Petition"</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>3</span><span style='color:#800080'>:</span>     
   <span style='color:#008c00'>4</span><span style='color:#800080'>:</span>     <span style='color:#800000;font-weight:bold'>if</span><span style='color:#808030'>(</span> IsPost <span style='color:#808030'>)</span>
   <span style='color:#008c00'>5</span><span style='color:#800080'>:</span>     <span style='color:#800080'>{</span>
   <span style='color:#008c00'>6</span><span style='color:#800080'>:</span>         <span style='color:#800000;font-weight:bold'>var</span> errors <span style='color:#808030'>=</span> <span style='color:#0f4d75'>false</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>7</span><span style='color:#800080'>:</span>         <span style='color:#800000;font-weight:bold'>var</span> signature <span style='color:#808030'>=</span> Request<span style='color:#808030'>[</span><span style='color:#0000e6'>"name"</span><span style='color:#808030'>]</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>8</span><span style='color:#800080'>:</span>  
   <span style='color:#008c00'>9</span><span style='color:#800080'>:</span>         <span style='color:#800000;font-weight:bold'>if</span><span style='color:#808030'>(</span> signature<span style='color:#808030'>.</span>IsEmpty<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#808030'>)</span>
  <span style='color:#008c00'>10</span><span style='color:#800080'>:</span>         <span style='color:#800080'>{</span>
  <span style='color:#008c00'>11</span><span style='color:#800080'>:</span>             errors <span style='color:#808030'>=</span> <span style='color:#0f4d75'>true</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>12</span><span style='color:#800080'>:</span>             @<span style='color:#800080'>:</span>Willst Du unterschreiben<span style='color:#808030'>,</span> dann trage Deinen Namen ein<span style='color:#808030'>!</span><span style='color:#808030'>&lt;</span>br<span style='color:#808030'>/</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>13</span><span style='color:#800080'>:</span>         <span style='color:#800080'>}</span>
  <span style='color:#008c00'>14</span><span style='color:#800080'>:</span>         
  <span style='color:#008c00'>15</span><span style='color:#800080'>:</span>         <span style='color:#800000;font-weight:bold'>if</span><span style='color:#808030'>(</span> errors <span style='color:#808030'>==</span> <span style='color:#0f4d75'>false</span> <span style='color:#808030'>)</span>
  <span style='color:#008c00'>16</span><span style='color:#800080'>:</span>         <span style='color:#800080'>{</span>
  <span style='color:#008c00'>17</span><span style='color:#800080'>:</span>             <span style='color:#800000;font-weight:bold'>var</span> insert <span style='color:#808030'>=</span> <span style='color:#0000e6'>"INSERT INTO Signed (Name, DateAndTime)</span><span style='color:#ffffff;background:#dd0000;font-weight:bold;font-style:italic'> </span><span style='color:#0000e6'></span>
<span style='color:#0000e6'>&#xa0;&#xa0;18:                             VALUES (@0, @1)"</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>19</span><span style='color:#800080'>:</span>             db<span style='color:#808030'>.</span>Execute<span style='color:#808030'>(</span> insert<span style='color:#808030'>,</span> signature<span style='color:#808030'>,</span> DateTime<span style='color:#808030'>.</span>Now<span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>20</span><span style='color:#800080'>:</span>         <span style='color:#800080'>}</span>
  <span style='color:#008c00'>21</span><span style='color:#800080'>:</span>     <span style='color:#800080'>}</span>
  <span style='color:#008c00'>22</span><span style='color:#800080'>:</span>     
  <span style='color:#008c00'>23</span><span style='color:#800080'>:</span>     <span style='color:#800000;font-weight:bold'>var</span> people <span style='color:#808030'>=</span> db<span style='color:#808030'>.</span>Query<span style='color:#808030'>(</span> <span style='color:#0000e6'>"SELECT TOP(5) * FROM Signed</span><span style='color:#ffffff;background:#dd0000;font-weight:bold;font-style:italic'> </span><span style='color:#0000e6'></span>
<span style='color:#0000e6'>&#xa0;&#xa0;24:                                 ORDER BY DateAndTime DESC"</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>25</span><span style='color:#800080'>:</span>     <span style='color:#800000;font-weight:bold'>var</span> totalPeopleSigned <span style='color:#808030'>=</span> db<span style='color:#808030'>.</span>QueryValue<span style='color:#808030'>(</span> <span style='color:#0000e6'>"SELECT COUNT(*) FROM Signed"</span> <span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>26</span><span style='color:#800080'>:</span> <span style='color:#800080'>}</span>
  <span style='color:#008c00'>27</span><span style='color:#800080'>:</span>  
  <span style='color:#008c00'>28</span><span style='color:#800080'>:</span>  
  <span style='color:#008c00'>29</span><span style='color:#800080'>:</span> <span style='color:#808030'>&lt;</span>!DOCTYPE html<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>30</span><span style='color:#800080'>:</span>  
  <span style='color:#008c00'>31</span><span style='color:#800080'>:</span> <span style='color:#808030'>&lt;</span>html lang<span style='color:#808030'>=</span><span style='color:#0000e6'>"en"</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>32</span><span style='color:#800080'>:</span>     <span style='color:#808030'>&lt;</span>head<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>33</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>meta charset<span style='color:#808030'>=</span><span style='color:#0000e6'>"utf-8"</span><span style='color:#0000e6'> </span><span style='color:#800000'>/</span><span style='color:#0000e6'>&gt;</span>
<span style='color:#0000e6'>&#xa0;&#xa0;34:         &lt;title&gt;Petition&lt;</span><span style='color:#800000'>/</span>title<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>35</span><span style='color:#800080'>:</span>     <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>head<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>36</span><span style='color:#800080'>:</span>     <span style='color:#808030'>&lt;</span>body<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>37</span><span style='color:#800080'>:</span>         
  <span style='color:#008c00'>38</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>h1<span style='color:#808030'>&gt;</span>Petition zur Erhaltung des Internets<span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>h1<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>39</span><span style='color:#800080'>:</span>         
  <span style='color:#008c00'>40</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>h2<span style='color:#808030'>&gt;</span>Zuletzt unterschrieben von<span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>h2<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>41</span><span style='color:#800080'>:</span>         
  <span style='color:#008c00'>42</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>ul<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>43</span><span style='color:#800080'>:</span>         @foreach<span style='color:#808030'>(</span> <span style='color:#800000;font-weight:bold'>var</span> person <span style='color:#800000;font-weight:bold'>in</span> people <span style='color:#808030'>)</span> <span style='color:#800080'>{</span>
  <span style='color:#008c00'>44</span><span style='color:#800080'>:</span>             <span style='color:#808030'>&lt;</span>li<span style='color:#808030'>&gt;</span>@person<span style='color:#808030'>.</span>Name am @person<span style='color:#808030'>.</span>DateAndTime<span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>li<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>45</span><span style='color:#800080'>:</span>         <span style='color:#800080'>}</span>
  <span style='color:#008c00'>46</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>ul<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>47</span><span style='color:#800080'>:</span>         
  <span style='color:#008c00'>48</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>h2<span style='color:#808030'>&gt;</span>@totalPeopleSigned Menschen haben diese Petition unterschrieben<span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>h2<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>49</span><span style='color:#800080'>:</span>         
  <span style='color:#008c00'>50</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>div id<span style='color:#808030'>=</span><span style='color:#0000e6'>'petitionform'</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>51</span><span style='color:#800080'>:</span>             <span style='color:#808030'>&lt;</span>form method<span style='color:#808030'>=</span><span style='color:#0000e6'>"POST"</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>52</span><span style='color:#800080'>:</span>                 <span style='color:#808030'>&lt;</span>fieldset<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>53</span><span style='color:#800080'>:</span>                     <span style='color:#808030'>&lt;</span>h4<span style='color:#808030'>&gt;</span>Unterschreibe diese Petition<span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>h4<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>54</span><span style='color:#800080'>:</span>                     <span style='color:#808030'>&lt;</span>label <span style='color:#800000;font-weight:bold'>for</span><span style='color:#808030'>=</span><span style='color:#0000e6'>"Name"</span><span style='color:#808030'>&gt;</span>Name<span style='color:#800080'>:</span> <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>label<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>55</span><span style='color:#800080'>:</span>                     <span style='color:#808030'>&lt;</span>input type<span style='color:#808030'>=</span><span style='color:#0000e6'>"text"</span> name<span style='color:#808030'>=</span><span style='color:#0000e6'>"Name"</span><span style='color:#0000e6'> </span><span style='color:#800000'>/</span><span style='color:#0000e6'>&gt;</span>
<span style='color:#0000e6'>&#xa0;&#xa0;56:                     &lt;input type="submit" value="Signed"</span><span style='color:#800000'>/</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>57</span><span style='color:#800080'>:</span>                 <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>fieldset<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>58</span><span style='color:#800080'>:</span>             <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>form<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>59</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>div<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>60</span><span style='color:#800080'>:</span>     <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>body<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>61</span><span style='color:#800080'>:</span> <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>html<span style='color:#808030'>&gt;</span>
</pre>
<p>Das @ Zeichen deklariert einen Razor Code Block. Razor ist die Syntax der View Engine die für ASP.NET Web Pages benötigt wird. Die Zeilen 1 – 26 greifen auf die Datenbank zu und prüfen ob es sich um einen Postback der Seite handelt. Falls ja, wird ein neuer Datensatz in die Datenbank eingetragen.</p>
<p>In der Zeile 43 – 46 sieht man die dynamische Erstellung der Personen die bereits die Petition unterschrieben haben. Zum Schluß folgt noch die Form die den Postback auslösen kann.</p>
<h2>Publizieren der Web Anwendung</h2>
<p>Damit die Web Anwendung aus einem StudiVZ Gadget genutzt werden kann, muss ich diese erst noch bei einem Hoster veröffentlichen. WebMatrix bietet hierfür eine Publish Schaltfläche, die automatisch auch noch Provider anbietet die ASP.NET Web Pages hosten können.</p>
<p>Nach dem Eintragen meiner Publishing Credentials publiziere ich die Anwendung mittels Web Deploy auf den Server.</p>
<p><a rel="attachment wp-att-2550" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/webmatrix-publish-petition-app/"><img class="alignnone size-full wp-image-2550" src="http://developer.studivz.net/wp-content/uploads/2010/11/webmatrix-publish-petition-app.png" alt="" width="690" height="524" /></a></p>
<p><a rel="attachment wp-att-2551" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/webmatrix-publish-preview/"><img class="alignnone size-full wp-image-2551" src="http://developer.studivz.net/wp-content/uploads/2010/11/webmatrix-publish-preview.png" alt="" width="690" height="524" /></a></p>
<p><a rel="attachment wp-att-2557" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/webmatrix-publish-publishing/"><img class="alignnone size-full wp-image-2557" src="http://developer.studivz.net/wp-content/uploads/2010/11/webmatrix-publish-publishing.png" alt="" width="600" height="500" /></a></p>
<p>Die App ist nun publiziert und unter der URL <a href="http://20313wdbv4.adhostbeta.com/studivz/petition.cshtml">http://20313wdbv4.adhostbeta.com/studivz/petition.cshtml</a> erreichbar.</p>
<h2>Erstellen des Gadgets</h2>
<p>Die Anwendung muss nun in ein Gadget gepackt werden. Hierfür gibt es entsprechende XML Schema Definitionen die auf dem <a href="http://developer.studivz.net/wiki">Developer Wiki</a> von StudiVZ zu finden sind. Das Gadget soll im Canvas View einfach die Anwendung kapseln und darstellen. Das ist leicht bewerkstelligt und sieht als Gadget folgendermaßen aus:</p>
<pre style='color:#000000;background:#ffffff'>    1: <span style='color:#ffffff;background:#dd0000;font-weight:bold;font-style:italic'>&lt;</span>?xml version="1.0" encoding="UTF-8" ?&gt;
   2: <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>Module</span><span style='color:#a65700'>&gt;</span>
   3:     <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>ModulePrefs</span> <span style='color:#274796'>title</span><span style='color:#808030'>=</span><span style='color:#0000e6'>"</span><span style='color:#0000e6'>Petition Gadget</span><span style='color:#0000e6'>"</span><span style='color:#a65700'>&gt;</span>
   4:         <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>Require</span> <span style='color:#274796'>feature</span><span style='color:#808030'>=</span><span style='color:#0000e6'>"</span><span style='color:#0000e6'>opensocial-0.9</span><span style='color:#0000e6'>"</span> <span style='color:#a65700'>/&gt;</span>
   5:         <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>Require</span> <span style='color:#274796'>feature</span><span style='color:#808030'>=</span><span style='color:#0000e6'>"</span><span style='color:#0000e6'>minimessage</span><span style='color:#0000e6'>"</span><span style='color:#a65700'>/&gt;</span>
   6:         <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>Require</span> <span style='color:#274796'>feature</span><span style='color:#808030'>=</span><span style='color:#0000e6'>"</span><span style='color:#0000e6'>views</span><span style='color:#0000e6'>"</span><span style='color:#a65700'>/&gt;</span>
   7:         <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>AllowedDomain</span> <span style='color:#274796'>name</span><span style='color:#808030'>=</span><span style='color:#0000e6'>"</span><span style='color:#0000e6'>20313wdbv4.adhostbeta.com</span><span style='color:#0000e6'>"</span><span style='color:#a65700'>/&gt;</span>
   8:     <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>ModulePrefs</span><span style='color:#a65700'>&gt;</span>
   9:     <span style='color:#a65700'>&lt;</span><span style='color:#5f5035'>Content</span> <span style='color:#274796'>view</span><span style='color:#808030'>=</span><span style='color:#0000e6'>"</span><span style='color:#0000e6'>canvas</span><span style='color:#0000e6'>"</span> <span style='color:#274796'>type</span><span style='color:#808030'>=</span><span style='color:#0000e6'>"</span><span style='color:#0000e6'>url</span><span style='color:#0000e6'>"</span> <span style='color:#274796'>href</span><span style='color:#808030'>=</span><span style='color:#0000e6'>"</span><span style='color:#0000e6'>http://20313wdbv4.adhostbeta.com/studivz/petition.cshtml</span><span style='color:#0000e6'>"</span><span style='color:#a65700'>&gt;</span>
  10:     <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>Content</span><span style='color:#a65700'>&gt;</span>
  11: <span style='color:#a65700'>&lt;/</span><span style='color:#5f5035'>Module</span><span style='color:#a65700'>&gt;</span>
</pre>
<p>Doch bevor wir das Gadget testen wollen wir noch die Funktionalität erweitern. Das einbinden der externen Webseite im Canvas bringt zwar ein schnelles Resultat doch hat man hier nichts weiter als die Seite eingebunden und keinerlei Integration in die StudiVZ Plattform getätigt.</p>
<p>Den Canvas View lasse ich erstmal so. Ich erweitere das Gadget um einen Content Bereich für die Views Profile und Group. In diesem View soll sich das Gadget entsprechend in die Seite integrieren. Beachten muss man lediglich das dass Gadget mit den Maßen 390 x 400px angezeigt wird, Content darüber wird abgeschnitten. Unsere Seite eignet sich nicht direkt für die Profile und Group Views, da das generierte HTML mit der Form zusammen größer ist.</p>
<p>Auch die Integration mit der Möglichkeit an die Pinnwand zu schreiben muss in die Signierung der Petition integriert werden. Das erfordert ein “Refactoring” der eigentlichen Anwendung. Ich füge zur Anwendung zwei URL Endpunkte hinzu. Eine die die letzten Petitionen anzeigt und eine die als POST Endpunkt dient um neue Unterschriften hinzuzufügen.</p>
<h2>Security über OAuth</h2>
<p>Die Authorisierung zwischen Gadget und Web Anwendung erfolgt über OAuth, einem Standard der es erlaubt Anwendungen untereinander zu vertrauen und entsprechend Zugriffe zu gewähren. Im Gadget werde ich die Signatur Funktion von OAuth nutzen, in der Web Anwendung verzichte ich auf die Prüfung, diese sollte natürlich erfolgen damit nicht jeder x-beliebige Post einer beliebigen Seite angenommen wird. Es gibt zahlreiche OAuth Tutorials auf dem Developer Wiki, so dass diese Übung dem Leser überlassen bleibt.</p>
<p>Damit habe ich nun zwei weitere Endpunkte:</p>
<p>ListPetition.cshtml</p>
<pre style='color:#000000;background:#ffffff'>    <span style='color:#008c00'>1</span><span style='color:#800080'>:</span> @<span style='color:#800080'>{</span>
   <span style='color:#008c00'>2</span><span style='color:#800080'>:</span>     <span style='color:#800000;font-weight:bold'>var</span> db <span style='color:#808030'>=</span> Database<span style='color:#808030'>.</span>Open<span style='color:#808030'>(</span><span style='color:#0000e6'>"Petition"</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>3</span><span style='color:#800080'>:</span>     
   <span style='color:#008c00'>4</span><span style='color:#800080'>:</span>     <span style='color:#800000;font-weight:bold'>var</span> people <span style='color:#808030'>=</span> db<span style='color:#808030'>.</span>Query<span style='color:#808030'>(</span> <span style='color:#0000e6'>"SELECT TOP(5) * FROM Signed ORDER BY DateAndTime DESC"</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>5</span><span style='color:#800080'>:</span>     <span style='color:#800000;font-weight:bold'>var</span> totalPeopleSigned <span style='color:#808030'>=</span> db<span style='color:#808030'>.</span>QueryValue<span style='color:#808030'>(</span> <span style='color:#0000e6'>"SELECT COUNT(*) FROM Signed"</span> <span style='color:#808030'>)</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>6</span><span style='color:#800080'>:</span> <span style='color:#800080'>}</span>
   <span style='color:#008c00'>7</span><span style='color:#800080'>:</span>  
   <span style='color:#008c00'>8</span><span style='color:#800080'>:</span>  
   <span style='color:#008c00'>9</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>h1<span style='color:#808030'>&gt;</span>Petition zur Erhaltung des Internets<span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>h1<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>10</span><span style='color:#800080'>:</span>         
  <span style='color:#008c00'>11</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>h2<span style='color:#808030'>&gt;</span>Zuletzt unterschrieben von<span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>h2<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>12</span><span style='color:#800080'>:</span>         
  <span style='color:#008c00'>13</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>ul<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>14</span><span style='color:#800080'>:</span>         @foreach<span style='color:#808030'>(</span> <span style='color:#800000;font-weight:bold'>var</span> person <span style='color:#800000;font-weight:bold'>in</span> people <span style='color:#808030'>)</span> <span style='color:#800080'>{</span>
  <span style='color:#008c00'>15</span><span style='color:#800080'>:</span>             <span style='color:#808030'>&lt;</span>li<span style='color:#808030'>&gt;</span>@person<span style='color:#808030'>.</span>Name am @person<span style='color:#808030'>.</span>DateAndTime<span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>li<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>16</span><span style='color:#800080'>:</span>         <span style='color:#800080'>}</span>
  <span style='color:#008c00'>17</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>ul<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>18</span><span style='color:#800080'>:</span>         
  <span style='color:#008c00'>19</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>h2<span style='color:#808030'>&gt;</span>@totalPeopleSigned Menschen haben diese Petition unterschrieben<span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>h2<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>20</span><span style='color:#800080'>:</span>
</pre>
<p>und SignPetition.cshtml</p>
<pre style='color:#000000;background:#ffffff'>    <span style='color:#008c00'>1</span><span style='color:#800080'>:</span> @<span style='color:#800080'>{</span>
   <span style='color:#008c00'>2</span><span style='color:#800080'>:</span>     <span style='color:#800000;font-weight:bold'>var</span> db <span style='color:#808030'>=</span> Database<span style='color:#808030'>.</span>Open<span style='color:#808030'>(</span><span style='color:#0000e6'>"Petition"</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>3</span><span style='color:#800080'>:</span>     
   <span style='color:#008c00'>4</span><span style='color:#800080'>:</span>     <span style='color:#800000;font-weight:bold'>if</span><span style='color:#808030'>(</span> IsPost <span style='color:#808030'>)</span>
   <span style='color:#008c00'>5</span><span style='color:#800080'>:</span>     <span style='color:#800080'>{</span>
   <span style='color:#008c00'>6</span><span style='color:#800080'>:</span>         <span style='color:#800000;font-weight:bold'>var</span> errors <span style='color:#808030'>=</span> <span style='color:#0f4d75'>false</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>7</span><span style='color:#800080'>:</span>         <span style='color:#800000;font-weight:bold'>var</span> signature <span style='color:#808030'>=</span> Request<span style='color:#808030'>[</span><span style='color:#0000e6'>"name"</span><span style='color:#808030'>]</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>8</span><span style='color:#800080'>:</span>  
   <span style='color:#008c00'>9</span><span style='color:#800080'>:</span>         <span style='color:#800000;font-weight:bold'>if</span><span style='color:#808030'>(</span> signature<span style='color:#808030'>.</span>IsEmpty<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#808030'>)</span>
  <span style='color:#008c00'>10</span><span style='color:#800080'>:</span>         <span style='color:#800080'>{</span>
  <span style='color:#008c00'>11</span><span style='color:#800080'>:</span>             errors <span style='color:#808030'>=</span> <span style='color:#0f4d75'>true</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>12</span><span style='color:#800080'>:</span>             @<span style='color:#800080'>:</span>Es fehlt die Unterschrift<span style='color:#808030'>!</span><span style='color:#808030'>&lt;</span>br<span style='color:#808030'>/</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>13</span><span style='color:#800080'>:</span>         <span style='color:#800080'>}</span>
  <span style='color:#008c00'>14</span><span style='color:#800080'>:</span>         
  <span style='color:#008c00'>15</span><span style='color:#800080'>:</span>         <span style='color:#800000;font-weight:bold'>if</span><span style='color:#808030'>(</span> errors <span style='color:#808030'>==</span> <span style='color:#0f4d75'>false</span> <span style='color:#808030'>)</span>
  <span style='color:#008c00'>16</span><span style='color:#800080'>:</span>         <span style='color:#800080'>{</span>
  <span style='color:#008c00'>17</span><span style='color:#800080'>:</span>             <span style='color:#800000;font-weight:bold'>var</span> insert <span style='color:#808030'>=</span> <span style='color:#0000e6'>"INSERT INTO Signed (Name, DateAndTime) VALUES (@0, @1)"</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>18</span><span style='color:#800080'>:</span>             db<span style='color:#808030'>.</span>Execute<span style='color:#808030'>(</span> insert<span style='color:#808030'>,</span> signature<span style='color:#808030'>,</span> DateTime<span style='color:#808030'>.</span>Now<span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>19</span><span style='color:#800080'>:</span>             @<span style='color:#800080'>:</span>Danke f�r Deine Unterschrift<span style='color:#808030'>!</span><span style='color:#808030'>&lt;</span>br<span style='color:#808030'>/</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>20</span><span style='color:#800080'>:</span>         <span style='color:#800080'>}</span>
  <span style='color:#008c00'>21</span><span style='color:#800080'>:</span>     <span style='color:#800080'>}</span>
  <span style='color:#008c00'>22</span><span style='color:#800080'>:</span>     <span style='color:#800000;font-weight:bold'>else</span>
  <span style='color:#008c00'>23</span><span style='color:#800080'>:</span>     <span style='color:#800080'>{</span>
  <span style='color:#008c00'>24</span><span style='color:#800080'>:</span>         Response<span style='color:#808030'>.</span>Redirect<span style='color:#808030'>(</span><span style='color:#0000e6'>"~/Petition.cshtml"</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>25</span><span style='color:#800080'>:</span>     <span style='color:#800080'>}</span>
  <span style='color:#008c00'>26</span><span style='color:#800080'>:</span> <span style='color:#800080'>}</span>
</pre>
<p>Wie schon gesagt, im richtigen Anwendungsfall sollte letztere auf jeden Fall die OAuth Signatur prüfen.</p>
<p>Da wir nun die Endpunkte haben können wir auch das Gadget um den Content Bereich für Profile und Group erweitern.</p>
<pre style='color:#000000;background:#ffffff'>    <span style='color:#008c00'>1</span><span style='color:#800080'>:</span> <span style='color:#808030'>&lt;</span><span style='color:#800080'>?</span>xml version<span style='color:#808030'>=</span><span style='color:#0000e6'>"1.0"</span> encoding<span style='color:#808030'>=</span><span style='color:#0000e6'>"UTF-8"</span> <span style='color:#800080'>?</span><span style='color:#808030'>&gt;</span>
   <span style='color:#008c00'>2</span><span style='color:#800080'>:</span> <span style='color:#808030'>&lt;</span>Module<span style='color:#808030'>&gt;</span>
   <span style='color:#008c00'>3</span><span style='color:#800080'>:</span>     <span style='color:#808030'>&lt;</span>ModulePrefs title<span style='color:#808030'>=</span><span style='color:#0000e6'>"Petition Gadget"</span><span style='color:#808030'>&gt;</span>
   <span style='color:#008c00'>4</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>Require feature<span style='color:#808030'>=</span><span style='color:#0000e6'>"opensocial-0.9"</span><span style='color:#0000e6'> </span><span style='color:#800000'>/</span><span style='color:#0000e6'>&gt;</span>
<span style='color:#0000e6'>&#xa0;&#xa0;&#xa0;5:         &lt;Require feature="minimessage"</span><span style='color:#800000'>/</span><span style='color:#808030'>&gt;</span>
   <span style='color:#008c00'>6</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>Require feature<span style='color:#808030'>=</span><span style='color:#0000e6'>"views"</span><span style='color:#800000'>/</span><span style='color:#0000e6'>&gt;</span>
<span style='color:#0000e6'>&#xa0;&#xa0;&#xa0;7:         &lt;AllowedDomain name="20313wdbv4</span><span style='color:#808030'>.</span><span style='color:#0000e6'>adhostbeta</span><span style='color:#808030'>.</span><span style='color:#0000e6'>com"</span><span style='color:#800000'>/</span><span style='color:#808030'>&gt;</span>
   <span style='color:#008c00'>8</span><span style='color:#800080'>:</span>     <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>ModulePrefs<span style='color:#808030'>&gt;</span>
   <span style='color:#008c00'>9</span><span style='color:#800080'>:</span>     <span style='color:#808030'>&lt;</span>Content view<span style='color:#808030'>=</span><span style='color:#0000e6'>"profile,group"</span> type<span style='color:#808030'>=</span><span style='color:#0000e6'>"html"</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>10</span><span style='color:#800080'>:</span>         <span style='color:#808030'>&lt;</span>!<span style='color:#808030'>[</span>CDATA<span style='color:#808030'>[</span>
  <span style='color:#008c00'>11</span><span style='color:#800080'>:</span>  
  <span style='color:#008c00'>12</span><span style='color:#800080'>:</span>             <span style='color:#808030'>&lt;</span>script type<span style='color:#808030'>=</span><span style='color:#0000e6'>"text/javascript"</span><span style='color:#808030'>&gt;</span>
   <span style='color:#008c00'>1</span><span style='color:#800080'>:</span>  
   <span style='color:#008c00'>2</span><span style='color:#800080'>:</span>             
   <span style='color:#008c00'>3</span><span style='color:#800080'>:</span>                 gadgets<span style='color:#808030'>.</span>util<span style='color:#808030'>.</span>registerOnLoadHandler<span style='color:#808030'>(</span> initializeApplication <span style='color:#808030'>)</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>4</span><span style='color:#800080'>:</span>     
   <span style='color:#008c00'>5</span><span style='color:#800080'>:</span>                 <span style='color:#800000;font-weight:bold'>function</span> initializeApplication<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#800080'>{</span>
   <span style='color:#008c00'>6</span><span style='color:#800080'>:</span>                     showAppVersionMessage<span style='color:#808030'>(</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>7</span><span style='color:#800080'>:</span>                     retrievePeopleSignedPetition<span style='color:#808030'>(</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
   <span style='color:#008c00'>8</span><span style='color:#800080'>:</span>                 <span style='color:#800080'>}</span>
   <span style='color:#008c00'>9</span><span style='color:#800080'>:</span>                 
  <span style='color:#008c00'>10</span><span style='color:#800080'>:</span>                 <span style='color:#800000;font-weight:bold'>function</span> showAppVersionMessage<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#800080'>{</span>
  <span style='color:#008c00'>11</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> msg <span style='color:#808030'>=</span> <span style='color:#800000;font-weight:bold'>new</span> gadgets<span style='color:#808030'>.</span>MiniMessage<span style='color:#808030'>(</span> <span style='color:#0000e6'>'__MODULE_ID__'</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>12</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> statusMsg <span style='color:#808030'>=</span> msg<span style='color:#808030'>.</span>createDismissibleMessage<span style='color:#808030'>(</span><span style='color:#0000e6'>"Petition Demo</span><span style='color:#ffffff;background:#dd0000;font-weight:bold;font-style:italic'> </span><span style='color:#0000e6'></span>
<span style='color:#0000e6'>&#xa0;&#xa0;13:                                                             Version 1.2"</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>14</span><span style='color:#800080'>:</span>                     statusMsg<span style='color:#808030'>.</span>style<span style='color:#808030'>.</span>backgroundColor <span style='color:#808030'>=</span> <span style='color:#0000e6'>"grey"</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>15</span><span style='color:#800080'>:</span>                     statusMsg<span style='color:#808030'>.</span>style<span style='color:#808030'>.</span>color <span style='color:#808030'>=</span> <span style='color:#0000e6'>"white"</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>16</span><span style='color:#800080'>:</span>                 <span style='color:#800080'>}</span>
  <span style='color:#008c00'>17</span><span style='color:#800080'>:</span>                 
  <span style='color:#008c00'>18</span><span style='color:#800080'>:</span>                 <span style='color:#800000;font-weight:bold'>function</span> retrievePeopleSignedPetition<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#800080'>{</span>
  <span style='color:#008c00'>19</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> url <span style='color:#808030'>=</span> 
  <span style='color:#008c00'>20</span><span style='color:#800080'>:</span> <span style='color:#0000e6'>"http://20313wdbv4.adhostbeta.com/studivz/listpetition.cshtml"</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>21</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> params <span style='color:#808030'>=</span> <span style='color:#800080'>{</span><span style='color:#800080'>}</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>22</span><span style='color:#800080'>:</span>                     params<span style='color:#808030'>[</span> gadgets<span style='color:#808030'>.</span>io<span style='color:#808030'>.</span>RequestParameters<span style='color:#808030'>.</span>AUTHORIZATION <span style='color:#808030'>]</span> <span style='color:#808030'>=</span> 
  <span style='color:#008c00'>23</span><span style='color:#800080'>:</span> gadgets<span style='color:#808030'>.</span>io<span style='color:#808030'>.</span>AuthorizationType<span style='color:#808030'>.</span>SIGNED<span style='color:#800080'>;</span>
  <span style='color:#008c00'>24</span><span style='color:#800080'>:</span>                     gadgets<span style='color:#808030'>.</span>io<span style='color:#808030'>.</span>makeRequest<span style='color:#808030'>(</span> url<span style='color:#808030'>,</span> 
  <span style='color:#008c00'>25</span><span style='color:#800080'>:</span>                                 onRetrievePeopleSignedPetition<span style='color:#808030'>,</span> params <span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>26</span><span style='color:#800080'>:</span>                 <span style='color:#800080'>}</span>
  <span style='color:#008c00'>27</span><span style='color:#800080'>:</span>                 
  <span style='color:#008c00'>28</span><span style='color:#800080'>:</span>                 <span style='color:#800000;font-weight:bold'>function</span> onRetrievePeopleSignedPetition<span style='color:#808030'>(</span> response <span style='color:#808030'>)</span> <span style='color:#800080'>{</span>
  <span style='color:#008c00'>29</span><span style='color:#800080'>:</span>                     document<span style='color:#808030'>.</span>getElementById<span style='color:#808030'>(</span><span style='color:#0000e6'>'peopleSigned'</span><span style='color:#808030'>)</span><span style='color:#808030'>.</span>innerHTML <span style='color:#808030'>=</span> 
  <span style='color:#008c00'>30</span><span style='color:#800080'>:</span>                                                                 response<span style='color:#808030'>.</span>data<span style='color:#800080'>;</span>
  <span style='color:#008c00'>31</span><span style='color:#800080'>:</span>                 <span style='color:#800080'>}</span>
  <span style='color:#008c00'>32</span><span style='color:#800080'>:</span>                 
  <span style='color:#008c00'>33</span><span style='color:#800080'>:</span>                 <span style='color:#800000;font-weight:bold'>function</span> signPetition<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#800080'>{</span>
  <span style='color:#008c00'>34</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> content <span style='color:#808030'>=</span> document<span style='color:#808030'>.</span>getElementById<span style='color:#808030'>(</span><span style='color:#0000e6'>'message'</span><span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>35</span><span style='color:#800080'>:</span>                     postToPetition<span style='color:#808030'>(</span>content<span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>36</span><span style='color:#800080'>:</span>                     postToBuschfunk<span style='color:#808030'>(</span>content<span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>37</span><span style='color:#800080'>:</span>                 <span style='color:#800080'>}</span>
  <span style='color:#008c00'>38</span><span style='color:#800080'>:</span>                 
  <span style='color:#008c00'>39</span><span style='color:#800080'>:</span>                 <span style='color:#800000;font-weight:bold'>function</span> postToPetition<span style='color:#808030'>(</span>content<span style='color:#808030'>)</span> <span style='color:#800080'>{</span>
  <span style='color:#008c00'>40</span><span style='color:#800080'>:</span>                     
  <span style='color:#008c00'>41</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> url <span style='color:#808030'>=</span> 
  <span style='color:#008c00'>42</span><span style='color:#800080'>:</span> <span style='color:#0000e6'>"http://20313wdbv4.adhostbeta.com/studivz/signpetition.cshtml"</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>43</span><span style='color:#800080'>:</span>                     
  <span style='color:#008c00'>44</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> data <span style='color:#808030'>=</span> <span style='color:#800080'>{</span> name<span style='color:#800080'>:</span> content<span style='color:#808030'>.</span>value <span style='color:#800080'>}</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>45</span><span style='color:#800080'>:</span>                     
  <span style='color:#008c00'>46</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> postdata <span style='color:#808030'>=</span> gadgets<span style='color:#808030'>.</span>io<span style='color:#808030'>.</span>encodeValues<span style='color:#808030'>(</span> data <span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>47</span><span style='color:#800080'>:</span>                     
  <span style='color:#008c00'>48</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> params <span style='color:#808030'>=</span> <span style='color:#800080'>{</span><span style='color:#800080'>}</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>49</span><span style='color:#800080'>:</span>                     params<span style='color:#808030'>[</span> gadgets<span style='color:#808030'>.</span>io<span style='color:#808030'>.</span>RequestParameters<span style='color:#808030'>.</span>METHOD <span style='color:#808030'>]</span> <span style='color:#808030'>=</span> 
  <span style='color:#008c00'>50</span><span style='color:#800080'>:</span> gadgets<span style='color:#808030'>.</span>io<span style='color:#808030'>.</span>MethodType<span style='color:#808030'>.</span>POST<span style='color:#800080'>;</span>
  <span style='color:#008c00'>51</span><span style='color:#800080'>:</span>                     params<span style='color:#808030'>[</span> gadgets<span style='color:#808030'>.</span>io<span style='color:#808030'>.</span>RequestParameters<span style='color:#808030'>.</span>POST_DATA <span style='color:#808030'>]</span> <span style='color:#808030'>=</span> postdata<span style='color:#800080'>;</span>
  <span style='color:#008c00'>52</span><span style='color:#800080'>:</span>                     params<span style='color:#808030'>[</span> gadgets<span style='color:#808030'>.</span>io<span style='color:#808030'>.</span>RequestParameters<span style='color:#808030'>.</span>AUTHORIZATION <span style='color:#808030'>]</span> <span style='color:#808030'>=</span> 
  <span style='color:#008c00'>53</span><span style='color:#800080'>:</span> gadgets<span style='color:#808030'>.</span>io<span style='color:#808030'>.</span>AuthorizationType<span style='color:#808030'>.</span>SIGNED<span style='color:#800080'>;</span>
  <span style='color:#008c00'>54</span><span style='color:#800080'>:</span>                     gadgets<span style='color:#808030'>.</span>io<span style='color:#808030'>.</span>makeRequest<span style='color:#808030'>(</span> url<span style='color:#808030'>,</span> 
  <span style='color:#008c00'>55</span><span style='color:#800080'>:</span>                                 onRetrievePeopleSignedPetition<span style='color:#808030'>,</span> params <span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>56</span><span style='color:#800080'>:</span>                 <span style='color:#800080'>}</span>
  <span style='color:#008c00'>57</span><span style='color:#800080'>:</span>                 
  <span style='color:#008c00'>58</span><span style='color:#800080'>:</span>                 <span style='color:#800000;font-weight:bold'>function</span> postToBuschfunk<span style='color:#808030'>(</span>content<span style='color:#808030'>)</span> <span style='color:#800080'>{</span>
  <span style='color:#008c00'>59</span><span style='color:#800080'>:</span>  
  <span style='color:#008c00'>60</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> params <span style='color:#808030'>=</span> <span style='color:#800080'>{</span><span style='color:#800080'>}</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>61</span><span style='color:#800080'>:</span>                     params<span style='color:#808030'>[</span> opensocial<span style='color:#808030'>.</span>Message<span style='color:#808030'>.</span>Field<span style='color:#808030'>.</span>TITLE <span style='color:#808030'>]</span> <span style='color:#808030'>=</span> 
  <span style='color:#008c00'>62</span><span style='color:#800080'>:</span>                                         <span style='color:#0000e6'>'Petition zum Erhalt des Internets'</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>63</span><span style='color:#800080'>:</span>                     params<span style='color:#808030'>[</span> opensocial<span style='color:#808030'>.</span>Message<span style='color:#808030'>.</span>Field<span style='color:#808030'>.</span>TYPE <span style='color:#808030'>]</span> <span style='color:#808030'>=</span> 
  <span style='color:#008c00'>64</span><span style='color:#800080'>:</span> opensocial<span style='color:#808030'>.</span>Message<span style='color:#808030'>.</span>Type<span style='color:#808030'>.</span>PUBLIC_MESSAGE<span style='color:#800080'>;</span>
  <span style='color:#008c00'>65</span><span style='color:#800080'>:</span>                     
  <span style='color:#008c00'>66</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> message <span style='color:#808030'>=</span> opensocial<span style='color:#808030'>.</span>newMessage<span style='color:#808030'>(</span> content<span style='color:#808030'>.</span>value <span style='color:#808030'>+</span> 
  <span style='color:#008c00'>67</span><span style='color:#800080'>:</span>                             <span style='color:#0000e6'>' hat die Petition zum Erhalt des </span>
<span style='color:#0000e6'>&#xa0;&#xa0;68:                                     Internets unterschrieben!'</span><span style='color:#808030'>,</span> params <span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>69</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>var</span> recipient <span style='color:#808030'>=</span> <span style='color:#0000e6'>"VIEWER"</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>70</span><span style='color:#800080'>:</span>                     
  <span style='color:#008c00'>71</span><span style='color:#800080'>:</span>                     opensocial<span style='color:#808030'>.</span>requestSendMessage<span style='color:#808030'>(</span>recipient<span style='color:#808030'>,</span> 
  <span style='color:#008c00'>72</span><span style='color:#800080'>:</span>                                         message<span style='color:#808030'>,</span> onSendMessageComplete<span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>73</span><span style='color:#800080'>:</span>                 <span style='color:#800080'>}</span>
  <span style='color:#008c00'>74</span><span style='color:#800080'>:</span>                 
  <span style='color:#008c00'>75</span><span style='color:#800080'>:</span>                 <span style='color:#800000;font-weight:bold'>function</span> onSendMessageComplete<span style='color:#808030'>(</span> data <span style='color:#808030'>)</span> <span style='color:#800080'>{</span>
  <span style='color:#008c00'>76</span><span style='color:#800080'>:</span>                     <span style='color:#800000;font-weight:bold'>if</span><span style='color:#808030'>(</span> data<span style='color:#808030'>.</span>hadError<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#808030'>)</span> <span style='color:#800080'>{</span>
  <span style='color:#008c00'>77</span><span style='color:#800080'>:</span>                         alert<span style='color:#808030'>(</span> <span style='color:#0000e6'>"Es gab ein problem: "</span> <span style='color:#808030'>+</span> data<span style='color:#808030'>.</span>getErrorCode<span style='color:#808030'>(</span><span style='color:#808030'>)</span> <span style='color:#808030'>)</span><span style='color:#800080'>;</span>
  <span style='color:#008c00'>78</span><span style='color:#800080'>:</span>                     <span style='color:#800080'>}</span>
  <span style='color:#008c00'>79</span><span style='color:#800080'>:</span>                 <span style='color:#800080'>}</span>
  <span style='color:#008c00'>80</span><span style='color:#800080'>:</span>                 
  <span style='color:#008c00'>81</span><span style='color:#800080'>:</span>             
<span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>script<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>13</span><span style='color:#800080'>:</span>             
  <span style='color:#008c00'>14</span><span style='color:#800080'>:</span>             <span style='color:#808030'>&lt;</span>div id<span style='color:#808030'>=</span><span style='color:#0000e6'>'main'</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>15</span><span style='color:#800080'>:</span>                 <span style='color:#808030'>&lt;</span>div id<span style='color:#808030'>=</span><span style='color:#0000e6'>'peopleSigned'</span><span style='color:#808030'>&gt;</span><span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>div<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>16</span><span style='color:#800080'>:</span>                 <span style='color:#808030'>&lt;</span>div id<span style='color:#808030'>=</span><span style='color:#0000e6'>'content'</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>17</span><span style='color:#800080'>:</span>                     Unterschreibe auch Du<span style='color:#808030'>!</span>
  <span style='color:#008c00'>18</span><span style='color:#800080'>:</span>                     <span style='color:#808030'>&lt;</span>input type<span style='color:#808030'>=</span><span style='color:#0000e6'>'text'</span> id<span style='color:#808030'>=</span><span style='color:#0000e6'>'message'</span><span style='color:#0000e6'> </span><span style='color:#800000'>/</span><span style='color:#0000e6'>&gt;</span>
<span style='color:#0000e6'>&#xa0;&#xa0;19:                     &lt;a href='javascript:void</span><span style='color:#808030'>(</span><span style='color:#0000e6'>0</span><span style='color:#808030'>)</span><span style='color:#0000e6'>;' onclick='signPetition</span><span style='color:#808030'>(</span><span style='color:#808030'>)</span><span style='color:#0000e6'>;'&gt;Unterschreiben&lt;</span><span style='color:#800000'>/</span>a<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>20</span><span style='color:#800080'>:</span>                 <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>div<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>21</span><span style='color:#800080'>:</span>             <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>div<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>22</span><span style='color:#800080'>:</span>         <span style='color:#808030'>]</span><span style='color:#808030'>]</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>23</span><span style='color:#800080'>:</span>     <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>Content<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>24</span><span style='color:#800080'>:</span>     <span style='color:#808030'>&lt;</span>Content view<span style='color:#808030'>=</span><span style='color:#0000e6'>"canvas"</span> type<span style='color:#808030'>=</span><span style='color:#0000e6'>"url"</span> href<span style='color:#808030'>=</span><span style='color:#0000e6'>"http://20313wdbv4.adhostbeta.com/studivz/petition.cshtml"</span><span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>25</span><span style='color:#800080'>:</span>     <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>Content<span style='color:#808030'>&gt;</span>
  <span style='color:#008c00'>26</span><span style='color:#800080'>:</span> <span style='color:#808030'>&lt;</span><span style='color:#808030'>/</span>Module<span style='color:#808030'>&gt;</span>
</pre>
<p>Eine kurze Erklärung der Funktionen. In Zeile 3 (JavaScript) registriere ich eine Funktion die beim Laden des Gadgets angesprungen wird. Die Funktion ruft showAppVersionMessage(); auf, welche über eine Mini Message einfach die aktuelle Versionsnummer des Gadgets anzeigt und dann schließlich die Funktion retrievePeopleSignedPetition();. Diese Funktion ruft letztlich den listpetition Endpunkt auf und erhält entsprechend ein Stück HTML zurück das in den aktuellen Gadget Bereich übergeben wird.</p>
<p>Weiter unten ab Zeile 13 (HTML) ist dann ein Anchor Tag angegeben welches die Funktion signPetition(); aufruft. Diese Funktion schreibt nun über den signPetition Endpunkt einen neuen Datensatz in die Petitions-Datenbank, zum anderen wird postToBuschfunk(); aufgerufen, welche eine Nachricht an die Pinnwand schreibt.</p>
<p>Das ist schon die komplette Funktionalität des Gadgets.</p>
<h2><span style="font-family: Calibri,serif"><span style="font-size: medium">Hochladen des Gadgets und Testen</span></span></h2>
<p>Um das Gadget zu testen muss man es in ein gleichnamiges ZIP packen. Das Gadget heißt PetitionGadget.xml und die Zip-Datei heißt demzufolge PetitionGadget.zip. Zum Testen nimmt man nun die Developer Sandbox von *VZ her und lädt das Gadget enstprechend hoch.</p>
<p><a rel="attachment wp-att-2545" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/sandbox-gadget-upload/"><img class="alignnone size-full wp-image-2545" src="http://developer.studivz.net/wp-content/uploads/2010/11/sandbox-gadget-upload.png" alt="" width="528" height="342" /></a></p>
<p><a rel="attachment wp-att-2554" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/sandbox-gadget-preview/"><img class="alignnone size-full wp-image-2554" src="http://developer.studivz.net/wp-content/uploads/2010/11/sandbox-gadget-preview.png" alt="" width="651" height="545" /></a></p>
<p>Ist das Gadget erfolgreich hochgeladen, so kann man sich in der Vorschau die Funktionalität des Gadgets anschauen. Zuerst einen Blick auf den Canvas View:</p>
<p><a rel="attachment wp-att-2552" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/sandbox-gadget-canvas-view/"><img class="alignnone size-full wp-image-2552" src="http://developer.studivz.net/wp-content/uploads/2010/11/sandbox-gadget-canvas-view.png" alt="" width="689" height="599" /></a></p>
<p>Dort wird die Web Anwendung 1:1, wie unter der ursprünglichen URL, integriert angezeigt. Schaltet man nun auf den Profile View erhält man das Mashup von dem HTML das im Gadget enthalten ist und dem Resultat des listpetition Endpunktes.</p>
<p><a rel="attachment wp-att-2544" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/sandbox-gadget-profile-view/"><img class="alignnone size-full wp-image-2544" src="http://developer.studivz.net/wp-content/uploads/2010/11/sandbox-gadget-profile-view.png" alt="" width="439" height="266" /></a></p>
<p>Gut zu sehen, die Mini Message mit der Versionsnummer und die letzten 5 Petitionsunterschriften. Möchte man nun die Petition unterschreiben, so einfach den Namen eintragen und auf Unterschreiben klicken. Sofort kommt die Meldung ob man das Gadget auf die Pinnwand posten lassen möchte:</p>
<p><a rel="attachment wp-att-2543" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/sandbox-gadget-pinnwand/"><img class="alignnone size-full wp-image-2543" src="http://developer.studivz.net/wp-content/uploads/2010/11/sandbox-gadget-pinnwand.png" alt="" width="528" height="235" /></a></p>
<p>Bestätigt man mit senden, so sieht man das Resultat auch in der Pinnwand:</p>
<p><a rel="attachment wp-att-2553" href="http://developer.studivz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/sandbox-gadget-pinnwand-result/"><img class="alignnone size-full wp-image-2553" src="http://developer.studivz.net/wp-content/uploads/2010/11/sandbox-gadget-pinnwand-result.png" alt="" width="419" height="165" /></a></p>
<h2><span style="font-family: Calibri,serif"><span style="font-size: large">Fazit</span></span></h2>
<p>Dieses einfache Beispiel hat gezeigt wie man eine bestehende Web Anwendung in StudiVZ mittels Gadgets und der OpenSocial API integrieren kann. Die Interaktion mit der OpenSocial API belief sich hierbei nur auf reinem JavaScript, es gibt sowohl noch die Möglichkeit über RPC und REST die API aus eigenen Web Anwendungen zu benutzen. Ich habe viele Bereiche nicht beschrieben die für eine richtige Produktiv-App wichtig wären, wie z.B. ein Melden Button für Custom Generated Content oder auch zusätzliche Informationen die zur Installation des Gadgets beigesteuert werden sollten. Komplett außen vorgelassen wurde das Thema OAuth Authentifizierung und Authorisierung. Das Thema ist umfangreich und mit Sicherheit einen eigenen Blogpost Wert und auf dem Developer Wiki findet man weitere Informationen zu diesem Thema. Das Gadget ist hier voll Funktionsfähig im Post enthalten und die Web Anwendung existiert noch bis mindestens Ende des Kalenderjahres 2010 unter dieser URL <a href="http://20313wdbv4.adhostbeta.com/studivz/petition.cshtml">http://20313wdbv4.adhostbeta.com/studivz/petition.cshtml</a>.</p>
<p><strong>Autor: Dariusz Parys, Technical Strategist Web Platform, Microsoft Deutschland GmbH</strong></p>
<p>Dariusz Parys ist seit 2007 als Technical Strategist Web Platform bei der D&amp;PE und seit 2000 bei Microsoft Deutschland tätig. Sein Themenschwerpunkt liegt auf der Microsoft Web Platform und verwandten Technologien. Davor war Dariusz zwei Jahre lang bei einem Großkonzern als Enterprise Architect für Microsoft Consulting Services tätig. Sein Wissen und seine Erfahrung vermittelt er in Vorträgen auf zahlreichen Entwicklerkonferenzen und Workshops. Sie erreichen ihn über seinen Blog unter <a href="http://downtocode.net">http://downtocode.net</a> und über Twitter <a href="http://twitter.com/writeline">@writeline</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/11/19/opensocial-apps-entwickeln-mit-asp-net-autor-dariusz-parys-microsoft-deutschland-gmbh/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>VZnet @ WebTech Conference 2010</title>
		<link>http://developer.vz.net/2010/10/15/vznet-webtech-conference-2010/</link>
		<comments>http://developer.vz.net/2010/10/15/vznet-webtech-conference-2010/#comments</comments>
		<pubDate>Fri, 15 Oct 2010 15:06:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[ActivityStrea.ms]]></category>
		<category><![CDATA[Federated Social Web]]></category>
		<category><![CDATA[OEmbed]]></category>
		<category><![CDATA[OExchange]]></category>
		<category><![CDATA[OpenID]]></category>
		<category><![CDATA[OpenID Connect]]></category>
		<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[PubSubHubbub]]></category>
		<category><![CDATA[Salmon]]></category>
		<category><![CDATA[WebFinger]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2518</guid>
		<description><![CDATA[This week VZnet hosted to sessions at the WebTech conference which took place from October 11th to October 13th in Mainz. Here are the abstracts and the slides for these presentations: Opening up the Social Web &#8211; Standards that are &#8230; <a href="http://developer.vz.net/2010/10/15/vznet-webtech-conference-2010/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This week VZnet hosted to sessions at the WebTech conference which took place from October 11th to October 13th in Mainz.</p>
<p><img class="alignnone" src="http://webtechcon.de/konferenzen/webtech2010/img/layout/header_de.png" alt="" width="960" height="132" /></p>
<p>Here are the abstracts and the slides for these presentations:</p>
<h3>Opening up the Social Web &#8211; Standards that are bridging the Islands</h3>
<p><strong>Speaker:</strong> Bastian Hofmann</p>
<p>Social networks are not closed off to the  rest of the web anymore. Various standards like ActivityStreams,  PubSubHubbub, WebFinger, OpenSocial, Salmon, OEmbed, XAuth or OExchange  are emerging to open them up to other websites. I will introduce these  protocols, show how they work together, how you can benefit from them  and give an outlook on how they will change the world of social  networks.</p>
<p>Slides: <a href="http://www.slideshare.net/bashofmann/open-5432123" target="_blank">http://www.slideshare.net/bashofmann/open-5432123</a></p>
<h3>Distributed Identities with OpenID</h3>
<p><strong>Speaker:</strong> Bastian Hofmann</p>
<p>The era of many separated logins and  identities in the web is slowly coming to an end. Currently many of the  big players are spurring this on with their own proprietary solutions,  but open standards are starting to get more support as well with OpenID  being the most promising one. In this session I will show how OpenID  works for users and developers, where it currently fails and how OpenID  is planned to evolve in the future.</p>
<p>Slides: <a href="http://www.slideshare.net/bashofmann/distributed-identities-with-openid" target="_blank">http://www.slideshare.net/bashofmann/distributed-identities-with-openid</a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/10/15/vznet-webtech-conference-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>First OpenSocial Europe Event in Utrecht (NL)</title>
		<link>http://developer.vz.net/2010/10/13/first-opensocial-europe-event-in-utrecht-nl/</link>
		<comments>http://developer.vz.net/2010/10/13/first-opensocial-europe-event-in-utrecht-nl/#comments</comments>
		<pubDate>Wed, 13 Oct 2010 11:58:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[OpenSocial]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2514</guid>
		<description><![CDATA[The OpenSocial Foundation just announced the first European OpenSocial summit which will be held from December 6th to December 7th in Utrecht (NL). The event will focus on the use of the OpenSocial, its technologies and implementations, and will have &#8230; <a href="http://developer.vz.net/2010/10/13/first-opensocial-europe-event-in-utrecht-nl/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The OpenSocial Foundation just announced the first European OpenSocial summit which will be held from December 6th to December 7th in Utrecht (NL).</p>
<blockquote><p>The event will focus on the use of the OpenSocial, its technologies and  implementations, and will have a special concentration on the  use of  OpenSocial in Research and Education. This two day event is the first  OpenSocial Summit held in Europe, and the first to include an industry  specific spotlight.</p>
<p>Day one will feature prominent speakers from  the OpenSocial community who will present and demonstrate the nuts and  bolts of the specification, including what&#8217;s new in version 1.1, best  practices for building social applications, and the emerging use of  OpenSocial within the Enterprise. There will also be technical sessions  on understanding Apache Shindig, the open source reference framework for  OpenSocial. The first day will conclude with a broad outline of where  the community is heading with future releases and a call to action to  get involved.</p>
<p>The second day is dedicated to the use of  OpenSocial in Research and Education. This will consist of both  interactive workshops and presentations. Several industry experts from  the Research and Educational sector will discuss their experiences using  OpenSocial in their solutions. For example, SURFnet will present its  project on implementing a new <a href="http://www.surfnet.nl/projectcoin">Collaboration Infrastructure</a> and will demonstrate how OpenSocial plays an important role in this  infrastructure by it enabling group centric collaboration in an open,  platform independent way.</p>
<p>We’ve setup a <a href="http://wiki.opensocial.org/index.php?title=OSE2010">wiki page</a> where we will be posting the agenda. While we will do our best to  accommodate all who wish to attend, please keep in mind that space is  limited. Stay tuned to this blog, the OpenSocial Community list, and  the wiki for RSVP information and further details.</p></blockquote>
<p><a href="http://blog.opensocial.org/2010/10/first-european-opensocial-event-in.html" target="_blank">http://blog.opensocial.org/2010/10/first-european-opensocial-event-in.html</a></p>
<p>VZnet will also participating and give a talk on advanced topics of OpenSocial app development, e.g. Data Pipelining, Proxied Content, Embedding of Gadgets or inter gadget communication.</p>
<p><strong>Update:</strong> Registration is now open at <a href="http://event.surfnet.nl/first_european_opensocial_event_in_utrecht_the_netherlands_6_and_7_december_2010.html" target="_blank">http://event.surfnet.nl/first_european_opensocial_event_in_utrecht_the_netherlands_6_and_7_december_2010.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/10/13/first-opensocial-europe-event-in-utrecht-nl/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Neues Feature: HTML5-basierte Diashow</title>
		<link>http://developer.vz.net/2010/09/23/neues-feature-html5-basierte-diashow/</link>
		<comments>http://developer.vz.net/2010/09/23/neues-feature-html5-basierte-diashow/#comments</comments>
		<pubDate>Thu, 23 Sep 2010 12:57:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2499</guid>
		<description><![CDATA[Seit ein paar Tagen gibt es auf *vz ein neues Feature, eine auf HTML5 basierte Diashow. Hier gibt es nun einige Informationen zur technischen Umsetzung und zu Lessons Learned. Die Diashow verwendet das HTML5-Canvas-Element. Die Darstellung der Bilder eines Albums &#8230; <a href="http://developer.vz.net/2010/09/23/neues-feature-html5-basierte-diashow/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>
Seit ein paar Tagen gibt es auf *vz ein neues Feature, eine auf HTML5 basierte Diashow. Hier gibt es nun einige Informationen zur technischen Umsetzung und zu Lessons Learned. Die Diashow verwendet das <a href="http://dev.w3.org/html5/spec/the-canvas-element.html" target="_blank">HTML5-Canvas-Element</a>. Die Darstellung der Bilder eines Albums als Polaroid, und die gespiegelte Anzeige erfolgen mit diesem HTML5-Element und seiner JavaScript-API. Daneben setzt die Diashow neue CSS-Techniken wie <a href="http://www.w3.org/TR/2002/WD-css3-background-20020802/#background-size" target="_blank">background-size</a> ein. Diese neuen Techniken werden von älteren Browsern nicht unterstützt. Um die Browser zu erkennen, die die nötigen Techniken beherschen, verwendet die Diashow eine entsprechende Feature-Detection:
</p>
<p><code>supportsCanvas : function () {<br />
&nbsp;&nbsp;if (/msie|MSIE 9/.test(navigator.userAgent)) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;return true;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;var supportsBgSize = !!($('body').css('background-size') <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|| $('body').css('-moz-background-size'));<br />
&nbsp;&nbsp;if (!supportsBgSize) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;return false;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;var canvas = document.createElement('canvas');<br />
&nbsp;&nbsp;if (!canvas.getContext) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;return false;<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;return !!canvas.getContext('2d').fillText;<br />
}</code></p>
<p>
Wie man sehen kann, ist es leider keine reine Feature-Detection, da auch die Abfrage des UserAgents erfolgt. Dies erfolgt aus dem Grund, dass die normalen VZ-Seiten momentan im Internet Explorer noch den IE7-Document-Modus verwenden. Im HTML-Head wird dies durch die Zeile</p>
<p><code>&lt;meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /&gt;</code></p>
<p>definiert. Durch diesen Document-Modus würde im Internet Explorer 9 aber eine reine Feature-Detection auf HTML5-Features nicht funktionieren, da der Internet Explorer 9 im IE7-Modus die HTML5-Features auch nicht unterstützt. Also wurde die Browserüberprüfung entsprechend erweitert, um die korrekte Verlinkung der neuen Diashow und der alten Diashow (die für Browser verlinkt ist, die die HTML5-Features nicht unterstützen) zu erreichen. Die Diashow selbst verwendet natürlich im Internet Explorer 9 den aktuellen Document-Mode, entsprechend ist dort im HTML-Head folgende Zeile:</p>
<p><code>&lt;meta http-equiv="X-UA-Compatible" content="IE=9" /&gt;</code>
</p>
<p>
Bei den Arbeiten mit dem Canvas-Element ergab sich ein Pattern für komplexere Anwendungen. Statt Verwendung eines einzelnen Canvas-Elements in einer Seite kann man mehrere Canvas-Elemente in eine Seite einbinden (entsprechende positioniert, und mit CSS über z-index die Darstellungs-Anordnung definiert). Dadurch ist es einfach möglich, mit Zeichnungsebenen zu arbeiten, die separat gelöscht und neugezeichnet werden können, die einzeln verschoben/animiert werden können, etc. Jede Zeichnungsebene ist dabei ein Canvas-Element. Diese Technik setzen wir in der Diashow ein, indem der Hintergrund mit einem Canvas-Element dargestellt wird, der Vordergrund mit den Polaroid-Darstellungen von einem anderen Canvas-Element. Bei bestimmten Aktionen, wie dem geringfügigen Ändern der Fenstergröße wird dann nur der Hintergrund neugezeichnet, das Canvas für den Vordergund bleibt bestehen. Mit nur einem Canvas-Element wären dagegen wesentlich mehr Funktionsaufrufe/Zeichenvorgänge nötig. Folgende Screenshots zeigen die Darstellung, wenn man über Firebug nur Vordergrund- bzw. Hintergrund-Canvas einblendet (beim Vordergrund-Canvas wurde zur besseren Darstellung auch die CSS-Hintergrund-Farbe weggeschaltet):
</p>
<p>
<a href="http://developer.studivz.net/wp-content/uploads/2010/09/diashow-background.png"><img src="http://developer.studivz.net/wp-content/uploads/2010/09/diashow-background-1024x519.png" alt="" width="740" class="alignnone size-large wp-image-2502" /></a><br />
<a href="http://developer.studivz.net/wp-content/uploads/2010/09/diashow-foreground2.png"><img src="http://developer.studivz.net/wp-content/uploads/2010/09/diashow-foreground2-1023x523.png" alt="" width="740" class="alignnone size-large wp-image-2503" /></a>
</p>
<p>Mit Vorder- und Hintergrund ergibt sich dann die Darstellung in der Diashow:<br />
<a href="http://developer.studivz.net/wp-content/uploads/2010/09/diashow-combination1.png"><img src="http://developer.studivz.net/wp-content/uploads/2010/09/diashow-combination1-1024x522.png" alt="" width="740" class="alignnone size-large wp-image-2505" /></a>
</p>
<p>Die Bildschirmschoner-Animation, die in der Übersicht eines Albums momentan nach 30 Sekunden ohne Aktion gestartet wird, erfolgt entsprechend ebenfalls in einem eigenen Canvas-Element. Dadurch kann dieser Animation auch schnell wieder ausgeblendet werden, und die vorherige Darstellung wiederhergestellt werden, ohne komplexe Canvas-Malvorgänge ausführen zu müssen.
</p>
<p><b>Interessante Links:</b><br />
<a target="_blank" href="https://developer.mozilla.org/en/Canvas_tutorial">Mozilla Canvas Tutorial</a><br />
<a target="_blank" href="http://canvas.quaese.de/">Deutsches Canvas Tutorial</a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/09/23/neues-feature-html5-basierte-diashow/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Traversieren/Modifizieren von TextNodes mit JQuery</title>
		<link>http://developer.vz.net/2010/09/22/traversierenmodifizieren-von-textnodes-mit-jquery-2/</link>
		<comments>http://developer.vz.net/2010/09/22/traversierenmodifizieren-von-textnodes-mit-jquery-2/#comments</comments>
		<pubDate>Wed, 22 Sep 2010 09:17:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Daily Business]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[RIA]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2490</guid>
		<description><![CDATA[In einer Webanwendung gibt es manchmal die Situation, dass man in  bestehendem HTML-Code bestimmte Textinhalte modifizieren muss, unter  Verwendung von zusätzlichem Markup. Z.B. Links klickbar machen,  Highlighting von Suchergebnissen, etc. Dieser Artikel zeigt, wie man  mit JQuery die Textnodes iterieren und dabei modifizieren kann. <a href="http://developer.vz.net/2010/09/22/traversierenmodifizieren-von-textnodes-mit-jquery-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In einer Webanwendung gibt es manchmal die Situation, dass man in  bestehendem HTML-Code bestimmte Textinhalte modifizieren muss, unter  Verwendung von zusätzlichem Markup. Z.B. Links klickbar machen,  Highlighting von Suchergebnissen, etc. Folgendes Sample zeigt, wie man  mit JQuery die Textnodes iterieren und dabei modifizieren kann:</p>
<p><code>// newElement enthält das zu modifizierende HTML. Dabei soll "Mein" durch "&lt;b&gt;Mein&lt;/b&gt;" ersetzt<br />
// werden, aber nur in Texten, nicht an sonstigen Stellen im HTML-Code<br />
var newElement = $(['&lt;ul&gt;&lt;li&gt;Erste &lt;a href="http://www.Mein.de/"&gt;',<br />
&nbsp;&nbsp;&nbsp;&nbsp;'URL anders?&lt;/a&gt; Zeile&lt;/li&gt;',<br />
&nbsp;&nbsp;&nbsp;&nbsp;'&lt;li&gt;Meine zweite Zeile&lt;/li&gt;&lt;li&gt;Dein und Mein&lt;/li&gt;',<br />
&nbsp;&nbsp;&nbsp;&nbsp;'&lt;li&gt;Nicht Mein sondern Main&lt;/li&gt;&lt;/ul&gt;'].join(''));<br />
&nbsp;&nbsp;<br />
// Diese Zeile selektiert/filtert die TextNodes in newElement:<br />
var textnodes = $('*', newElement).contents().filter(function(){ return this.nodeType == 3 ; });<br />
&nbsp;&nbsp;<br />
// Durchlaufen der TextNodes:<br />
$.each(textnodes, function () {<br />
&nbsp;&nbsp;// mit this.nodeValue erhält man den Text-Inhalt des Text-Elements im DOM<br />
&nbsp;&nbsp;if (this.nodeValue.indexOf('Mein')&gt;=0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;//Ersetzen des TextNodes durch ein HTML-Konstrukt<br />
&nbsp;&nbsp;&nbsp;&nbsp;$(this).replaceWith(this.nodeValue.replace('Mein', '&lt;b&gt;Mein&lt;/b&gt;'));<br />
&nbsp;&nbsp;}<br />
});<br />
&nbsp;&nbsp;<br />
// Anzeige des Ergebnis<br />
console.log(newElement.html());</code></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/09/22/traversierenmodifizieren-von-textnodes-mit-jquery-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Incorporating a remote Subversion repository into a local spin off</title>
		<link>http://developer.vz.net/2010/07/22/incorporating-a-remote-subversion-repository-into-a-local-spin-off/</link>
		<comments>http://developer.vz.net/2010/07/22/incorporating-a-remote-subversion-repository-into-a-local-spin-off/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 17:34:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Daily Business]]></category>
		<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[Operations]]></category>
		<category><![CDATA[Shindig]]></category>
		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2454</guid>
		<description><![CDATA[To render and display the OpenSocial apps available on our platform we are using the Apache Shindig gadget server, currently with the version 1.0.incubating Up until now we had just exported this Shindig version and committed this into our local &#8230; <a href="http://developer.vz.net/2010/07/22/incorporating-a-remote-subversion-repository-into-a-local-spin-off/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>To render and display the <a href="http://www.opensocial.org/">OpenSocial</a> apps available on our platform we are using the <a href="http://shindig.apache.org/">Apache Shindig</a> gadget server, currently with the version 1.0.incubating<br />
Up until now we had just exported this Shindig version and committed this into our local in-house subversion repository. From there on we added all kinds of patches, bug fixes and extensions to it. Over the month this accumulated to about 50 different changes to the original shindig codebase, which made it very hard to upgrade to a newer Shindig version or to apply any patches for the original version.</p>
<p>Now that the time is coming to migrate to the <a href="http://opensocial-resources.googlecode.com/svn/spec/0.9/">OpenSocial 0.9 spec</a> with Shindig 2.0 we rethought our Shindig development strategy and came up with a different process:</p>
<p>At first we refactored the changes we did heavily to be as separated as possible from the original Shindig codebase.<br />
What we couldn&#8217;t strip out, we extracted as diff patches into separated patch files.<br />
This left us with the original codebase, some 20 patch files and some extra php classes and JavaScript packages.<br />
Now this allowed us to just commit the patches and extra files into our own subversion repository. Then we added a small build script which will export the rest of the folders and files we need from the Apache Shindig Subversion server. This means that these files are not under version control anymore and subversion does not want to commit them to the Apache Shindig Subversion (for which we have no write access) if some files have changed. For this files and folders there is a <a href="http://svnbook.red-bean.com/en/1.1/ch07s02.html#svn-ch-7-sect-2.3.3">svn:ignore</a> property set in our subversion, so that these files are not committed accidentally.<br />
After the export the build script applies all patches and we have a working shindig server in our file system.</p>
<p><code><br />
#!/bin/bash<br />
apache_svn_base="https://svn.apache.org/repos/asf/"<br />
shindig_svn_base="shindig/trunk"</code><br />
<code><br />
paths[0]="config/OSML_library.xml"<br />
paths[1]="config/container.js"<br />
paths[2]="config/oauth.json"<br />
paths[3]="content"<br />
paths[4]="extras/src/main/javascript/features-extras"<br />
paths[5]="features"<br />
paths[6]="php/config/container.php"<br />
paths[7]="php/docs"<br />
paths[8]="php/external"<br />
paths[9]="php/src"<br />
paths[10]="php/test"<br />
paths[11]="php/.htaccess"<br />
paths[12]="php/index.php"</code><br />
<code><br />
revision[0]="965715"<br />
revision[1]="965715"<br />
revision[2]="965715"<br />
revision[3]="965715"<br />
revision[4]="965715"<br />
revision[5]="965715"<br />
revision[6]="965715"<br />
revision[7]="965715"<br />
revision[8]="965715"<br />
revision[9]="965715"<br />
revision[10]="965715"<br />
revision[11]="965715"<br />
revision[12]="965715"</code><br />
<code><br />
ELEMENTS=${#paths[@]}</code><br />
<code><br />
for (( i=0;i&lt;$ELEMENTS;i++)); do<br />
# remove local files<br />
rm -rf ${paths[${i}]}<br />
# export remote files to local copy<br />
svn export -r ${revision[${i}]} $apache_svn_base$shindig_svn_base/${paths[${i}]} ${paths[${i}]}<br />
done</code><br />
<code><br />
# apply patches<br />
patches="patches/*.patch"</code><br />
<code><br />
for f in $patches<br />
do<br />
echo "********** load patch $f"<br />
patch -p0 -N -i $f<br />
done</code></p>
<p>In this solution it is necessary for us to be able to see what we changed in the original files while developing, so that we can add or modify new patch files. For this we wrote a small diff script which downloads the version of a file from the Apache Shindig SVN and diffs it to its local copy.</p>
<p><code><br />
#!/bin/bash<br />
apache_svn_base="https://svn.apache.org/repos/asf/"<br />
shindig_svn_base="shindig/trunk"</code><br />
<code><br />
paths[0]="config/OSML_library.xml"<br />
paths[1]="config/container.js"<br />
paths[2]="config/oauth.json"<br />
paths[3]="content"<br />
paths[4]="extras/src/main/javascript/features-extras"<br />
paths[5]="features"<br />
paths[6]="php/config/container.php"<br />
paths[7]="php/docs"<br />
paths[8]="php/external"<br />
paths[9]="php/src"<br />
paths[10]="php/test"<br />
paths[11]="php/.htaccess"<br />
paths[12]="php/index.php"</code><br />
<code><br />
revision[0]="965715"<br />
revision[1]="965715"<br />
revision[2]="965715"<br />
revision[3]="965715"<br />
revision[4]="965715"<br />
revision[5]="965715"<br />
revision[6]="965715"<br />
revision[7]="965715"<br />
revision[8]="965715"<br />
revision[9]="965715"<br />
revision[10]="965715"<br />
revision[11]="965715"<br />
revision[12]="965715"</code><br />
<code><br />
ELEMENTS=${#paths[@]}<br />
line="==================================================================="</code><br />
<code><br />
for (( i=0;i&lt;$ELEMENTS;i++)); do<br />
find ${paths[${i}]} -type f -exec sh -c '(curl -s $2!svn/bc/$3/$4/$1 | diff -w - $1 |  sed -e "1i\\<br />
Index: $1\\<br />
$5")' {} {} $apache_svn_base ${revision[${i}]} $shindig_svn_base $line \;<br />
done</code></p>
<p>For all folders we traverse through all files, fetch the file from the remote Shindig SVN with CURL, diff the fetched content to the local file, and print out a ready diff patch with leading Index entry and separator line like its generated by the svn diff command.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/07/22/incorporating-a-remote-subversion-repository-into-a-local-spin-off/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>XMPP Chat Beta</title>
		<link>http://developer.vz.net/2010/06/30/xmpp-chat-beta/</link>
		<comments>http://developer.vz.net/2010/06/30/xmpp-chat-beta/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 12:00:03 +0000</pubDate>
		<dc:creator>Peter</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[XMPP]]></category>
		<category><![CDATA[chat]]></category>
		<category><![CDATA[Plauderkasten]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2431</guid>
		<description><![CDATA[Achtung: Seit 22.11.2010 ist eine neue Version des XMPP Servers Online. (ohne den JID-wechseldich-Bug) Ihr wollt den Plauderkasten über XMPP testen? Ihr dürft! Server jabber.vz.net (studiVZ+meinVZ) ODER jabber.schuelervz.net Port: 5222 ODER 5223 (SSL/TLS wird unterstützt, für Legacy-Clients wird Port 5223 &#8230; <a href="http://developer.vz.net/2010/06/30/xmpp-chat-beta/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Achtung:</strong> Seit 22.11.2010 ist eine neue Version des XMPP Servers Online. (ohne den JID-wechseldich-Bug)</p>
<p>Ihr wollt den Plauderkasten über XMPP testen? Ihr dürft!</p>
<p><strong>Server</strong><br />
jabber.vz.net (studiVZ+meinVZ) ODER jabber.schuelervz.net<br />
Port: 5222 ODER 5223<br />
(SSL/TLS wird unterstützt, für Legacy-Clients wird Port 5223 mit SSL-Verschlüsselung angeboten)</p>
<p><strong>Login studiVZ oder meinVZ</strong><br />
Jabber-User: john\40doe.de@vz.net &#8211; das \40 ersetzt das @ in eurer Mailadresse<br />
Passwort: deinvzpasswort</p>
<p><strong>Login schülerVZ</strong><br />
Jabber-User: john\40doe.de@schuelervz.net &#8211; das \40 ersetzt das @ in eurer Mailadresse<br />
Passwort: deinvzpasswort</p>
<p>Folgende Clients machen momentan leider Probleme: <del datetime="2010-12-22T13:26:56+00:00">PSI, Empathy, Pidgin</del> qutIM</p>
<p>Euer Feedback könnt ihr gern hier im Blog posten. Aber bitte denkt daran: Da steht noch ein  Beta drüber. ;-)</p>
<p>Happy Testing!</p>
<p><strong>UPDATE  +++ UPDATE +++ UPDATE</strong> </p>
<p>Danke für eure zahlreichen Kommentare und Hinweise. Wir haben in den letzten Tagen unsere XMPP Server unter Livebedingungen ausgiebig getestet und euer Feedback zusammengetragen. Hier die für euch spannenden Informationen.</p>
<p>Folgende Dinge wurden schon erledigt und sollten keine Probleme mehr bereiten.<br />
#6 DNS-Einträge (SRV-Records)<br />
Die Einträge haben wir nachgezogen, auch für schülerVZ. Danke für den Hinweis.</p>
<p>#56 Mit meinVZ und schülerVZ gleichzeitig verbinden<br />
Das ist möglich, bitte oben auf die unterschiedlichen Serveradressen achten.</p>
<p>#73 Ports öffnen<br />
Wir haben Port 80 nun auch für XMPP Verbindungen freigegeben.<br />
(Bitte beachten: Da klappt leider die automatische Server-Konfiguration nicht.)</p>
<p>Das wird es bald geben:<br />
#19 Sonderzeichen im Passwort<br />
Das ist ein Bug im xmpp und wird gefixt.</p>
<p>#5 /40 für @ sorgt für Verwirrung<br />
Da überlegen wir uns eine elegantere Lösung. </p>
<p># &#8220;Jid wechsel dich&#8221;<br />
Das ist als Bug aufgenommen und in bearbeitung. </p>
<p>Weiterhin sorgt die Erweiterung des Standards für Probleme bei verschiedenen Clients. Wir überlegen uns gerade wie wir das lösen werden und halten euch hier auf dem laufenden!</p>
<p>Übrigens, wir Developer suchen noch Kollegen: <a href="http://jobs.studivz.net/">jobs.studivz.net</a> :)</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/06/30/xmpp-chat-beta/feed/</wfw:commentRss>
		<slash:comments>680</slash:comments>
		</item>
		<item>
		<title>Ganz frisch: VZ App mit Plauderkasten für Android!</title>
		<link>http://developer.vz.net/2010/06/17/ganz-frisch-vz-app-mit-plauderkasten-fur-android/</link>
		<comments>http://developer.vz.net/2010/06/17/ganz-frisch-vz-app-mit-plauderkasten-fur-android/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 09:34:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Plauderkasten]]></category>
		<category><![CDATA[VZ App]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2405</guid>
		<description><![CDATA[Schöner als Weihnachten und Grand Prix Gewinn zusammen: die VZ App für Android (1.5)! Neu, frisch und ab sofort mit Plauderkasten gibt&#8217;s studiVZ, meinVZ und schülerVZ als App für alle Android Geräte ab Version 1.5. Download direkt via Handy beim &#8230; <a href="http://developer.vz.net/2010/06/17/ganz-frisch-vz-app-mit-plauderkasten-fur-android/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Schöner als Weihnachten und Grand Prix Gewinn zusammen: <strong>die VZ App für Android (1.5)!</strong></p>
<p>Neu, frisch und ab sofort mit Plauderkasten gibt&#8217;s studiVZ, meinVZ und schülerVZ als App für alle Android Geräte ab Version 1.5.</p>
<p>Download direkt via Handy beim Market: <a href="market://search?q=pname:net.studivz.android">VZ App für Android</a></strong></p>
<p>oder via:<br />
<a href="http://developer.studivz.net/wp-content/uploads/2010/06/vz-app-android.png"><img src="http://developer.studivz.net/wp-content/uploads/2010/06/vz-app-android.png" alt="" title="vz app android" width="165" height="167" class="alignnone size-full wp-image-2414" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/06/17/ganz-frisch-vz-app-mit-plauderkasten-fur-android/feed/</wfw:commentRss>
		<slash:comments>46</slash:comments>
		</item>
		<item>
		<title>Endlich: VZ App für Windows Mobile!</title>
		<link>http://developer.vz.net/2010/06/16/endlich-vz-app-fur-windows-mobile/</link>
		<comments>http://developer.vz.net/2010/06/16/endlich-vz-app-fur-windows-mobile/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 14:21:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[VZ App]]></category>
		<category><![CDATA[Windows Mobile]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2398</guid>
		<description><![CDATA[Update: Nun auch für die größeres Displays: Download VZ App für Windows Mobile Endlich ist sie da &#8211; die VZ App mit Plauderkasten für Windows Mobile! Folgende Handys werden mit dieser ersten Version unterstützt: Acer Neo Touch P400 (320&#215;480) Acer &#8230; <a href="http://developer.vz.net/2010/06/16/endlich-vz-app-fur-windows-mobile/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</p>
<p>Nun auch für die größeres Displays: <a href="http://static.studivz.net/media/de/mobile-widgets/WindowsMobile/VZ-WindowsMobileAPP.CAB">Download VZ App für Windows Mobile</a></strong></p>
<p>Endlich ist sie da &#8211; die <strong>VZ App mit Plauderkasten für Windows Mobile</strong>!</p>
<p>Folgende Handys werden mit dieser ersten Version unterstützt:</p>
<p><strong>Acer Neo Touch  P400  (320&#215;480)<br />
Acer Neo Touch  P400  (240&#215;400)<br />
Acer beTouch E101 (240&#215;400)<br />
Acer beTouch E200 (240&#215;400)<br />
htc HD mini  (320&#215;480)<br />
htc Touch 2 (240&#215;320)<br />
htc Touch 3G (240&#215;320)<br />
LG GM750 (240&#215;400)<br />
O2 xda Guide (240&#215;320)</strong></p>
<p>In den nächsten Tagen gibt&#8217;s ein Update mit dem dann auch weitere Geräte mit größeren Auflösungen unterstützt werden. Versprochen!</p>
<p><a href="http://static.studivz.net/media/de/mobile-widgets/WindowsMobile/VZ_1_00_12.CAB"><strong>Download VZ App für Windows Mobile</strong></a></p>
<p>Mit der Bitte um Feedback in unsere <a href="http://www.studivz.net/Groups/Overview/edfc4ca1e45f6ff9"><b>Mobile Gruppe (studiVZ)</b></a> oder <a href="http://www.schuelervz.net/Groups/Overview/8290e5965cd376b8"><b>Mobile Gruppe (schülerVZ)</b></a>. :)</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/06/16/endlich-vz-app-fur-windows-mobile/feed/</wfw:commentRss>
		<slash:comments>79</slash:comments>
		</item>
		<item>
		<title>Neue VZ-App mit Plauderkasten für Nokia!</title>
		<link>http://developer.vz.net/2010/06/14/neue-vz-app-mit-plauderkasten-fur-nokia/</link>
		<comments>http://developer.vz.net/2010/06/14/neue-vz-app-mit-plauderkasten-fur-nokia/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 14:40:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[App]]></category>
		<category><![CDATA[Nokia]]></category>
		<category><![CDATA[Plauderkasten]]></category>
		<category><![CDATA[Symbian]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2381</guid>
		<description><![CDATA[Ganz frisch und noch warm gibt&#8217;s die neue VZ-App mit der Plauderkasten-Funktion für alle Nokia Geräte, die auf Symbian 60 laufen. Ein Liste der Nokia Handys mit s60 findet Ihr hier: Nokia s60 (1) Nokia s60 (2) Nokia s60 (3) &#8230; <a href="http://developer.vz.net/2010/06/14/neue-vz-app-mit-plauderkasten-fur-nokia/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ganz frisch und noch warm gibt&#8217;s die neue VZ-App mit der <strong>Plauderkasten-Funktion</strong> für alle Nokia Geräte, die auf Symbian 60 laufen.</p>
<p>Ein Liste der Nokia Handys mit s60 findet Ihr hier:</p>
<p><a href="http://www.forum.nokia.com/Devices/Device_specifications/matrix_s60_5ed_1.html">Nokia s60 (1)</a><br />
<a href="http://www.forum.nokia.com/Devices/Device_specifications/matrix_s60_3ed_fp2_1.html">Nokia s60 (2)</a><br />
<a href="http://www.forum.nokia.com/Devices/Device_specifications/matrix_s60_3ed_fp1_1.html">Nokia s60 (3)</a></p>
<p><strong><a href="http://static.studivz.net/media/de/mobile-widgets/Symbian/VZ_1_1_19_Express_Signed.sis">Download der neuen VZ-APP</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/06/14/neue-vz-app-mit-plauderkasten-fur-nokia/feed/</wfw:commentRss>
		<slash:comments>99</slash:comments>
		</item>
		<item>
		<title>Deutschlands größte Fankurve! &#8211; und die Menschen hinter studiVZ &amp; Co.</title>
		<link>http://developer.vz.net/2010/06/14/deutschlands-groste-fankurve-und-die-menschen-hinter-studivz-co/</link>
		<comments>http://developer.vz.net/2010/06/14/deutschlands-groste-fankurve-und-die-menschen-hinter-studivz-co/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 13:52:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Jobs]]></category>
		<category><![CDATA[studiVZ]]></category>
		<category><![CDATA[VZ Netzwerke]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2374</guid>
		<description><![CDATA[Werde Teil von Deutschlands größter Fankurve und studiVZ.]]></description>
			<content:encoded><![CDATA[<p><a href="http://developer.studivz.net/wp-content/uploads/2010/06/P6117624b.jpg"><img src="http://developer.studivz.net/wp-content/uploads/2010/06/studivzall2.jpg" alt="" title="Das VZ-Team steht hinter unseren Jungs!" width="700"  class="aligncenter size-full wp-image-2373" /></a></p>
<p>Werde Teil von <a href="http://www.studivz.net/Profile/Flipside/jP9OL5WwpYPlwmCc13rO4w">Deutschlands größter Fankurve </a>und <a href="http://www.studivz.net/l/jobs">studiVZ</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/06/14/deutschlands-groste-fankurve-und-die-menschen-hinter-studivz-co/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Kostenlos: studiVZ, schülerVZ und meinVZ für das iPad!</title>
		<link>http://developer.vz.net/2010/06/11/kostenlos-studivz-schulervz-und-meinvz-fur-das-ipad/</link>
		<comments>http://developer.vz.net/2010/06/11/kostenlos-studivz-schulervz-und-meinvz-fur-das-ipad/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 11:12:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[App]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[ipad]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2343</guid>
		<description><![CDATA[Update am 13.05.2011: Die VZ iPad-Applikation steht nicht mehr zur Verfügung. Bitte nutzt die iPhone-Applikation.&#160; Mit dem iPad Launch in Deutschland bringen wir jetzt auch studiVZ, schülerVZ und meinVZ auf die Wunderflunder aus Cupertino. Wochen und Monate saß mein Team42 &#8230; <a href="http://developer.vz.net/2010/06/11/kostenlos-studivz-schulervz-und-meinvz-fur-das-ipad/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://itunes.apple.com/de/app/vz-netzwerke-hd/id374943677?mt=8" _mce_href="http://itunes.apple.com/de/app/vz-netzwerke-hd/id374943677?mt=8" alt="iPad App Download" title="iPad App Download"><img src="http://developer.studivz.net/wp-content/uploads/2010/06/Icon_iPad_App.png" _mce_src="http://developer.studivz.net/wp-content/uploads/2010/06/Icon_iPad_App.png"></a></p>
<p><strong>Update am 13.05.2011: Die VZ iPad-Applikation steht nicht mehr zur Verfügung. Bitte nutzt die iPhone-Applikation.</strong>&nbsp;</p>
<p>Mit dem iPad Launch in Deutschland bringen wir jetzt auch <strong>studiVZ</strong>, <strong>schülerVZ</strong> und <strong>meinVZ</strong> auf die Wunderflunder aus Cupertino.</p>
<p>Wochen und Monate saß mein Team42 aus dem Engineering daran, eine neue <a href="http://itunes.apple.com/de/app/vz-netzwerke-hd/id374943677?mt=8" _mce_href="http://itunes.apple.com/de/app/vz-netzwerke-hd/id374943677?mt=8">maßgeschneiderte App</a> speziell für das iPad zu entwickeln. </p>
<p>Im neuen <strong>Look &amp; Feel</strong> wollen wir die außergewöhnliche iPad-Userexperience für unsere 16 Millionen Nutzer auf den Punkt bringen: <strong>Klar. Verständlich. Interaktiv.</strong></p>
<p>So erscheint unter anderem der Buschfunk im neuem interaktiven Zeitungsstil.</p>
<p>Mehr seht, spürt und fühlt Ihr, wenn Ihr es selbst <a href="http://itunes.apple.com/de/app/vz-netzwerke-hd/id374943677?mt=8" _mce_href="http://itunes.apple.com/de/app/vz-netzwerke-hd/id374943677?mt=8">ausprobiert</a>! ;)</p>
<p>Und Feedback gerne an uns!</p>
<p><center<br />
<img src="http://developer.studivz.net/wp-content/uploads/2010/06/ipad-app-1.png" _mce_src="http://developer.studivz.net/wp-content/uploads/2010/06/ipad-app-1.png" alt="" title="ipad app 1" width="373" height="491" class="aligncenter size-full wp-image-2352"><br />
<img src="http://developer.studivz.net/wp-content/uploads/2010/06/ipad-app-2.png" _mce_src="http://developer.studivz.net/wp-content/uploads/2010/06/ipad-app-2.png" alt="" title="ipad app 2" width="495" height="375" class="alignnone size-full wp-image-2353"><br />
<img src="http://developer.studivz.net/wp-content/uploads/2010/06/ipad-app-3.png" _mce_src="http://developer.studivz.net/wp-content/uploads/2010/06/ipad-app-3.png" alt="" title="ipad app 3" width="492" height="376" class="alignnone size-full wp-image-2354"><br />
<img src="http://developer.studivz.net/wp-content/uploads/2010/06/ipad-app-4.png" _mce_src="http://developer.studivz.net/wp-content/uploads/2010/06/ipad-app-4.png" alt="" title="ipad app 4" width="492" height="372" class="alignnone size-full wp-image-2355"><br />
<img src="http://developer.studivz.net/wp-content/uploads/2010/06/ipad-app-5.png" _mce_src="http://developer.studivz.net/wp-content/uploads/2010/06/ipad-app-5.png" alt="" title="ipad app 5" width="373" height="490" class="alignnone size-full wp-image-2356"><br />
</center</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/06/11/kostenlos-studivz-schulervz-und-meinvz-fur-das-ipad/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>iPhoto Plugin für studiVZ, schülerVZ und meinVZ.</title>
		<link>http://developer.vz.net/2010/05/14/iphoto-plugin-fur-studivz-schulervz-und-meinvz/</link>
		<comments>http://developer.vz.net/2010/05/14/iphoto-plugin-fur-studivz-schulervz-und-meinvz/#comments</comments>
		<pubDate>Fri, 14 May 2010 10:30:32 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/2010/05/14/iphoto-plugin-fur-studivz-schulervz-und-meinvz/</guid>
		<description><![CDATA[Wir haben noch einmal dran gebastelt und ein neues Update zum iPhoto Plugin veröffentlicht. Nutzer, welche die Vorgängerversion bereits installiert haben, erhalten automatisch ein Update. Alle anderen können sich das aktuelle Plugin für iPhoto hier holen: Download iPhoto Plugin für &#8230; <a href="http://developer.vz.net/2010/05/14/iphoto-plugin-fur-studivz-schulervz-und-meinvz/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Wir haben noch einmal dran gebastelt und ein neues Update zum iPhoto Plugin veröffentlicht.</p>
<p>Nutzer, welche die Vorgängerversion bereits installiert haben, erhalten automatisch ein Update. Alle anderen können sich das aktuelle Plugin für iPhoto hier holen:</p>
<p><strong><a href="http://static.pe.studivz.net/media/de/mobile-widgets/iPhotoplugin/VZnetiPhotoPlugin.dmg">Download iPhoto Plugin für studiVZ schülerVZ und meinVZ</a></strong></p>
<p><a href="http://static.pe.studivz.net/media/de/mobile-widgets/iPhotoplugin/VZnetiPhotoPlugin.dmg"><img src="http://developer.studivz.net/wp-content/uploads/2010/05/VZnet-iPhoto-Plugin.jpg"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/05/14/iphoto-plugin-fur-studivz-schulervz-und-meinvz/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Releasenotes Major Release 2010-08</title>
		<link>http://developer.vz.net/2010/04/28/releasenotes-major-release-2010-08/</link>
		<comments>http://developer.vz.net/2010/04/28/releasenotes-major-release-2010-08/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 11:12:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Daily Business]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[ReleaseNotes]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2331</guid>
		<description><![CDATA[Am Montag Nachmittag ist unser Major Release 2010-08 online gegangen. Neben zahlreichen Infrastruktur- und Backendmaßnahmen wurden folgende Features releast: - Embedding auf Pinnwänden, in Gruppen und im Nachrichtendienst für externe Seiten - Embedding Dialoge für Fotos, Videos, Apps, Pinnwandbilder, Gruppen &#8230; <a href="http://developer.vz.net/2010/04/28/releasenotes-major-release-2010-08/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Am Montag Nachmittag ist unser Major Release 2010-08 online gegangen. Neben zahlreichen Infrastruktur- und Backendmaßnahmen wurden folgende Features releast:</p>
<p>- Embedding auf Pinnwänden, in Gruppen und im Nachrichtendienst für externe Seiten<br />
- Embedding Dialoge für Fotos, Videos, Apps, Pinnwandbilder, Gruppen und Profile<br />
- Meldefunktion für einzelne Pinnwand-Posts und Foren-Posts<br />
- Vorschau-Funktion für Pinnwand-Posts und Foren-Posts</p>
<p>Apps:<br />
- Vergrößerung des Integration Views auf 800px Breite<br />
- Überarbeitung Visitenkartenverwaltung</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/04/28/releasenotes-major-release-2010-08/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>VZ-Netzwerke @ next Conference 2010</title>
		<link>http://developer.vz.net/2010/04/28/vz-netzwerke-next-conference-2010/</link>
		<comments>http://developer.vz.net/2010/04/28/vz-netzwerke-next-conference-2010/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 09:37:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[Conference]]></category>
		<category><![CDATA[next10]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2321</guid>
		<description><![CDATA[On May, 11th and May, 12th the 10th next Conference takes place in Berlin. We are happy to announce that VZ-Netzwerke will sponsor this conference. Additionally we will be present with a booth on the small conference fair where you &#8230; <a href="http://developer.vz.net/2010/04/28/vz-netzwerke-next-conference-2010/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" src="http://developer.studivz.net/wp-content/uploads/2010/04/Bildschirmfoto-2010-04-28-um-10.59.38.png" alt="next Conference" />On May, 11th and May, 12th the 10th <a href="http://nextconf.eu/next10/">next Conference</a> takes place in Berlin.</p>
<p>We are happy to announce that VZ-Netzwerke will sponsor this conference. Additionally we will be present with a booth on the small conference fair where you will be able to meet up with some of our developers, product and partner managers. Be prepared to get your adrenalin up and running at our VZ-Racing-Competition.</p>
<p>On the conference itself we are holding a session on Social Apps at VZ-Netzwerke:</p>
<p><strong>Day:</strong> May 12, Track 3<br />
<strong>Time:</strong> 11.45am – 12.15pm</p>
<p><strong>Session topic:</strong> Openess<br />
<strong>Topic of talk:</strong> Social apps done right</p>
<p><strong>Speaker:</strong><br />
Bastian Hofmann (Software Developer, VZnet Netzwerke Ltd.)<br />
Kristian Raabe (Manager Strategic Partnerships, VZnet Netzwerke Ltd.)</p>
<p><strong>Abstract:</strong><br />
One year ago we were faced with the task of providing an app platform for the 16 million users of our three Social networks studiVZ, meinVZ and schülerVZ. Our aim: to create the best social app platform out there based on OpenSocial. Today, five month after launch, we want to share the story of how we accomplished these aims. We will show how apps are performing on our platform, as well as introduce our plans for further improvements of the developer and user app-experience which are being developed right now.</p>
<p>If you would like to attend, there are still tickets <a href="http://nextconf.eu/next10/tickets.html">available</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/04/28/vz-netzwerke-next-conference-2010/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Label inside – Beschriftung in Formularfeldern</title>
		<link>http://developer.vz.net/2010/04/14/label-inside-%e2%80%93-beschriftung-in-formularfeldern/</link>
		<comments>http://developer.vz.net/2010/04/14/label-inside-%e2%80%93-beschriftung-in-formularfeldern/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 13:04:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[autofocus]]></category>
		<category><![CDATA[Beschriftung]]></category>
		<category><![CDATA[Eingabefeld]]></category>
		<category><![CDATA[input]]></category>
		<category><![CDATA[label]]></category>
		<category><![CDATA[textarea]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2286</guid>
		<description><![CDATA[Dieser Artikel behandelt Eingabefelder, bei denen ihre zugehörige Beschriftung im Eingabefeld selbst angezeigt wird. Es wird eine Alternative zu der problematischen technischen Umsetzung gezeigt, die Beschriftung in den Wert des @value-Attribut des input-Elements bzw. den Inhalt des textarea-Elements zu setzen und per JavaScript aus- und einzublenden: mit dem HTML-Element label, CSS und wenigen Zeilen JavaScript. Auch auf das beim Seitenaufruf automatisch fokussierte Eingabefeld wird eingegangen. <a href="http://developer.vz.net/2010/04/14/label-inside-%e2%80%93-beschriftung-in-formularfeldern/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>(Dies ist eine leicht gekürzte Fassung des Artikels <a href="http://bittersmann.de/articles/label-inside/">Label inside – Beschriftung in Formularfeldern</a>.)</p>
<p>Auf unseren Plattformen verwenden wir an mehreren Stellen Eingabefelder, bei denen ihre zugehörige Beschriftung im Eingabefeld selbst angezeigt wird. Dies ist platzsparend und dem Nutzer können zusätzliche Informationen gegeben werden.</p>
<p>Die technische Umsetzung, die Beschriftung in den Wert des @value-Attribut des input-Elements bzw. den Inhalt des textarea-Elements zu setzen und per JavaScript aus- und einzublenden, ist jedoch problematisch:</p>
<ul>
<li> Beschriftung und wirkliche Nutzereingabe im Feld müssen unterschieden werden; der Textstil (Farbe) muss mit JavaScript geändert werden. Sollen auch vorbelegte Felder verwendet werden, muss die Unterscheidung auch im Markup (HTML) erfolgen.</li>
<li>Wenn das JavaScript zu spät ausgeführt wird, gibt der Nutzer schon etwas ins Feld ein, bevor dessen Beschriftung gelöscht wurde. Dadurch wird der Beschriftungstext unerwünscht zu einem Teil der Eingabe.</li>
</ul>
<p><strong>Lösung mit label</strong></p>
<p><strong>Markup: </strong>Besser realisiert man die Beschriftung mit dem dafür vorgesehenen HTML-Element label. Dieses wird zusammen mit dem Eingabefeld in einem Containerelement der Klasse &#8220;labelinside&#8221; gekapselt. Auch vorbelegte Felder sind möglich:</p>
<pre><code>&lt;p&gt;
  &lt;span class="labelinside"&gt;
    &lt;label for="foo"&gt;Label inside&lt;/label&gt;
    &lt;input id="foo"/&gt;
  &lt;/span&gt;
  &lt;span class="labelinside"&gt;
    &lt;label for="baz"&gt;Label inside&lt;/label&gt;
    &lt;input id="baz" value="vorbelegt"/&gt;
  &lt;/span&gt;
&lt;/p&gt;
&lt;div class="labelinside"&gt;
  &lt;label for="bar"&gt;Label inside&lt;/label&gt;
  &lt;textarea id="bar"&gt;&lt;/textarea&gt;
&lt;/div&gt;
&lt;div class="labelinside"&gt;
  &lt;label for="quz"&gt;Label inside&lt;/label&gt;
  &lt;textarea id="quz"&gt;vorbelegt&lt;/textarea&gt;
&lt;/div&gt;
</code>
</pre>
<p><strong>Stylesheet: </strong>Damit die Beschriftung im Eingabefeld erscheint, wird das label-Element per absoluter Positionierung aus dem Fluss genommen und im Containerelement oben links positioniert. Dazu muss das Containerelement selbst auch positioniert sein:</p>
<pre><code>.labelinside
{
  margin: 3px 0;
  position: relative;
}

.labelinside label
{
  color: silver;
  cursor: text;
  display: none;
  font-size: 0.8em;
  left: 0;
  line-height: 0.8em;
  padding: 6px 3px;
  position: absolute;
  top: 0;
}

.labelinside input,
.labelinside textarea
{
  margin: 0;
}
</code>
</pre>
<p><strong>JavaScript: </strong>Wir verwenden auf unseren Plattformen das jQuery-Framework. Damit lassen sich recht einfach alle input- und textarea-Elemente selektieren, die Kindelemente eines Containerelements der Klasse &#8220;labelinside&#8221; sind. Beim Seitenaufruf sollen die Beschriftungen aller dieser Eingabefelder eingeblendet werden, die nicht vorausgefüllt sind; die anderen bleiben ausgeblendet. Beim Fokussieren eines Eingabefeldes wird dessen Beschriftung   ausgeblendet; beim Verlassen wird dessen Beschriftung eingeblendet, wenn   kein Eingabewert im Feld steht.</p>
<p>Außerdem wird die display-Eigenschaft von inzeiligen Containerelementen auf &#8220;inline-block&#8221; geändert, damit die Beschriftung auch bei diesen passt; dies jedoch nicht für Internet Explorer &lt; 8 (Abfrage per <a href="http://www.javascriptkit.com/javatutors/conditionalcompile.shtml">conditional compilation</a> und <a href="http://aktuell.de.selfhtml.org/weblog/kompatibilitaetsmodus-im-internet-explorer-8">document.documentMode</a>).</p>
<pre><code>var $inputControl = $(".labelinside&gt;input, .labelinside&gt;textarea");

$inputControl.each(function (index, domElement)
{
  /*@cc_on if (document.documentMode &amp;&amp; document.documentMode &gt;= 8) @*/
  if ($(this).parent().css("display") == "inline")
    $(this).parent().css("display", "inline-block");

  if (!$(this).val())
    $(this).parent().children("label").show();
});

$inputControl.bind("focus", function(event)
{
  $(this).parent().children("label").hide();
});

$inputControl.bind("blur", function(event)
{
  if (!$(this).val())
    $(this).parent().children("label").show();
});
</code>
</pre>
<p>Und so sieht’s aus: <a href="http://bittersmann.de/articles/label-inside/example1.html">Beipiel 1</a></p>
<p><strong>Automatisch fokussiertes Eingabefeld</strong></p>
<p>Besondere Beachtung erfordert das beim Seitenaufruf automatisch fokussierte Eingabefeld (HTML5: @autofocus), denn für dieses ist das initiale Ausblenden der Beschriftung nicht ratsam, wenn der Nutzer dadurch keine Information bekommt,  was er in dieses Feld eintragen sollte. Auf unseren Plattformen betrifft dies bspw. das Login-Feld.</p>
<p>Hier wird die Beschriftung  anfangs eingeblendet. Im Internet Explorer ist dabei eine kurze  Verzögerung notwendig (per <a href="http://www.javascriptkit.com/javatutors/conditionalcompile.shtml">conditional  compilation</a> eingebunden, damit die Ausführung in anderen Browsern nicht  verzögert wird). Die Beschriftung wird ausgeblendet, sobald Text eingegeben wird oder  wenn mit der Maus in das Eingabefeld geklickt wird.</p>
<pre><code>var $autofocus = $inputControl.filter("[autofocus]");  // oder Selektion per ID

$autofocus.focus();  // setzt den Fokus auch in Browsern, die @autofocus noch nicht interpretieren

if (!$autofocus.val())
  /*@cc_on setTimeout(function () { @*/
  $autofocus.parent().children("label").show();
  /*@cc_on }, 0); @*/

$autofocus.bind("click", function(event)
{
  $(this).parent().children("label").hide();
});

$autofocus.bind("keyup", function(event)
{
  $(this).parent().children("label").hide();
});
</code>
</pre>
<p>Und so sieht’s aus: <a href="http://bittersmann.de/articles/label-inside/example2.html">Beipiel 2</a></p>
<p><strong>Vorteile dieser Lösung</strong></p>
<p>Bei dieser Lösung genügen wenige Codezeilen für alle Eingabefelder auf einer Webseite. Für neu hinzukommende Eingabefelder ist kein zusätzliches JavaScript erforderlich.</p>
<p>Präsentationsschicht (CSS) und Verhaltensschicht (JavaScript) sind sauber voneinander getrennt. Beschriftung und Nutzereingaben sind sauber voneinander getrennt; eine ungewollte Übernahme des Beschriftungstextes als Eingabe kann nicht erfolgen. Zur Unterscheidung von Beschriftung und Nutzereingaben in den Feldern sind keine Flags oder gar Stringvergleiche des value mit dem (für jedes Eingabefeld anderen) Beschriftungstext erforderlich. Der Stil für den Beschriftungstext steht im Stylesheet; mit JavaScript muss lediglich die Sichtbarkeit geändert werden, nicht jedoch die Textfarbe o.a. Dadurch ist die Lösung nicht nur einfach, sondern auch schnell.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/04/14/label-inside-%e2%80%93-beschriftung-in-formularfeldern/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Announcement: Change of OpenSocial ID Prefix &#8211; Migration plan</title>
		<link>http://developer.vz.net/2010/04/14/announcement-change-of-opensocial-id-prefix-migration-plan/</link>
		<comments>http://developer.vz.net/2010/04/14/announcement-change-of-opensocial-id-prefix-migration-plan/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 08:46:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[Operations]]></category>

		<guid isPermaLink="false">http://developer.studivz.net/?p=2305</guid>
		<description><![CDATA[In order to simplify the communication between app backends and our OpenSocial API and to fix the issue of user migration between studiVZ and meinVZ we are planning to reduce the amount of possible endpoints by one. Therefore, we will &#8230; <a href="http://developer.vz.net/2010/04/14/announcement-change-of-opensocial-id-prefix-migration-plan/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In order to simplify the communication between app backends and our OpenSocial API and to fix the issue of user migration between studiVZ and meinVZ we are planning to reduce the amount of possible endpoints by one.</p>
<p>Therefore, we will change the OpenSocial User ID Prefixes as follows:</p>
<ul>
<li>www.studivz.net:abcdefg → www.vz.net:abcdefg</li>
<li>www.meinvz.net:abcdefg → www.vz.net:abcdefg</li>
<li>www.schuelervz.net:abcdefg → www.schuelervz.net:abcdefg</li>
<li>sandbox.developer.studivz.net:abcdefg → sandbox.developer.studivz.net:abcdefg</li>
</ul>
<p><strong>The ID suffix will not change!</strong></p>
<p>We won&#8217;t change the hostnames of the different endpoints, but if you have an www.vz.net id it won&#8217;t matter if you request the meinVZ or studiVZ endpoint. This means, that the following endpoints are<br />
available:</p>
<ul>
<li>http://meinvz.gadgets.apivz.net/social/rest or http://studivz.gadgets.apivz.net/social/rest </li>
<li>http://schuelervz.gadgets.apivz.net/social/rest </li>
<li>http://sandbox.gadgets.apivz.net/social/rest </li>
<li>http://meinvz.gadgets.apivz.net/social/rpc or http://studivz.gadgets.apivz.net/social/rpc </li>
<li>http://schuelervz.gadgets.apivz.net/social/rpc </li>
<li>http://sandbox.gadgets.apivz.net/social/rpc </li>
</ul>
<p>Our migration plan has two steps:</p>
<p><strong>April, 13th – May, 18th:</strong><br />
While we still send the old OpenSocial Ids  in our requests to your backend an in our API responses, our REST and RPC API will accept both old and new Ids as request parameters. In this timeframe you have to change your backend, to replace the old prefix with the new prefix in all our requests and responses (see example code below) and only store the new ids in your database.</p>
<p><strong>May, 18th:</strong><br />
We will start sending out the new ids in our requests to your backend in in our API responses. Your backend should be ready for this after phase one, because while the replace logic is still applied to every request and response, it won&#8217;t find any matches. You can now remove this replace logic from your backend if you want.</p>
<p><strong>Example source code for replacement logic:</strong></p>
<p>When your backend receives request from the gadget (makeRequest):</p>
<p><code>$viewerId = str_replace('www.studivz.net', 'www.vz.net', $_GET['opensocial_viewer_id']);<br />
$viewerId = str_replace('www.meinvz.net', 'www.vz.net', $_GET['opensocial_viewer_id']);<br />
$ownerId = str_replace('www.studivz.net', 'www.vz.net', $_GET['opensocial_owner_id']);<br />
$ownerId = str_replace('www.meinvz.net', 'www.vz.net', $_GET['opensocial_owner_id']);</code></p>
<p>When your backend receives a response from our REST or RPC API (example for receiving a list of users):</p>
<p><code>foreach ($decodedResponse['entry'] as $id =&gt; $user) {<br />
  $decodedResponse['entry'][$id]['id'] = str_replace('www.studivz.net', 'www.vz.net', $decodedResponse['entry'][$id]['id'])<br />
 $decodedResponse['entry'][$id]['id'] = str_replace('www.meinvz.net', 'www.vz.net', $decodedResponse['entry'][$id]['id'])<br />
}</code></p>
<p>If you are a developer and have an app live, that has its own backend, you will be contacted in the next days by our support team in order to coordinate your personal migration process.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.vz.net/2010/04/14/announcement-change-of-opensocial-id-prefix-migration-plan/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
