MARMITA. Desarrollo

De EduWiki
Saltar a: navegación, buscar

Marmita. Desarrollo

Volver a Marmita

Descripción

Contempla las normativas y estándares para la elaboración de un código fuente homogéneo y estándar con el objeto de minimizar las tareas de mantenimiento.

También se incorporan las especificaciones para la obtención de sistemas de información seguros, con un rendimiento óptimo y adaptados a las necesidades de las tecnologías definidas en la Arquitectura de MARMITA.

Objetivos

  • Promover la generación de código fuente de calidad.
  • Unificar el uso de librerías y utilidades de apoyo.
  • Proponer plugins.
  • Promover el uso de patrones de diseño software.

Principios generales

  • Todas las aplicaciones web deberán evitar poner el nombre de la consejería, debido a que éste cambia con mucha frecuencia y obliga a redesplegar todas las aplicaciones.
En caso de ser necesario se deberá utilizar el esquema de TACO que contiene la orgánica.
  • En su caso, deberá estar en el pie de página "© Comunidad Autónoma de la Región de Murcia"
  • En el encabezado de la página aparecerá el nombre de la aplicación, el escudo de la CARM, el usuario conectado y la última parte de la IP del servidor entre paréntesis.
 Esto último es útil pues en caso de servidores balanceados permite diagnosticar, en caso de incidencias, el servidor que sirve la página

Normas de desarrollo

En esta sección se establecen el conjunto general de normas de desarrollo

Definiciones

  • pom.xml -> pom, responde a las siglas de Project Object Model, es un fichero XML, que es la “unidad” principal de un proyecto Maven. Contiene información a cerca del proyecto, fuentes, test, dependencias, plugins, version…
  • maven -> Maven es una herramienta de software para la gestión y construcción de proyectos Java. Maven utiliza un Project Object Model (POM) para describir el proyecto de software a construir, sus dependencias de otros módulos y componentes externos, y el orden de construcción de los elementos. Viene con objetivos predefinidos para realizar ciertas tareas claramente definidas, como la compilación del código y su empaquetado.

+ INFO: http://es.wikipedia.org/wiki/Maven

Las aplicaciones se separan en tres partes perfectamente diferenciadas, que son:

  1. pom.xml (ver definición)
  2. El back,que está a su vez dividido en 2 back-dao y back-restful, en el dao se definen las entidades, las interfaces, las implementaciones que vamos a usar en la aplicación
  3. El front


Criterios generales

Criterios generales de nomenclatura

  • Los identificadores estarán compuesto únicamente por los siguientes caracteres: [A-Z] [a-z] [0-9] y [_].
  • Queda por tanto prohibido el uso de Ñ, ñ, acentos y demás caracteres.

Criterios generales en ORACLE

  • No están permitidos los sinónimos públicos
  • Antes de plantearse crear un dblink, debe solicitarse a los responsables de los departamentos de sistemas y desarrollo que estudiaran si es realmente necesario el dblink
  • Antes de plantearse crear un job, debe solicitarse a los responsables de los departamentos de sistemas y desarrollo que estudiaran si es realmente necesario el job
  • Siempre antepondremos el esquema para hacer referencia a un objecto de bbdd ya sea una tabla, vista, procedimiento, ... aunque sea es propietario del esquema es que usa el objecto.
  • La nomenclatura debe seguirse rigurosamente en los nuevos proyectos.
  • Las palabras reservadas del lenguaje serán escritas en mayúsculas: BEGIN, END, NUMBER, SUBSTR, REPLACE, ….

Normas de codificación

Normas

los siguientes normas de codificación.

