2008-12-21 4 views
0

ADDENDA EDIT:est la syntaxe de langage SFig efficace et claire (et mieux que XML DSL de Spring-Framework)?

ont pas accepté une réponse à ce que il n'y a pas eu de commentaires de Spring Framework expérimentés développeurs.

Je travaille sur un DSL de remplacement à utiliser pour les fichiers Spring Framework applicationContext.xml (où initialisation de haricots et les relations de dépendance sont décrites pour le chargement vers le haut dans l'usine de haricots de printemps). Ma motivation est que je n'ai rien contre l'utilisation de XML par Spring dans ce but, et je n'aime pas vraiment les alternatives qui ont été imaginées jusqu'à présent. Pour diverses raisons que je n'irai pas dans, je veux rester avec un langage déclaratif et pas un langage de script impératif tel que Groovy. J'ai donc saisi l'analyseur syntaxique ANTLR et j'ai conçu un nouveau DSL d'usine de haricots que j'ai baptisé SFig. Voici un lien qui parle plus à ce sujet:

SFig™ - alternative metadata config language for Spring-Framework

Et voici le site de dépôt de code source:

http://code.google.com/p/sfig/

Je suis intéressé de savoir comment je fais de la langue syntaxe jusqu'à présent. Pensez-vous que SFig est efficace et clair à comprendre? (Je suis particulièrement préoccupé en ce moment avec la chaîne de texte mulit-ligne):

properties_include "classpath:application.properties"; 


org.apache.commons.dbcp.BasicDataSource dataSource { 
    @scope = singleton; 
    @destroy-method = close; 
    driverClassName = "${jdbc.driverClassName}"; 
    url = "${jdbc.url}"; 
    username = "${jdbc.username}"; 
    password = "${jdbc.password}"; 
    defaultAutoCommit = true; 
} 


org.springframework.orm.ibatis.SqlMapClientFactoryBean sqlMapClient { 
    @scope = singleton; 
    @init-method = afterPropertiesSet; 
    @factory-method = getObject; 
    configLocation = "classpath:sqlmap-config.xml"; 
    dataSource = $dataSource; 
} 


/* this string will have Java unescape encoding applied */ 
STRING str = "\tA test\u0020string with \\ escaped character encodings\r\n"; 


/* this string will remain literal - with escape characters remaining in place */ 
STRING regexp = @"(\$\{([a-zA-Z][a-zA-Z0-9._]*)\})"; 


/* multi-line text block - equates to a java.lang.String instance */ 
TEXT my_multi_line_text = /// 
Here is a line of text. 
This is yet another. Here is a blank line: 

Now picks up again. 
///; 


/* forward use of 'props' bean */ 
java.util.HashMap map { 
    this($props); 
} 


/* equates to a java.util.Propertis instance */ 
PROPERTIES props { 
    "James Ward" = "Adobe Flex evangelist"; 
    "Stu Stern" = "Gorilla Logic - Flex Monkey test automation"; 
    Dilbert = "character in popular comic strip of same title"; 
    "App Title Display" = "Application: ${app.name}"; 
    "${app.desc}" = "JFig processes text-format Java configuration data"; 
} 


/* equates to a java.util.ArrayList instance */ 
LIST list { 
    this(["dusty", "moldy", "${app.version}", $str]); 
    [234, 9798.76, -98, .05, "numbers", $props, ["red", "green", "blue"]]; 
} 
+0

je dû modifier mon poste pour changer « JFig » à « SFIG ». Turns out il y a déjà un autre outil de programmation Java-centrique appelé JFig et il a été autour depuis plusieurs années. J'ai choisi SFIG impliquer la relation prévue de configuration pour le printemps-cadre. – RogerV

Répondre

0

Je n'ai pas beaucoup d'expérience avec le Spring XML vous faites référence, vous devez donc prendre les commentaires suivants avec une pincée de sel.

En tant que deuxième et troisième mise en garde:

  • fournir un extrait de code donnera une saveur de ce que la langue et sa sémantique sont. Il est difficile de comprendre complètement certains des choix que vous avez déjà faits (et avec raison), de sorte que tout commentaire ici peut être complètement contradictoire ou impossible à la lumière de ces choix.
  • la conception de la langue est autant un art qu'une science, et donc à ce stade, tout commentaire que vous pourriez obtenir est susceptible d'être assez subjectif.

Une plus grande, méta, question: en tant que DSL essayez-vous de faire la configuration de Spring, ou comme une classe plus générale de frameworks?

Là: caveat emptor. Maintenant, mes commentaires subjective et incomplète;)

  • Je ne suis pas sûr de comprendre la raison pour laquelle vous avez le préfixe @ pour scope et destroy-method, mais pas driverClassName. En outre, le mélange de à la fois xml-case et camelCase n'est pas complètement évident pour commencer. Le préfixe @ est-il un modificateur de type, ou s'agit-il de mots-clés dans la langue?

  • Je ne suis pas complètement sûr de vos intentions sur le format d'en-tête de bloc. Vous avez un nom de classe, puis une fonction de cette classe; est l'intention de spécifier quelle classe vous allez utiliser pour une fonction particulière?

par exemple.

sqlMapClient: org.springframework.orm.ibatis.SqlMapClientFactoryBean { 
    # body. 
} 

