Par Nicolas,
vendredi 27 octobre 2017 à 23:59 ::geek stuff
Const - block scoped - better than var which has a global scope
Types - boolean, number, string, symbol, null, undefined
type inference : const tax = 20;
6) improve the range from 10cm to 100m by plugging a piece of wire in the 4th GPIO pin. I took an old headset, cut at both ends, plugged. no soldering needed, google to find which GPIO is the 4th one.
7) replace the bbc stream with France Info or France Inter or whatever stream : France Bleu Breizh, Tendance Ouest Rouen, Kiss FM dance or whatever obscure campus radio that streams on internet. Yay.
http://www.listenlive.eu/france.html
8) play your mp3s in the house
sox -v .9 -t mp3 ./someCrap.mp3 -t wav -r 22050 -c 1 - | sudo /home/pi/pifm/pifm - 100
Par Nicolas,
jeudi 15 décembre 2011 à 05:05 ::geek stuff
Define a service to expose logic.
Expose the interface to this logic at a certain endpoint, certain channel (in our case BasicHTTPBinding).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using DM.PetShop;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// service relies on an implementation
ServiceHost host = new ServiceHost(typeof(OrderService));
// service is exposed through the intreface (i.e. contract)
host.AddServiceEndpoint(typeof(IOrderContract), new BasicHttpBinding(), "http://localhost:9000/PetShop");
// open the service ("fire and forget" call)
host.Open();
// make sure the service doesn't die and print status
Console.Title = String.Format("{0} is running ...", host.Description.Endpoints[0].Address);
Console.Write("Server started. Press enter to stop...");
Console.ReadLine();
// close after receiving a keystroke
host.Close();
Console.WriteLine("Server stoppped. Press enter to quit...");
Console.ReadLine();
}
}
}
Here is the contract (a.k.a. interface) that will be exposed to the world
Here the implementation (note the annotations,most important part)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace DM.PetShop
{
[ServiceBehavior(Name = "DM.PetShop.OrderService", Namespace = Constants.SERVICE_NAMESPACE)]
public class OrderService : IOrderContract
{
public void PlaceOrder(string orderData)
{
Console.WriteLine("Diagnostic message !");
}
}
}
Then write a client :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using IOrderContractChannelFactory = System.ServiceModel.ChannelFactory;
using DM.PetShop;
namespace Project_Client1
{
class Client1App
{
static void Main(string[] args)
{
IOrderContractChannelFactory factory = new IOrderContractChannelFactory(new BasicHttpBinding());
IOrderContract channel = factory.CreateChannel(new EndpointAddress("http://localhost:9000/PetShop/"));
channel.PlaceOrder("1 parrot");
IClientChannel clientChannel = (IClientChannel)channel;
try
{
if (clientChannel.State != CommunicationState.Closed)
clientChannel.Close();
}
catch
{
clientChannel.Abort();
}
}
}
}
Par Nicolas,
mercredi 14 décembre 2011 à 10:53 ::geek stuff
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Threading;
using System.Collections.Generic;
using System.Diagnostics;
///
/// Summary description for JokeServer
///
public static class MOTDServer
{
static Queue MessageQueue = new Queue();
static Random rng = new Random();
static Thread ProducerThread;
static string[] Messages =
{
"A bird in the hand is worth two in the bush",
"A rolling stone gathers no moss",
"A penny saved is a penny earned",
"I'd rather have a bottle in front of me than a frontal lobotomy",
"When life hands you lemons, make lemonade"
};
private static void Init()
{
ProducerThread = new Thread(ProduceMessages);
ProducerThread.Priority = ThreadPriority.Lowest;
ProducerThread.Start();
}
public static string GetNextMessage()
{
if (ProducerThread == null)
Init();
string retval = null;
Monitor.Enter(MessageQueue);
while(MessageQueue.Count == 0)
Monitor.Wait(MessageQueue);
retval = MessageQueue.Dequeue();
Monitor.Exit(MessageQueue);
return retval;
}
static void ProduceMessages()
{
for (; ; )
{
if (MessageQueue.Count == 0)
{
Monitor.Enter(MessageQueue);
MessageQueue.Enqueue(Messages[rng.Next(Messages.Length)]);
Monitor.Pulse(MessageQueue);
Monitor.Exit(MessageQueue);
}
Thread.Sleep(rng.Next(5000) + 2000);
Debug.WriteLine("finished waiting");
}
}
}
Par Nicolas,
mercredi 14 décembre 2011 à 05:19 ::geek stuff
// define the delegate needed for async calls below
delegate List GetQuoteDelegate(DateTime dt);
// Use Async invocation to request the quotes in parallel
List[] GetQuotes(DateTime dt)
{
ReservationServices reservationService = new ReservationServices();
List[] retval = new List[3];
List getQuoteDelegates = new List();
getQuoteDelegates.Add(reservationService.GetAirlineQuotes);
getQuoteDelegates.Add(reservationService.GetCarRentalQuotes);
getQuoteDelegates.Add(reservationService.GetHotelQuotes);
CountdownEvent cde = new CountdownEvent(3);
for(int i=0; i<3; i++)
{
int localI = i;
GetQuoteDelegate getQuoteDelegate = getQuoteDelegates[i];
getQuoteDelegate.BeginInvoke(dt,
iar => {
retval[localI] = (List)getQuoteDelegate.EndInvoke(iar);
cde.Signal();
},
null
);
}
// wait for all to be finished
cde.Wait();
return retval;
}
Par Nicolas,
lundi 12 décembre 2011 à 08:48 ::geek stuff
Material : tinyurl.com/89 sj qvn
Iterators and anonymous methods
- yield keyword
- internal and external iterations
- anonymous methods : for throwaway methods ...
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
foreach (int i in DivisibleBy(0, 50, 5))
{
Console.WriteLine(i);
}
}
static IEnumerable DivisibleBy(int min, int max,int divisor) {
for (int i = min; i < max; i++)
{
if (i % divisor == 0) {
yield return i;
}
}
}
}
class X_Enumerable : IEnumerable {
private int min;
private int max;
private int divisor;
public X_Enumerable(int min, int max, int divisor)
{
this.min = min;
this.max = max;
this.divisor = divisor;
}
public IEnumerator GetEnumerator() {
return new X_Enumerator(min, max, divisor);
}
}
class X_Enumerator : IEnumerator
{
int min;
int max;
int divisor;
int current;
public X_Enumerator(int min, int max,int divisor)
{
this.min=min;
this.max = max;
this.divisor = divisor;
}
public Object Current
{
get { return current; }
}
public bool MoveNext()
{
this.current++;
while (current % divisor != 0) {
this.current++;
if (current == max) {
return false;
}
}
return true;
}
public void Reset()
{
this.current=min;
}
public void Dispose()
{
throw new NotImplementedException();
}
}
}
LINQ to Objects
- anonymous types :
var p = new { Name = "Andy", Age = 21 };@@
using System;
using System.Collections.Generic;
using System.Text;
namespace LINQBase
{
class Program
{
static void Main(string[] args)
{
var people = new List();
people.Add(new Person { Name = "Nick", Height = 1.30m });
people.Add(new Person { Name = "Jay", Height = 1.80m });
people.Add(new Person { Name = "Bob", Height = 2.30m });
foreach (var littlePerson in people.Where(p => p.Height < 2))
{
Console.WriteLine(littlePerson.Name);
}
}
}
public class Person
{
public decimal Height { get; set; }
public string Name { get; set; }
}
public static class Utils {
public static IEnumerable Where(this IEnumerable items, Predicate condition)
{
foreach (T item in items)
{
if (condition(item))
yield return item;
}
}
}
}
LINQ to XML
CLR via C#, Second EditionJeffrey Richter.Net 2.0.Net General
http://www.amazon.com/gp/product/0735621632/sr=8-1/qid=1141842947/ref=pd_bbs_1/103-3403410-7338268?_encoding=UTF8
35.99Creating Workflow Services and Durable Services (MSDN)Anonymous.Net 3.5Service Composition
http://msdn2.microsoft.com/en-us/library/bb412181.aspx
0.0Data Binding with Windows Forms 2.0Brian Noyes.Net 2.0Windows Forms
http://www.amazon.com/Data-Binding-Windows-Forms-2-0/dp/032126892X/ref=pd_bxgy_b_img_b
32.99Essential ASP.NET 2.0Fritz OnionKeith Brown.Net 2.0Web Apps
http://www.amazon.com/Essential-ASP-NET-2-0-Fritz-Onion/dp/0321237706/ref=pd_bbs_sr_1/103-2749730-3599818?ie=UTF8&s=books&qid=1176902837&sr=8-1
36.99Essential ASP.NET With Examples in C#Fritz Onion.Net 2.0Web Apps
http://www.amazon.com/Essential-ASP-NET-Examples-Fritz-Onion/dp/0201760401/ref=pd_bbs_sr_2/103-2749730-3599818?ie=UTF8&s=books&qid=1176902837&sr=8-2
31.49Essential C# 2.0Mark Michaelis.Net 2.0C# Language
http://www.amazon.com/Essential-2-0-Microsoft-NET-Development/dp/0321150775/ref=pd_bxgy_b_text_b/102-4792916-8428135?ie=UTF8&qid=1174210886&sr=1-2
37.79Essential Windows Presentation FoundationChris Anderson.Net 3.0Presentation Foundation
http://www.amazon.com/Essential-Presentation-Foundation-Microsoft-Development/dp/0321374479/ref=sr_1_1/002-9650384-5136050?ie=UTF8&s=books&qid=1188296520&sr=8-1
31.49Essential Windows Workflow FoundationDharma ShuklaBob Schmidt.Net 3.0Workflow Foundation
http://www.amazon.com/Essential-Workflow-Foundation-Microsoft-Development/dp/0321399838/ref=pd_bbs_sr_1/102-1611469-3153757?ie=UTF8&s=books&qid=1192436658&sr=8-1
31.49Learning WCFMichele Bustamante.Net 3.0Communication Foundation
http://www.amazon.com/Learning-WCF-Hands-Michele-Bustamante/dp/0596101627/ref=pd_bbs_sr_1/103-2749730-3599818?ie=UTF8&s=books&qid=1176904112&sr=8-1
29.69LINQ in ActionFabrice MarguerieSteve EichertJim Wooley.Net 3.5LINQ
http://www.amazon.com/LINQ-Action-Fabrice-Marguerie/dp/1933988169/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1202326210&sr=1-1
29.69Programming .NET Components, 2nd EditionJuval Lowy.Net 2.0.Net General
http://www.amazon.com/gp/product/0596102070/ref=pd_kar_gw_1/103-3403410-7338268?_encoding=UTF8&v=glance&n=283155
29.67Programming WCF ServicesJuval Lowy.Net 3.0Communication Foundation
http://www.amazon.com/Programming-WCF-Services-Juval-Lowy/dp/0596526997/ref=pd_bbs_sr_1/102-1611469-3153757?ie=UTF8&s=books&qid=1192436749&sr=8-1
29.69Programming Windows Workflow FoundationK. Scott Allen.Net 3.0Workflow Foundation
http://www.amazon.com/Programming-Windows-Workflow-Foundation-Techniques/dp/1904811213/ref=sr_1_1/102-1611469-3153757?ie=UTF8&s=books&qid=1192436585&sr=8-1
44.99Smart Client Deployment with ClickOnceBrian Noyes.Net 2.0Windows Forms
http://www.amazon.com/Smart-Client-Deployment-ClickOnce-Applications/dp/0321197690/ref=pd_bbs_sr_1/102-5394843-6848112?ie=UTF8&s=books&qid=1175345601&sr=8-1
29.69Understanding Windows CardSpaceVittorio BertocciGarrett SerackCaleb Baker.Net 3.0CardSpace
http://www.amazon.com/Understanding-Windows-CardSpace-Introduction-Independent/dp/0321496841/ref=sr_1_1/102-1611469-3153757?ie=UTF8&s=books&qid=1192436821&sr=8-1
32.84Windows Forms 2.0 Programming (2nd Edition)Chris SellsMichael Weinhardt.Net 2.0Windows Forms
http://www.amazon.com/gp/product/0321267966/qid=1141845579/sr=1-1/ref=sr_1_1/103-3403410-7338268?s=books&v=glance&n=283155
32.39Windows Presentation Foundation UnleashedAdam Nathan.Net 3.0Presentation Foundation
http://www.amazon.com/Windows-Presentation-Foundation-Unleashed-WPF/dp/0672328917/ref=pd_bbs_sr_1/103-2749730-3599818?ie=UTF8&s=books&qid=1176903814&sr=8-1
34.49
public class Book
{
// Book properties
public string Category { get; set; }
public string Topic { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public string[] Authors { get; set; }
public string WebSite { get; set; }
// Book description
public override string ToString()
{
string output = string.Format("{0} by {1}",
Title, string.Join(", ", this.Authors));
output += string.Format(" {0} {1} {2}",
Category, Topic, Price.ToString("c"));
return output;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace LinqToXmlLab
{
static class RssFeed
{
public static XElement GetBooksXml(string url)
{
XElement xml = XElement.Load(url);
return xml;
}
public static List GetBooks(XElement xml)
{
XNamespace ns = "http://develop.com";
IEnumerable booksQuery = from b in xml.Elements(ns + "book") select
new Book { Title = (string)b.Element(ns + "title"),
Category = (string)b.Element(ns + "category"),
Topic = (string)b.Element(ns+"topic"),
Price = (decimal)b.Element(ns + "price"),
WebSite = (string)b.Element(ns + "link"),
Authors = (from a in b.Element(ns + "authors").Elements(ns + "author") select (string)a).ToArray()
};
return booksQuery.ToList();
}
public static XElement GetFeedXml(List books) {
XElement xml = new XElement("rss",
new XAttribute("version", "2.0"),
new XElement("channel",
new XElement("title", "Essential .Net Reading"),
new XElement("link", "http://localhost:12345/books/"),
new XElement("description", ".Net developer reading"),
from b in books orderby b.Category, b.Topic, b.Title select new XElement(
"item",
new XElement("title", b.Title),
new XElement("link", b.WebSite),
new XElement("description", b))));
return xml;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml.Linq;
namespace LinqToXmlLab
{
class Program
{
static void Main(string[] args)
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://localhost:12345/books/");
listener.Start();
Console.WriteLine("Rss Feed Service is running");
Console.WriteLine("Press Ctrl+C to terminate ...");
while (true)
{
HttpListenerContext ctx = listener.GetContext();
using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream))
{
// Load xml from file
string url = @"..\..\books.xml";
XElement booksXml = RssFeed.GetBooksXml(url);
// Get books list
List books = RssFeed.GetBooks(booksXml);
// Convert books list to xml
XElement feedXml = RssFeed.GetFeedXml(books);
// Send xml to the reponse stream
writer.Write(feedXml);
}
}
}
}
}
Par Nicolas,
lundi 20 juin 2011 à 11:27 ::geek stuff
XAML, WPF and converters
Write a stupid app that has 2 text boxes, each time a number is entered in the first, the second receives the double, and the first should as well reflect the second one if the second is changed.
Par Nicolas,
lundi 6 juin 2011 à 16:15 ::geek stuff
I'm getting serious about C# and had a course today on the basics :
- C# overview
- Visual Studio
- Projects and assemblies
- Collections
- Generics
We were finally given 2 exercises.
Par Nicolas,
mardi 23 juin 2009 à 09:33 ::geek stuff
Weather is quite bad here in Zürich but well, I don't
mind too much as I'll be attending Jazoon, THE java dev conference in Europe.
I'll be blogging mainly for my employer but I'll tweet
a lot, stay tuned : http://twitter.com/#search?q=Jazoon
Right now, opening keynote by James Gosling !
Edit 12:10 James Gosling's keynote was excellent, presenting shocking numbers and funny projects, in a nutshell :
10 billions Java enabled devices in the world (yes billions)
15 millions downloads of the JRE Java Runtime Environment a week
www.lincvolt.com project transforming a 6000 pounds lincoln car into an electric car, power management done by Java o' course
Then James did a little demo of the 2 ground breaking features of Java EE6, annotated servlets and EJB injection in servlets. I knew already about it, but it remains extremely handy and simplifies the EE development a great deal !
The talk closed with a little Java FX note and the future of computers, heading to massively parrallel computing instead of increasing GHz on single cores.
Afternoon sessions i attended were "RIA, security broken by design" and "JSF and Ajax @ Credit Suisse", quite obvious for the second one !
The RIA session was mostly about demoing XSS attacks and why using a framework is a good idea to enhance the security, nothing much.
On the other hand, the CS-Jsf and Ajax session by Micha Kiener was extremely interesting and will hopefully impact my daily work as of Q3 2009. (Wait a minute Q3, really?).
D'un point de vue pragmatique, j'aurais plus comparé des frameworks dans un premier temps. Applet, par exemple n'en a pas à ma connaissance, il faudra tout programmer de A à Z, et comprendre les détails de la techno. Pour faire une RIA, ça va être long. Très long. Personne ne fait ça, c'est clair.
Ajax, à l'opposé dispose de très nombreux frameworks qui permettront d'aller directement à l'essentiel.
style de développement identique aux applis non Ajax (tags générant du HTML et du JS)
dépendance accrue entre les widgets et la techno serveur
Dans la mesure ou l'on parle d'un business model de développement en interne, les coûts vont être pour 0.2 dans le dev et 0.6 dans la maintenance (licences, serveurs etc sont probablement négligeables).
Avec la mobilité permanente des développeurs, investir dans une techno jeune et très marketée comme Ajax, c'est s'assurer une certaine perennité et des coûts de maintenance bas. Qui ne connait pas Ajax dans le principe...
A l'inverse, quel développeur veut marquer sur son cv "2008-2010 : développement d'applets".
Pour Flex, comme toute techno propriétaire, les ressources de dév et maintenance coûteront plus chers "par tête", mais seront probablement plus productives, de par l'intégration et la qualité de l'outillage.
Pour revenir au concret, mes récentes tentatives avec JSF puis iceFaces ont été bien accueillies par les développeurs (Ajax framework de .Net pour les Microsoft boys). Solutions maintenant éprouvées, légères, qui couvrent la majorité des besoins, simples à maintenir dans le sens ou elles sont standard.
Applets? Plusieurs legacy en ont, et c'est un véritable cauchemar en maintenance...
Allez un peu de recherche sur JavaFX maintenant !
Par Nicolas,
lundi 5 janvier 2009 à 16:20 ::geek stuff
/*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
public class InstallCert {
public static void main(String[] args) throws Exception {
String host;
int port;
char[] passphrase;
if ((args.length == 1) || (args.length == 2)) {
String[] c = args[0].split(":");
host = c[0];
port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
String p = (args.length == 1) ? "changeit" : args[1];
passphrase = p.toCharArray();
} else {
System.out
.println("Usage: java InstallCert [:port] [passphrase]");
return;
}
File file = new File("jssecacerts");
if (file.isFile() == false) {
char SEP = File.separatorChar;
File dir = new File(System.getProperty("java.home") + SEP + "lib"
+ SEP + "security");
file = new File(dir, "jssecacerts");
if (file.isFile() == false) {
file = new File(dir, "cacerts");
}
}
System.out.println("Loading KeyStore " + file + "...");
InputStream in = new FileInputStream(file);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(in, passphrase);
in.close();
SSLContext context = SSLContext.getInstance("TLS");
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
X509TrustManager defaultTrustManager = (X509TrustManager) tmf
.getTrustManagers()[0];
SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
context.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory factory = context.getSocketFactory();
System.out
.println("Opening connection to " + host + ":" + port + "...");
SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
socket.setSoTimeout(10000);
try {
System.out.println("Starting SSL handshake...");
socket.startHandshake();
socket.close();
System.out.println();
System.out.println("No errors, certificate is already trusted");
} catch (SSLException e) {
System.out.println();
e.printStackTrace(System.out);
}
X509Certificate[] chain = tm.chain;
if (chain == null) {
System.out.println("Could not obtain server certificate chain");
return;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
System.out.println();
System.out.println("Server sent " + chain.length + " certificate(s):");
System.out.println();
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
MessageDigest md5 = MessageDigest.getInstance("MD5");
for (int i = 0; i < chain.length; i++) {
X509Certificate cert = chain[i];
System.out.println(" " + (i + 1) + " Subject "
+ cert.getSubjectDN());
System.out.println(" Issuer " + cert.getIssuerDN());
sha1.update(cert.getEncoded());
System.out.println(" sha1 " + toHexString(sha1.digest()));
md5.update(cert.getEncoded());
System.out.println(" md5 " + toHexString(md5.digest()));
System.out.println();
}
System.out
.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
String line = reader.readLine().trim();
int k;
try {
k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
} catch (NumberFormatException e) {
System.out.println("KeyStore not changed");
return;
}
X509Certificate cert = chain[k];
String alias = host + "-" + (k + 1);
ks.setCertificateEntry(alias, cert);
OutputStream out = new FileOutputStream("jssecacerts");
ks.store(out, passphrase);
out.close();
System.out.println();
System.out.println(cert);
System.out.println();
System.out
.println("Added certificate to keystore 'jssecacerts' using alias '"
+ alias + "'");
}
private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
private static String toHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * 3);
for (int b : bytes) {
b &= 0xff;
sb.append(HEXDIGITS[b >> 4]);
sb.append(HEXDIGITS[b & 15]);
sb.append(' ');
}
return sb.toString();
}
private static class SavingTrustManager implements X509TrustManager {
private final X509TrustManager tm;
private X509Certificate[] chain;
SavingTrustManager(X509TrustManager tm) {
this.tm = tm;
}
public X509Certificate[] getAcceptedIssuers() {
throw new UnsupportedOperationException();
}
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
throw new UnsupportedOperationException();
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
this.chain = chain;
tm.checkServerTrusted(chain, authType);
}
}
}
Par Nicolas,
jeudi 4 septembre 2008 à 09:29 ::geek stuff
J'ai commençé un peu à tester le nouveau browser, nos amis canadiens diraient "butineur" ou navigateur, et la rapidité de chargement des pages est tout simplement incroyable.
Comme d'habitude chez google la version mac est en retard, mais je l'attend avec impatience.
Les grosses différences avec Firefox (le seul browser crédible sur cette terre avec Safari) sont
la présence des onglets non plus sous la barre d'adresse mais tout en haut de l'interface
l'incroyable rapidité
la promesse (il faut tester) de ne jamais rester bloqué sur un onglet mort
les onglets "détachables"
Les techies ont produit une petit bande dessinée dans le pur esprit google, amusante, sympathique et assez technique. Allez testez le !
This configuration will create at runtime a Properties object and fill it with the properties contained in sapconnection.properties.
Then i just have to inject this bean in a containing bean, which has indeed a member such as described below :
private Properties SAPconnectionProperties;
And appropriate getter and setter of course...
Par Nicolas,
mardi 27 mai 2008 à 17:46 ::geek stuff
Dans le fichier de configuration web.xml de notre application, il est possible de déclarer des éléments "listener". Que font-ils? Comment Spring s'initialise grâce à eux?
Une classe listener implémenter l'une des deux super classe suivantes :
ServletContextListener
HttpSessionListener
Dans le premier cas, il faudra obligatoirement implémenter la méthode suivante :
public void contextInitialized(ServletContextEvent ce)
Dans le second cas, il faudra implémenter entre autres :
ublic void sessionCreated(HttpSessionEvent se)
A quoi tout cela peut il bien servir?
Oui exact, c'est ça, on obtient tout simplement ce qu'on appelle un hook sur les événements suivants (respectivement) :
création d'un ServletContext
création d'une session
Revenons en à Spring. Dés que l'application est démarrée, il nous faut le fameux "ApplicationContext Spring".
Très simplement, on va choisir de démarrer ce dernier par le biais d'une classe listener, qui sera déclarée dans le fichier web.xml comme suit :
Et bien sûr il existe une configuration par défaut pour le nom de fichier. S'il est déclaré comme suit, le listener le trouvera sans plus de configuration : <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/applicationContext.xml, /WEB-INF/classes/resources.xml</param-value> </context-param>
Voila voila...(A noter qu'en fait, petit malin, j'ai passé deux fichiers de config).
Par Nicolas,
vendredi 28 mars 2008 à 15:20 ::geek stuff
4 authentication methods to identify a user with JAAS over HTTP
basic authentication : the popup asking for login/password, not encrypting anything
digest-authentication : same as basic, with password encryption. Not a really nice user experience (login popups remind of the 90's )
certificate based authentication : HTTPS, using SSL, secured socket layer. first the usual PKI handshake (asymetric encryption) then the usual symetric encryption for performance. (A variant of this authentication is also managed for installations providing users PKI certificates, chip card format for example)
form based authentication, the usual HTML form...
How do i do that?
-> form based authentication, most often used :
add a security constraint and a security role in web.xml :
<security-constraint> <web-resource-collection> <web-resource-name>All JSP direct access</web-resource-name> <url-pattern>private/*</url-pattern> <http-method>POST</http-method> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <description> No Access </description> <role-name>restricted</role-name> </auth-constraint> </security-constraint>
Par Nicolas,
jeudi 14 février 2008 à 15:22 ::geek stuff
Un objet Collection modélise tout groupe d'objets Java.
Collection est une interface générale qui définit les méthodes suivantes :
public boolean add(Object o); public boolean addAll(Collection<? extends Object> c); public void clear(); public boolean contains(Object o); public boolean containsAll(Collection<?> c); public boolean isEmpty(); public Iterator<Object> iterator(); public boolean remove(Object o); public boolean removeAll(Collection<?> c); public boolean retainAll(Collection<?> c); public int size(); public Object toArray(); public <T> T toArray(T a);
Objet référençant des paires clés-valeurs. Evidemment, il n'est pas possible de dupliquer un clé.
A noter, la Map modélise l'abstraction mathématique connue sous le nom de fonction...Voila.
Performance analogues aux hashsets...
HashMap<K, V>
LinkedHashMap<K, V>
TreeMap<K, V>
HashTable a été revue pour implémenter l'interface.
Chacune des implémentation de List, Map et Set ont leurs avantages et leurs inconvénients, et c'est au développeur de choisir celle qui répond le mieux à ses besoins, dans un cadre de performance, optimisation de la consommation mémoire ou CPU...
Et les bon vieux tableaux? Non. Ils n'implémentent pas Collection. Il existe cependant une passerelle, la méthode toArray().
Par Nicolas,
mercredi 30 janvier 2008 à 16:43 ::geek stuff
Cette transformation peut être adaptée à souhait selon le but.
Dans la majorité des cas, migration de données, XML vers XML, avec une structure différente, ou encore pour éliminer du contenu sans information (tags inutiles etc.).
Par Nicolas,
mardi 15 janvier 2008 à 09:20 ::geek stuff
La librairie "Jakarta HTTP components" du projet Apache fournit de nombreux utilitaires pour construire simplement des requêtes HTTP, simuler un proxy ou encore intégrer du HTTP dans un client lourd.
Par Nicolas,
jeudi 6 décembre 2007 à 10:55 ::geek stuff
Bon. On a besoin de tester un produit dont la license est limitée à l'usage sur l'hôte localhost? Bon. Une petite manip simple peut nous aider à le tester quand même sur des hôtes distants.
Il suffit en fait d'ouvrir un port d'écoute localement (comme le fait tout serveur) par exemple le port XXX. Bon. On lie ensuite ce port via une connection distante sur le protocole ssh à la machine distante. Et le tour est joué. Le navigateur demande l'url localhost port XXX : http://localhost:XXX et le système d'exploitation sait qu'il faut alors faire suivrela demande à la machine distante via la connection ssh préalablement ouverte...
Mais ça le browser n'en a pas connaissance. Il croit que le serveur contacté est bien local. Magie.
Donc la commande magique pour ouvrir le port local vers le port distant via ssh : ssh –L local_port: remote_machine_name:remote_port login@remote_machine_name
Par Nicolas,
mardi 4 décembre 2007 à 11:52 ::geek stuff
Configuration(s) de JNDI
Tomcat offre un service de nommage JNDI, par webapp depuis la version 5.5.
Comment le configurer et y accéder?
Il faut, si l'on veut insérer une information dans le context général, commun à toutes les applications tournant sur le serveur, ajouter les lignes suivantes dans $TOMCAT_HOME/conf/context.xml : (exmple pour une datasource)
Si l'on veut restreindre l'acessibilité du contexte à une application web, il suffit de créer un fichier context.xml contenant les lignes ci-dessus (dans un tag <context></context>) dans le répertoire META-INF de la webapp et de déployer sous forme d'archive web (war).
On accédera ensuite à l'objet avec un code de type
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
if (envCtx == null)
throw new Exception("Boom - No Context");
DataSource ds = (DataSource) envCtx.lookup("jdbc/TestDB");
if (ds != null) {
Connection conn = ds.getConnection();
// etc etc...
A noter que le registre JNDI de Tomcat est readonly, il n'est donc pas modifiable par programmation. On ne peut le configurer qu'au démarrage du serveur ou lors du déploiement d'une application...
Les "resources factories" proposées par Tomcat
Donc non seulement le service JNDI de Tomcat nous a permis de référencer une source de données, nous permettant ainsi de nous affranchir d'un nommage (et d'un paramétrage) dans l'application elle même, mais en plus, comme on le voit dans le code ci-dessus, Tomcat nous simplifie encore une étape en construisant pour nous l'objet Java Datasource directement, sur la base des infos JNDI.
Tomcat dispose en effet de "ressources factories", dans le cas ci-dessus, nous avons utilisé la "datasource factory". Ok quelles sont les autres?
De base, Tomcat fournit les factories suivante :
JDBC datasource factory
Javamail session factory
Javabean factory (similaire à Spring, en un sens)
On peut ensuite intégrer sa propre factory d'objet à Tomcat si l'on en ressent le besoin, une custom factory en fait...
Plus ici.
Par Nicolas,
vendredi 30 novembre 2007 à 14:38 ::geek stuff
HSQLDB est un SGBD (systême de gestion de base de données) qui offre une alternative simplifiée pour le prototypage et le développement rapide d'application.
Ô joie, un client qui permet de se connecter à la base et de regarder un peu ce qu'il s'y passe est livré avec. Plus besoin de télécharger Squirrel SQL, le driver JDBC pour HSQL...Déja 20 minutes de gagnées.
Bref, on télécharge ici : http://hsqldb.org/, on dézippe, et on copie le jar nommé hsqldb.jar contenu dans le dossier lib de notre projet.
Ensuite, on peut lancer le serveur HSQL à la ligne de commande :
java -classpath lib/hsqldb.jar org.hsqldb.Server
Ou si on est un inconditionnel de Ant : <java classname="org.hsqldb.Server" fork="yes"> <classpath> <fileset dir="./lib" includes="*.jar"/> </classpath> </java>
Log de démarrage classique...
Ensuite on peut démarrer le client pour passer des commandes SQL :
java -classpath lib/hsqldb.jar org.hsqldb.util.DatabaseManager -driver org.hsqldb.jdbcDriver -url jdbc:hsqldb:hsql://localhost/ -user sa
Par Nicolas,
vendredi 23 novembre 2007 à 09:48 ::geek stuff
In the old Unix world, a huge toolset was used to trace, optimize, analyze the software behavior.
With Java, you might easily use the wrong implementation of an API thus getting lousy performance. Or you might just write crappy/unadapted/inefficient code (What?).
Sun's JVM's offer a way to track performance bottlenecks in various ways, with the java option HPROF. Some examples :
Before :
Par Nicolas,
mercredi 7 novembre 2007 à 07:52 ::geek stuff
cette n-ième nouvelle méthode de développement logiciel a le mérite d'apporter des réponses concrêtes à des problèmes récurrents sur les projets de taille moyenne et grande : l'intégration, le travail en groupe, les spécifications/expressions de besoins, la documentation...
This ant task, however, needs additional libs : check for the keyword scp here...
Afterwards, if you use Eclipse to run ant, you need to do the following :
Go into Eclipse then click on Window->Preferences->ant->Runtime, then select 'Ant Home Entries (Default). Click on the button 'Add External JARs'. Locate the jar file you copied, select it and hit 'OK'.
Need to tell Ant about the proxy? set ANT_OPTS=-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=3128
Par Nicolas,
jeudi 4 octobre 2007 à 13:17 ::geek stuff
Sunrise, opérateur télécom actif depuis une dizaine d'année sur le marché Suisse, livre son nouveau magasin en ligne
La mission a été longue mais tout se termine dans les temps, nous sommes passé en production depuis ce matin !
Le shop est consultable par tous à l'adresse suivante : https://eshop.sunrise.ch/
Le site est entièrement disponible en 3 langues, Allemand, Français et Italien, il permet de commander des forfaits, des téléphones mobiles ainsi que des cartes pour se connecter à internet par le réseau mobile de Sunrise.
Par Nicolas,
mardi 26 juin 2007 à 09:35 ::geek stuff
don't use public attributes, use getters and setters
This can be read everywhere and everybody knows that. But why? What is the reason behind that? Well...
It's because you don't want people to flatten your cat.
Ok here is your code : public class Cat { public int size; }
And here is your buddy's code : public static void main(String args) { Cat myCat = new Cat(); myCat.size = 0; }
Here we are. Now the poor cat looks like a pile of pancake. Weight watchers pancakes even.
The goal of writing getters and setters (right names for these actually being accessors and mutators, but who cares) is to protect the cat from the being flattened :
public class Cat { private int size; public int getSize() { return size; } public void setSize(int size) { if(size > 5) this.size = size; } }
The cat cannot be flattened. The size attribute is private and can be changed only via the setter.
This concept seems pretty straightforward. However, it is one of the main reason the 3 tiers architecture is so successful these days :
View <-> Business comps <-> Data
Instead accessing the data directly, you have to use the business components to modify the data, and those business components contain the business rules and prevent some crazy things to happen on the data !
Par Nicolas,
vendredi 8 juin 2007 à 10:15 ::geek stuff
Un petit outil bien pratique vient avec Cygwin, curl.
Celui-ci permet d'afficher le code HTML d'une page web par exemple. Utile si on veut tester qu'on a accès à internet via Cygwin, et que ping est...interdit !
Pourr setter le proxy dans Cygwin ou dans toute console tournant sous Windows, il faut setter la variable http_proxy :
export http_proxy="monproxy.net:8080"
Après quoi :
curl http://www.google.fr retourne le code HTML de la page de garde de Google...
Voila. Maintenant, rien à voir, les stats du blog :
Par Nicolas,
dimanche 18 mars 2007 à 15:49 ::geek stuff
Build an iso file from a cd/dv/usb key/directory
check the mounted medias : diskutil list
unmount the media : diskutil unmountDisk /dev/disk1
extract the iso file : dd if=/dev/disk1 of=my_file.iso bs=2048
Burn the iso file on a cd/dvd :
hdiutil burn my_file.iso
Usb key / SD card :
diskutil list to identify where the key is
Go to the disk utility in Apps -> Utilities and unmount all partitions of this usb key
dd if=myiso.iso of=/dev/dikSomething
Done...
Par Nicolas,
mercredi 21 février 2007 à 09:24 ::geek stuff
Under which conditions is my XML document valid?
the document validates the xml formatting rules :
XML documents must have a root element
XML elements must have a closing tag
XML tags are case sensitive
XML elements must be properly nested
XML attribute values must always be quoted
check everything regarding your XML document syntax with this online validator
the document validates against the DTD !
What are XML data islands?
Data islands are a way to introduce xml data in an HTML document in Internet Explorer only with the special HTML tag <xml>.
This is very very very probable that you do not want to do that because it will NOT be supported by any other browser More on XML data islands
XML namespace
Namespaces are usually used to avoid conflicts between tags having the same name but not the same meaning (semantically differents ).
Example : xmlns:namespace-prefix="namespaceURI"
The CDATA tag
All text in an XML document will be parsed by the parser.
Only text inside a CDATA section will be ignored by the parser.
Example : <!CDATA[ myjavascript code... ]>
Par Nicolas,
vendredi 16 février 2007 à 17:20 ::geek stuff
Little tip in case ou want to have HIGHER level of logging from tomcat (version 5.5 or higher), because he fails to do something but just says failure
Tomcat, out of the box, does not include any logging library. However, if you want to make some fine-tuning on the logging, he is ready to achieve your configuration.
At startup (my guess...) Tomcat checks if some special configuration has to be applied, via the "bridge" interface commons logging . This library can be described as a logging implementation abstraction layer. If so, he applies it. Commons logging interface hides the actual implementation, that is, you can use either log4j or any alternative behind the scenes.
Anyway, drop the commons logging and log4j jar files in the common/lib directory, write a log4j.properties file in the common/classes directory, and you should be fine.
Par Nicolas,
vendredi 9 février 2007 à 13:31 ::geek stuff
Finalement, la frontière entre les specs fonctionnelles et techniques est souvent trop peu marquée, de même que la frontière entre les spécifications techniques et l'architecture...
Voila quelques exemples tout bêtes qui m'en ont fait comprendre plus que les absconces définitions habituelles :
Les spécifications fonctionnelles (le plus facile) décrivent des comportements et aspects du systême:
authentification
navigation
contenu des vues
Les spécifications techniques décrivent des qualités du systême, par exemple :
scalabilité
performance
résistance aux pannes (exemple tolérance 99.9%)
On en vient à MDA : model driven architecture, qui est une nouvelle approche de la conception logicielle.
MDA tend à découpler au maximum la conception et l'architecture, et également à produire directement le code à partir du modèle.
La conception traite les spécifications fonctionnelles et l'architecture les specs techniques.
Ainsi, si l'on conçoit un modèle conceptuel implémentant les spécifications fonctionnelles, et que l'on a un traducteur modèle->architectureX qui va produire le code selon l'architecture X, on obtient les effets suivants :
chaque modification des spécifications implique une modification du modèle, et une nouvelle génération (automatique !) du systême.
Si finalement l'architecture X ne répond pas ou répond mal aux specs techniques, on change le traducteur et on prend modèle->architectureY, ce qui génère automatiquement une solution technique totalement diffèrente, mais implémentant exactement de la même manière les specs fonctionnelles !
C'est presque magique. Plus qu'à acheter les traducteurs...Voila le problème...Ils ne sont pas en rayon chez Monoprix ou Migros et en écrire un soi même, c'est comme pour les langues. Si on sait juste dire bonjour en chinois on fera un traducteur qui ne sait faire qu'un "hello world".
MDA reste une technologie extrêmement prometteuse, en particulier pour la création de maquettes. Lorsqu'on a construit un traducteur incluant un pan raisonnable d'une technologie, il est possible de construire une application avec des fonctionnalités basiques en quelques minutes.
Avec deux traducteurs, exemple Java EE et .Net, on pourra aller jusqu'à effectuer des comparatifs d'architecture.
Par Nicolas,
lundi 5 février 2007 à 12:30 ::geek stuff
Pour publier un article sur un blog Dotclear, on peut écrire directement en html, ce qui est mal, pour les raisons décrites ici, ou écrire dans un syntaxe wiki somme toute très simple. Par malheur, cette syntaxe est propre à Dotclear et n'est qu'à peu près compatible avec la syntaxe wiki de wikipedia par exemple.
Bref, le pense-bête que je perd tout le temps est ici, et en particulier, il dit comment publier
du code : @@code@@
insérer du HTML, parce que parfois on n'a pas le choix, par exemple si l'on veut insérer un clip Vimeo ;-) :
///html
mon code html avec <br/> saut de lignes <i>en italique</i> ///
donnera :