Guía de desarrollo en Educación: File:guia_desarrollo_v3.doc

  1. Normas de codificación. Madeja Junta de Andalucía 
  2. Guía de desarrollo. Media:MARMITA_GUIA_DESARROLLO.doc
  3. Estructura de proyectos maven. Media:Normativa_maven.doc
  4. Normas de escritura: se establece la convención lowerCamelCase (http://es.wikipedia.org/wiki/CamelCase)


Normas de prefijos de programas

A la hora de poner nombres a los programas o funciones que recuperan datos, se ha de utilizar la siguiente nomeclatura. Se escribirá en minúscula y a continuación la primera letra en mayúscula del programa, clase o método.

  • newPrograma, para insertar.
  • getPrograma, para recuperar información.
  • updPrograma, para grabar información de un registro ya existente.
  • delPrograma, para borrar información.


Estas normas son de obligado cumplimiento en todos los desarrollos que se efectúen en la Consejería.


Especificaciones de Codificación y Construcción


Construcción de Aplicaciones por Capas

Capa de Presentación

Capa de Negocio

Capa de Persistencia

Seguridad

Control de Acceso y Autenticación

Codificación y Validación de entrada/salida

Cifrado

Gestión de Sesiones y Usuarios

Gestión de Errores y Excepciones

Auditoría y Registro

Servicios Web

Servicios REST

Rendimiento

Ejemplos

Servicio de información de aplicaciones

Para agilizar la comunicación de incidencias y localizar mejor el origen de ella, es necesario conocer la versión de war que se está ejecutando y de alguna manera saber el servidor en el que se está ejecutando.

El siguiente documento explica cómo se intgra el servicio de información en una aplicación web de manera que cuando se compile con Jenkins éste le asigne número de versión y además de la configuración del servicio REST que permite obtener dicha información:

Ejemplo de servicio completo

EntityServiceDao.java

package es.carm.app.dao;
public interface EntityServiceDao {
  public Pojo getPojoById(String id) throws Exception;
  public Pojo delPojoById(String id) throws Exception;
  public Pojo insertPojo(Pojo pojo) throws Exception;
  public Pojo updatePojo(Pojo pojo) throws Exception;
  public List<Pojo> getPojos() throws Exception;
}

EntityServiceDaoImpl.java

package es.carm.app.dao;
public class EntityServiceDaoImpl implements EntityServiceDao {
  private EntityMapper entityMapper;
  public void setEntityMapper(EntityMapper entityMapper){ … }
  public EntityMapper getEntityMapper() { … }
  public Pojo getPojoById(String id) throws Exception { ... }
  public Pojo delPojoById(String id) throws Exception { ... }
  public Pojo insertPojo(Pojo pojo) throws Exception { ... }
  public Pojo updatePojo(Pojo pojo) throws Exception { ... }
  public List<Pojo> getPojos() throws Exception { ... }
}

EntityMapper.java

package es.carm.app.dao;
public interface EntityMapper {
  final String SELECT_ALL = “Select * FROM entity”;
  final String INSERT = “INSERT ...”;
  final String DELETE = “DELETE ...”;
  final ...;

  @Select(SELECT_ALL)
  public List<Pojo> getPojos();
  @Insert(INSERT)
  public Pojo insert(Pojo pojo);
  @Delete(DELETE)
  public Pojo delete(@Param(“id”) String id);
  ...
}

EntityService.java

package es.carm.app.service;

@Path(“/EntityService”)
@Produces(“application/json”)
public class EntityService {
  private EntityServiceDao entityServiceDao;
  public EntityServiceDao getEntityServiceDao() { ... }
  public void setEntityServiceDao(EntityServiceDao entityServiceDao) { ... }

  @Get
  @Path(“/pojos/”)
  public Response getPojos(){
    try{
      //comprobar autorizacion
      //Seguridad de servicios rest
      Subject user = SecurityUtils.getSubject();
      if (!user.hasRole("PROCESO_ACCESO")) {
          System.out.println("---- Procesos.BaremarSolicitud: no tiene permisos");
          return Response.serverError().build();
      }

      List<Pojo> res = entityServiceDao.getPojos();
      return Response.ok(res).build();
    } catch (Exception e){
      //sistema de logs
      e.printStackTrace();
      return Response.serverError().entity(e.getMessage()).build();
    }
  }
  ...
}

index.html

<!DOCTYPE html>
<html lang="en" id="ng-app" ng-app="myApp" xmlns="http://www.w3.org/1999/html" xmlns:ng="http://angularjs.org">
<head>
  <meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE" /> 
  <meta charset="utf-8">
  <title>Disposiciones</title>
  <script src="angular.min.js"></script>
  <script src="angular-resource.min.js"></script>
  <script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
ID:<input type="text" ng-model="ID">
<input type="button" value="imprimir" ng-click="imprimir()" />
<hr>
{{data}}
<hr>
{{ error }}
</body>
</html>

app.js

var myApp= angular.module('myApp', ['service']);

angular.module('service', ['ngResource']).
factory('Procesos', function($resource){
  return $resource('services/procesos/:ID', {}, {
  imprimir: {method:'POST', params:{ID:"imprimir"}, withCredentials: true, isArray:false}
  });
});

function MainCtrl($scope,Procesos){
  $scope.data = {};
  $scope.error = {};

  $scope.imprimir = function(){
    Procesos.imprimir($scope.data,function(data){
      alert('ok:'+data);
    },function(data){
      $scope.error = data;
      alert('ERROR:'+data.data);
    });
  }
}

Servicios Comunes REST

Menu

Este servicio está integrado con CONTROL-APLIC y la aplicación de gestión de menús. Devuelve el menú de la aplicación asociado al usuario de esa sesión.

ruta: appName/services/controlservice/menu/lineas/{idAppName}

parametros: {idAppName}: nombre de la aplicación en control-aplic. Es sensible a mayusculas.

respuesta: json. Array de "Menu". Cada menu es { "id":String, "nombre":String, "proceso":String, "submenu": [Menu]}

ejemplo:

[
  {"id":"14",
   "nombre":"Configuracion",
   "proceso":"LIBRO",
   "submenu":[
     {"id":"2",
      "nombre":"Adscripciones",
      "proceso":"ADSCRIPCIONES",
      "submenu":[]},
     {"id":"3",
      "nombre":"Configuracion",
      "proceso":"CONFIGCENTRO",
      "submenu":[]}
  }
]
 

Autorización

Este servicio ofrece inbformación de la presona que está conectada.

ruta: /appName/services/controlservice/autorizacion/{idAppName}

parametros: {idAppName}: nombre de la aplicación en control-aplic. Es sensible a mayusculas.

respuesta: json. Objeto "Usuario". { "login":String, "userName":String, "codigoCentro":String, "perfil":String, "idAlumno":String, "roles": [String], "gruposCentros": { key:valor } }

ejemplo:

{ "login":"xxx99x",
  "userName":"Persona Apellidos",
  "codigoCentro":"30010841",
  "perfil":null,
  "idAlumno":null,
  "roles":["ADMINISTRACION","CENTRO_DIRECTOR","CONFIGCENTRO"],
  "gruposCentros":
     { "LIBRO_ADMIN":"CONSEJERIA",
       "LIBRO_DIRECTOR":"30010841",
       "LIBRO_CENTROS":"30010841"
     }
}

URLS

http://draptik.github.io/blog/2013/07/13/angularjs-example-using-a-java-restful-web-service/


JENKINS y LINEAS DE PRODUCCION http://javablog.eliumontoya.com/a/eliumontoya.com/blog/home/integracioncontinuapromocionesylineasdeproduccion



Evitar que aparezca el jsessionID en las urls:

dentro del web.xml añadir:

<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>


Nueva integracion de maven con grunt:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${exec-maven-plugin-version}</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>node.exe</executable>
<!-- <outputFile>grunt.info</outputFile> -->
<commandlineArgs>"${NPMPREFIX}\node_modules\grunt-cli\bin\grunt" --no-color</commandlineArgs>
<!-- <successCodes><param>0</param><param>-1073741819</param></successCodes> -->
</configuration>
</plugin>



Seguridad de servicios rest

Subject user = SecurityUtils.getSubject();
if (!user.hasRole("CENTRO")) {
System.out.println("---- Procesos.BaremarSolicitud: no tiene permisos");
return Response.serverError().build();
}



Integracion SIGEINFO


Integracion Gestion de incidencias



Pasarela de sistemas (SesionTools)


JDBCBridge


Integracion servicios WEB Plumier y otros.


Que poner en control aplic:


Procesos:

Apliaciones

Grupos

Usuarios


Lineas de menu




Establecer la seguridad en la aplicacion

En web.xml debe estar el filtro de shiro activado:

<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


En springConfig definir y configurar el cliente Shiro:

En el fichero ShiroContext.xml debe contener lo siguiente, es el mismo para todos:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="${casServerPrefix}/login?service=${casService}" />
<property name="successUrl" value="/" />
<property name="unauthorizedUrl" value="/error.html" />
<property name="filterChainDefinitions">
<value>
/shiro-cas = casFilter
/webdav/** = anon
/** = roles[ROLE_USER]
</value>
</property>
</bean>
<bean id="casFilter" class="org.apache.shiro.cas.CasFilter">
<property name="failureUrl" value="/error.html"></property>
</bean>

<bean id="casSubjectFactory" class="org.apache.shiro.cas.CasSubjectFactory" />

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="casRealm" />
<property name="subjectFactory" ref="casSubjectFactory" />
</bean>

<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

<bean id="casRealm" class="es.carm.eduws.shiro.MyCasRealmWS">
<property name="defaultRoles" value="ROLE_USER" />
<property name="casServerUrlPrefix" value="${casServerPrefix}" />
<property name="casService" value="${casService}" />
<property name="controlAplicAPI" ref="controlAplicAPI" />
<property name="debug" value="true" />
</bean>

<!-- Enable Shiro Annotations for Spring-configured beans. Only run after -->
<!-- the lifecycleBeanProcessor has run: -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
</beans>


Lo unico que hay que hacer es configurar el aplication.properties


Ademas. en el fichero userInfo.xml se establece como se obtienen los roles y a que se puede acceder con cada rol


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
">


<bean id="userInfo" class="es.carm.mydom.security.UserInfoMock">
<property name="defaultUser" value="andres" />
<property name="separator" value="|" />
<property name="defaultRoles" value="|[Administrador]|[SuperUsuario]|[Gestor]|[Consultor]|" />
</bean>

<!-- <bean id="userInfo" class="es.carm.mydom.eduws.security.UserInfoControlAplic">
<property name="controlAplicAPI" ref="controlAplicAPI" />
<property name="aplicacion" value="${aplicacionControlAplic}" />
<property name="cacheSecs" value="60"></property>
</bean> -->

<bean id="securityPolice" class="es.carm.mydom.security.SecurityPoliceImpl">
<property name="denyWhenNoMatch"><value type="java.lang.Boolean">true</value></property>
<property name="needAllRoles"><value type="java.lang.Boolean">false</value></property>
<!-- <property name="fileEntries" value=""></property> -->
<property name="entries"><map>
<entry key="[SuperUsuario]"><list>
<bean class="es.carm.mydom.security.SecurityEntry" p:resource="*" p:action="*" />
</list></entry>
<entry key="[Administrador]"><list>
<bean class="es.carm.mydom.security.SecurityEntry" p:resource="*" p:action="*" />
</list></entry>
<entry key="[Gestor]"><list>
<bean class="es.carm.mydom.security.SecurityEntry" p:resource="Centro" p:action="*" />
<bean class="es.carm.mydom.security.SecurityEntry" p:resource="Entrada" p:action="*" />
<bean class="es.carm.mydom.security.SecurityEntry" p:resource="Expediente" p:action="*" />
<bean class="es.carm.mydom.security.SecurityEntry" p:resource="DatosRegistro" p:action="*" />
</list></entry>
</map></property>
</bean>

</beans>


Actualización de eduws a la versión 1.0.5-SNAPSHOT


Hay que modificar los siguientes ficheros shirocontext.xml y educacontext.xml en educacontext.xml en el bean cuyo id es controlAplicAPI hay
que eliminar las propiedades cuyo id son "ambito" y "aplicacion", en el shirocontext.xml hay que añadir el siguiente property al
bean cuyo id es casRealm
<property name="currentApp" value="${aplicacionControlAplic}" />


Uso de logs slf4j y slf4j-simple

hay una dependencia slf4j que debe ser añadida al pom


<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
version 1.7.5


por defecto esta dependencia se encuentra en la semilla indirectamente a través de eduws-api y/o eduws-rest


Esto permite que en el proyecto puedas crear las lineas de debug

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class pojo {
final Logger log = LoggerFactory.getLogger(pojo.class);

....
public .... {
log.debug("");
log.error("");
}

}


En tiempo de ejecución, dentro del proyecto war hay que enlazar el API con una implementacion del logger, en mi caso uso slf4j-simple

<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>

que debe estar dentro del paquete eduws-rest

Por último cuando se despliega el war (tomcat7:run)

hay que configurar el nivel por defecto de debug (por defecto esta desactivado)

en el goal de maven hay que escribir: tomcat7:run -Dorg.slf4j.simpleLogger.defaultLogLevel=debug




Generic REST

genericEduCrud

Paquete contenido en el proyecto genericRest (enlace al proyecto en el servidor SVN).

genericEduProcess

El paquete genericEduProcess, contenido en el proyecto genericRest (enlace al proyecto en SCM Manager) permite la comunicación, mediante una estructura simple definida en el Resolver, con procesos definidos en PL\SQL.

Dentro del archivo applicationcontext, en el front del proyecto donde se vaya a conectar con genericEduProcess (ver controlAplic-front como ejemplo), se deberán definir los siguientes beans:

  • genericEduProcessService
<bean id="genericProcessService" class="es.educarm.genericEduProcess.GenericEduProcessService">
<property name="service" ref="genericEduProcessServiceDao"/>
<property name="userDao" ref="userDao"/>
<property name="securityDao" ref="securityProcessDao"/>
<property name="app" value="${aplicacionControlAplic}"/>
</bean>
  • genericEduProcessServiceDao
<bean id="genericEduProcessServiceDao" class="es.educarm.genericEduProcess.GenericEduProcessServiceDaoImpl">
<property name="mapper" ref="genericEduProcessServiceMapper"></property>
<property name="info" ref="genericEduProcessMapperInfo"></property>
</bean>
  • genericEduProcessServiceMapper
<bean id="genericEduProcessServiceMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="es.educarm.genericEduProcess.GenericEduProcessServiceMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
  • resolverProcess
<bean id="resolverProcess" class="es.educarm.genericEduProcess.GenericEduProcessMapperInfoProcessResolverImpl"></bean>
  • secResolverProcess
<bean id="secResolverProcess" class="es.educarm.genericEduProcess.GenericEduProcessMapperSecurityProcessResolverImpl">
<property name="defaultResponse" value="true" />
</bean
  • genericEduProcessMapperInfo
<bean id="genericEduProcessMapperInfo" class="es.educarm.genericEduProcess.GenericEduProcessMapperInfo" depends-on="jdbcBridge,contextAware">
<property name="defaultResolver" ref="resolverProcess" />
<property name="defaultSecResolver" ref="secResolverProcess" />
<property name="info">
<property name="security">


Dentro de las propiedades "info" y "security" se definirán las conexiones con los procesos PL\SQL mediante la sintaxis mediante la etiqueta <value>:

<property name="info">
<value>
 Alias:Paquete#TipoDatoSalida|Dato1Entrada#TipoDatoEntrada|Dato2Entrada|...
</value>
<property name="security">
<value>
Alias|E=ROL1:ROL2:ROL3:...	
</value>


  • Alias:Paquete - Paquete hace referencia al paquete PL que contiene los procesos a definir en cada línea con esta estreuctura (una línea por proceso), mientras que el alias es como se define de manera interna el acceso al paquete.proceso definido (no puede haber dos alias idénticos).
  • TipoDatoSalida y TipoDatoEntrada - Delimitan el tipo de dato de los diferentes elementos de entrada y salida de PL\SQL, pudiendo ser los siguientes:
* T - VarChar2
* F - Date
* N - Number
* S - 
* C - Cursor
  • Dato1Entrada, Dato2Entrada, ... - Cada uno de los datos de entrada para el proceso PL\SQL, pudiendo llevar un tipo de dato asociado mediante la sintaxis #TipoDato alguno de ellos, pero no es obligatorio que lo lleven todos.
  • E=ROL1:ROL2:... - Hace referencia a los permisos de ejecución (E) del proceso PL\SQL en función de los roles prestablecidos (ROL1, ROL2, etc) designados para cada Alias.


Los parámetros de cada conexión introducida en la estructura serán procesados por la clase genericEduProcessMapperInfo, apoyándose en genericEduProcessMapperInfoParam y genericEduProcessMapperInfoProcess para la estructura mediante la que el paquete Java procesa la información acerca del Paquete PL\SQL y los diferentes parámetros de entrada del mismo.

Documentación de código javascript (+angularJS) (NgDocs)

Instalación:

Desde el directorio donde se almacena project's Gruntfile y package.json, instala el plugin con el siguiente comando:


npm install grunt-ngdocs --save-dev


Una vez que has hecho esto, añade esta línea en el project's Gruntfile:


grunt.loadNpmTasks('grunt-ngdocs');


Puedes ver un ejemplo completo en github.com/m7r/grunt-ngdocs-example


Configuración:

Dentro del fichero gruntfile.js, añade una sección llamada ngdocs, aquí tienes un ejemplo simple:

ngdocs: {
all: ['src/**/*.js']
}

Otras opciones: 

ngdocs: {
   options: {
      dest: 'docs',
      scripts: ['../app.min.js'],
      html5Mode: false,
      startPage: '/api',
      title: "My Awesome Docs",
      titleLink: "/api",
      bestMatch: true
   }
},
   api: {
      src: ['src/**/*.js', '!src/**/*.spec.js'],
      title: 'API Documentation'
   }
}