ou même:

sqlMapClient { 
    @class = org.springframework.orm.ibatis.SqlMapClientFactoryBean; 
    # is there a sensible (perhaps built-in) default if this is missing? 
} 
  • J'aime la substitution de variable ; Je suppose que les valeurs proviendront des propriétés du système? J'aime pouvoir spécifier littéraux de chaîne (sans s'échapper), en particulier pour les expressions régulières que vous avez montrées. Cependant, avoir une citation ou un modificateur de citation à plusieurs caractères semble un peu étranger. Je suppose que vous avez considéré la guillemets simples (shell et Perl utilisent des guillemets simples pour les chaînes littérales).

  • D'autre part, je pense que la triple barre oblique pour sur plusieurs lignes TEXT est la bonne approche, mais deux pas sans rappeler les commentaires dans les langues de style C. Python utilise un triple " à cette fin. Certains idiomes shell ont une convention de texte multiligne que je ne copierais pas. J'aime beaucoup l'apparence des propriétés et l'emplacement de la configuration, en utilisant ce qui ressemble à une notion d'adresse URI d'adressage. Si c'est un URI, classpath://file.xml peut être plus clair. Je peux avoir la mauvaise extrémité du bâton ici, cependant.

  • Je aime aussi beaucoup la notion de liste et une carte littéraux vous, bien que je ne suis pas sûr où:

    • this entre en (je suppose un appel à un constructeur Java)
    • pourquoi certains types sont en majuscules et d'autres non. Dois-je comprendre qu'il existe un type MAP par défaut, que vous pouvez utiliser plus précisément si vous le souhaitez?
    • est Dilbert un littéral de chaîne non cité?

Enfin, je vous point à un autre DSL de configuration, mais peut-être plus pour une utilisation sysadmin: Puppet.

Aller bien.

0

Je vais vous donner un peu de fond sur printemps et il est applicationContext.xml fichier - qui prêtera clarté à certaines des choses qui se passent dans la syntaxe SFIG.

Le fichier applicationContext.xml est utilisé pour exprimer l'initialisation du haricot pour les haricots qui seront gérés par l'usine de haricots de printemps.Donc, étant donné l'exemple des haricots vus dans ma version SFIG de ce fichier, en Java code d'application on peut demander l'usine de haricots pour faire une instance d'un haricot comme ceci:

SqlMapClient sqlMapClient = getBean("sqlMapClient"); 

L'usine de haricot prend soin de toute instanciation et initialisation que le bean nécessite - même au point d'injecter des dépendances. Dans ce cas, un bean SqlMapClient a besoin d'une instance d'un bean dataSource (qui est également décrit et référencé dans l'exemple SFig).

Un descripteur de haricot relaie les informations suivantes à l'usine de haricots:

  • Java nom de la classe du bean
  • un ID de haricot qui à la demande ou font référence
  • définition de haricot meta attributs (facultatif)
  • arguments d'initialisation du constructeur (optionnel)
  • et/ou initialiseurs propriété

Les attributs de méta de définition du bean de préfixes '@'. Ce sont des attributs utilisés par l'usine de haricots pour gérer le bean. Par exemple, @scope = singleton, informerait la fabrique de beans pour créer une seule instance du bean, la mettra en cache et lui remettra des références quand elle est demandée. Ceux qui peuvent être définis sont les mêmes que ceux définis par Spring-Framework.

Si un haricot doit être initialisé par un constructeur, puis qui est exprimé dans SFIG par une syntaxe qui semble invoquer ce avec des arguments entre parenthèses.

Vous pouvez également initialiser un bean en définissant ses propriétés. Les identificateurs affectés à '@' et non préfixés sont des propriétés de bean. Lorsque vous référencez un bean qui est une dépendance requise, il peut être référencé en préfixant son ID de bean avec '$'. Plusieurs exemples de cela apparaissent dans l'exemple SFig. Le syle $ {foo.bar} de la variable apparaissant dans les chaînes littérales sera remplacé par une valeur de propriété Java. Dans ce cas, les propriétés sont chargées à partir du fichier application.properties via cette ligne:

properties_include "classpath:application.properties"; 

propriétés Java System seront examinés à la prochaine si elle est introuvable dans les propriétés incluses. Ceci est une pratique largement suivie dans de nombreux frameworks Java. Le fichier applicationContext.xml basé sur XML en cours permet également cette utilisation. Comme java.util.Properties est souvent utilisé pour initialiser les beans, SFig fournit les propriétés comme une syntaxe pratique spéciale pour déclarer un objet Properties. De même pour java.util.List, qui a le SFig LIST correspondant. De plus, les tableaux de valeurs peuvent être déclarés entre crochets [...].

De plus, il y a TEXT pour déclarer des blocs de texte multiligne. Le '@' préfixant un littéral de chaîne signifie désactiver l'encodage d'échappement - une syntaxe de langage empruntée à C#.

L'un des principaux objectifs de conception du SFig DSL est de rester déclaratif par nature. Je m'abstiens volontairement d'ajouter des fonctionnalités de script impératives. La complexité de la logique de programmation intégrée dans un fichier de configuration de texte impliquera la possibilité de devoir le déboguer.Je ne veux pas ouvrir une autre dimension du débogage de code.

Questions connexes