Opciones: 

dest

'docs' es la carpeta que se generará y donde se construirá nuestra documentación. 

Scripts

['angular.js'] Usa angular 1.2 y angular-animate 1.2.16 mostrado con grunt-ngdocs.

['path/to/file.js'] fichero que será copiado dentro de docs, dentro de la carpeta grunt-scripts.

['http://example.com/file.js', 'https://example.com/file.js', '//example.com/file.js'] referencia a ficheros remotos.

['../app.js'] Fichero referencia a la carpeta de destino.

startPage

'/api' Establece la primera página.


Targets:

Cada grunt target crea una sección en la documentación.

src [requerido] Lista de ficheros para documentar.


Funcionamiento:

La tarea analiza los archivos especificados para documentarlos y extrae los ficheros html para la aplicación de documentación.

En la primera ejecución, todos los archivos se copian a la carpeta de destino Despúes de eso, index.html, js/docs-setup.js y los parciales se sobreescribirán.

Los parciales que ya no son necesarios no se eliminarán. Usa, por ejemplo, la tarea grunt-contrib-clean para limpiar la carpeta docs antes de crear una nueva distribución.

Después de una actualización, debería limpiar también la carpeta docs.


/**
* @ngdoc directive
* @name rfx.directive:rAutogrow
* @element textarea
* @function
*
* @description
* Resize textarea automatically to the size of its text content.
*
* **Note:** ie<9 needs pollyfill for window.getComputedStyle
*
* @example
<example module="rfx">
<file name="index.html">
<textarea ng-model="text"rx-autogrow class="input-block-level"></textarea>
<pre>Plantilla-Text</pre>
</file>
</example>
*/
angular.module('rfx', []).directive('rAutogrow', function() {
//some nice code
});


Echa un vistazo a github.com/angular/angular.js/wiki/Writing-AngularJS-Documentation para ver de lo que es capaz o en github.com/angular/angular.js/tree/master/src/ng para ver más ejemplos.


Librerías y Módulos

Patrones de Diseño

Referencias