Back-End

19 mar, 2012

Veja como usar o MongoDB com Django

Publicidade

O Django é usado em um estilo maravilhosamente modular; é simples para substituir os diferentes componentes de um aplicativo Django baseado na web. Como os bancos de dados NoSQL são mais comuns nos dias de hoje, pode ser que você queira tentar executar um aplicativo com um backend diferente, em vez de um dos bancos de dados relacionais padrão, como o MySQL. Neste artigo, você começa a saborear o MongoDB, incluindo como chamá-lo em seus projetos Python usando o PyMongo ou o MongoEngine. Logo, você usa o Django e o MongoEngine para criar um blog simples que pode executar operações Create, Read, Update, and Delete (CRUD).

Sobre os bancos de dados NoSQL

De acordo com o nosql-database.org, os bancos de dados NoSQL são a “próxima geração de bancos de dados endereçando primordialmente alguns dos pontos: ser não relacional, distribuído, software livre e escalável horizontalmente”. Nesta classe de banco de dados está o MongoDB, um banco de dados orientado a documento.

Na prática do dia a dia, o Django 1.3 inclui suporte ao SQLite, MySQL, PostgreSQL e Oracle, mas não inclui suporte ao MongoDB. Mas isso não é problema, por é fácil fazê-lo. Infelizmente, a desvantagem é que você perde o painel de administração automática. Portanto, você tem que pesar isso com relação às suas necessidades.

Breve introdução ao MongoDB

O MongoDB age como um interpretador de JavaScript e, portanto, a manipulação do banco de dados é feita por meio de comandos JavaScript. Depois de instalá-lo localmente na sua máquina (consulte “Recursos”), tente alguns dos comandos mostrados em Listagem 1.

var x = "0";
x === 0;
typeof({});

Lista 1. Comandos JavaScript de amostra que podem ser testados com o MongoDB.

Não é necessário ser um especialista em JavaScript para começar a usar o MongoDB, ainda assim, seguem alguns conceitos úteis:

  •  É possível criar objetos usando a sintaxe literal de objeto, em outras palavras, com duas chaves (por exemplo var myCollection = {};);
  •  É possível criar matrizes com colchetes ([]);
  •  Tudo no JavaScript é um objeto, exceto para números, variáveis booleanas, nulo e indefinido.

Se você quiser saber mais sobre outros recursos do JavaScript, como a programação orientada a objetos de protótipo (OOP), regras de escopo e a sua natureza de programação funcional, consulte “Recursos”.

O MongoDB não possui esquemas, contrastando com os bancos de dados relacionais. Em vez de tabelas, coleções, que consistem em documentos, são usadas. Os documentos são criados usando sintaxe literal de objeto, conforme mostrado na Listagem 2.

var person1 = {name:"John Doe", age:25};
var person2 = {name:"Jane Doe", age:26, dept: 115};

Lista 2. Exemplos de criação de documento.

Agora, execute os comandos mostrados na Listagem 3 para criar uma nova coleção.

db.employees.save(person1);
db.employees.save(person2);

Lista 3. Criando coleções.

Como o MongoDB não possui esquemas, person1 e person2 não precisam ter os mesmos tipos de coluna, ou até o mesmo número de colunas. Além disso, o MongoDB é dinâmico por natureza, por isso cria funcionários ao invés de lançar um erro. É possível recuperar documentos por meio do método find() . Para obter todos os documentos em funcionários, chame find() sem qualquer argumento, conforme mostrado na Listagem 4.

> db.employees.find();
// returns
[
{ "_id" : { "$oid" : "4e363c4dcc93747e68055fa1" },
"name" : "John Doe", "age" : 25 },
{ "_id" : { "$oid" : "4e363c53cc93747e68055fa2" },
"name" : "Jane Doe", "dept" : 115, "age" : 26 }
]

Lista 4. Uma consulta MongoDB simples.

Observe que _id é o equivalente a uma chave primária. Para executar consultas específicas, é necessário passar outro objeto com o par de chave/valor que indica o que você está consultando, conforme mostrado na Listagem 5.

> db.employees.find({name: "John Doe"});
// returns
[
{ "_id" : { "$oid" : "4e363c4dcc93747e68055fa1" },
"name" : "John Doe", "age" : 25 }
]

Lista 5. Consulta por um parâmetro de pesquisa.

Para consultar os funcionários com idade acima de 25 anos, execute o comando mostrado na Listagem 6.

> db.employees.find({age:{'$gt':25}});
// returns
[
{ "_id" : { "$oid" : "4e363c53cc93747e68055fa2" },
"name" : "Jane Doe", "dept" : 115, "age" : 26 }
]

Lista 6. Consulta pelos funcionários com idade superior a 25 anos.

O $gt é um operador especial que significa maior do que. A Tabela 1 lista alguns outros modificadores.

Modificador Descrição
$gt Maior que
$lt Menor que
$gte Maior ou igual a
$lte Menor ou igual a
$in Verificar a existência de um array, semelhante ao operador ‘in’ de SQL.

Tablela 1. Os modificadores que podem ser usados com o MongoDB.

É possível, evidentemente, atualizar um registro usando o método update() . É possível, também, todo ele, conforme mostrado na Listagem 7.

> db.employees.update({
name:"John Doe", // Document to update
{name:"John Doe", age:27} // updated document
});

Lista 7. Atualizar um registro todo.

Como alternativa, é possível atualizar apenas um único valor usando o operador $set , conforme mostrado na Listagem 8 .

> db.employees.update({name:"John Doe", 
{ '$set': {age:27} }
});

Lista 8. Atualizar um valor único em um registro.

Para esvaziar uma coleção, chame o método remove() sem qualquer argumento. Por exemplo, se deseja remover o “John Doe” da coleção funcionários, você poderia fazer o que é mostrado na Listagem 9.

> db.employees.remove({"name":"John Doe"});
> db.employees.find();
// returns
[
{ "_id" : { "$oid" : "4e363c53cc93747e68055fa2" }, "name" : "Jane Doe",
"dept" : 115, "age" : 26 }
]

Lista 9. Remover o “John Doe” da coleção de funcionários.

Isso é apenas o suficiente para você começar. Claro que você pode continuar explorando o site oficial, que possui um prompt de comando mongodb interativo e puro baseado na web completo com tutorial, bem como os documentos oficiais. Consulte “Recursos”.

Integrando o Django ao MongoDB

Você tem algumas opções de acesso ao MongoDB a partir do Python ou Django. A primeira é usar o módulo Python, PyMongo. A Listagem 10 é uma sessão PyMongo de amostra, supondo que você tenha instalado o MongoDB e já tenha uma instância rodando em uma porta.

from pymongo import Connection

databaseName = "sample_database"
connection = Connection()

db = connection[databaseName]
employees = db['employees']

person1 = { "name" : "John Doe",
"age" : 25, "dept": 101, "languages":["English","German","Japanese"] }

person2 = { "name" : "Jane Doe",
"age" : 27, "languages":["English","Spanish","French"] }

print "clearing"
employees.remove()

print "saving"
employees.save(person1)
employees.save(person2)

print "searching"
for e in employees.find():
print e["name"] + " " + unicode(e["languages"])

Lista 10. Sessão de PyMongo de amostra.

O PyMongo permite que você execute mais de um banco de dados simultaneamente. Para definir uma conexão, basta passar em um nome de banco de dados para uma instância de conexão. Os dicionários Python, neste caso, substituem os literais de objeto JavaScript para criar novas definições de documentos, e as listas de Python substituem matrizes de JavaScript. O método find retorna um objeto cursor de banco de dados sobre o qual é possível iterar.

A semelhança na sintaxe facilita a alternância entre a linha de comando MongoDB e a execução de comandos com PyMongo. Por exemplo, a Listagem 11 mostra como executar uma consulta com o PyMongo.

for e in employees.find({"name":"John Doe"}):
print e

Lista 11. Executar uma consulta com o PyMongo.

A sua outra opção para chamar o MongoDB a partir do Python é o MongoEngine, que deve ser familiar caso você já tenha usado o ORM integrado do Django. O MongoEngine é um mapeador de documento para objeto, que é semelhante, em conceito, a um ORM. Listagem 12 mostra uma sessão de exemplo com o MongoEngine.

from mongoengine import *

connect('employeeDB')

class Employee(Document):
name = StringField(max_length=50)
age = IntField(required=False)

john = Employee(name="John Doe", age=25)
john.save()

jane = Employee(name="Jane Doe", age=27)
jane.save()

for e in Employee.objects.all():
print e["id"], e["name"], e["age"]

Lista 12. Sessão de exemplo do MongoEngine.

O objeto Employee recebe herança de mongoengine.Document. Neste exemplo, dois tipos de campo são usados: StringField e IntField. Assim como o ORM do Django, para consultar todos os documentos na coleção, você chama o Employee.objects.all(). Observe que para acessar o ID de objeto único, usa-se o “id” em vez de “_id”.

Um blog de amostra

Agora, um blog simples, chamado Blongo, será criado. O Python 1.7, Django 1.3, MongoDB 1.8.2, MongoEngine 0.4 e Hypertext Markup Language (HTML) 5 serão usados. Se deseja recriar minhas configurações exatas, eu usei o Ubuntu Linux com o FireFox. O Blongo exibe qualquer entrada de blog inserida no carregamento da página e permite a atualização e exclusão de qualquer entrada – em outras palavras, todas as operações CRUD padrão. As visualizações do Django possuem três métodos: index, update e o delete.

As definições em Cascading Style Sheets (CSS) seguem em um arquivo estático separado. Não entrarei em detalhes aqui, mas fique à vontade para explorar o código fonte incluso em “Download”.

Considerando que tudo esteja instalado e funcionando bem, crie um novo projeto Django e os componentes necessários, conforme mostrado na Listagem 13.

$ django-admin.py startproject blongo
$ cd blongo
$ django-admin.py startapp blogapp
$ mkdir templates
$ cd blogapp
$ mkdir static

Lista 13. Comandos para configuração do projeto de blog Django.

Como novidade para o Django 1.3, há um aplicativo contribuído incluso para uma melhor manipulação de arquivos estáticos. Ao incluir um diretório estático a qualquer diretório do aplicativo (como blogapp, neste caso) e certificar-se de que o django.contrib.staticfiles esteja incluído nos aplicativos instalados, o Django é capaz de localizar arquivos estáticos, como arquivos .css e .js, sem a necessidade de quaisquer ajustes adicionais. A Listagem 14 mostra as linhas dos arquivos de configuração que foram alteradas (a partir do arquivo settings.py padrão) para obter o aplicativo de blog em execução.

# Django settings for blog project.
import os
APP_DIR = os.path.dirname( globals()['__file__'] )

DBNAME = 'blog'

TEMPLATE_DIRS = (
os.path.join( APP_DIR, 'templates' )
)

INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog.blogapp',
)

Lista 14. Linhas dos arquivos de configuração que foram alteradas (a partir do arquivo settings.py padrão).

Você possui três modelos neste projeto: index.html, update.html e delete.html. A Listagem 15 mostra o código para todos os três arquivos de modelo.

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<link href="{{STATIC_URL}}blog.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1>Blongo</h1>
<form method="post" action="http://127.0.0.1:8000/">
{% csrf_token %}
<ul>
<li>
<input type="text" name="title" placeholder="Post Title" required>
</li>
<li>
<textarea name="content" placeholder="Enter Content" rows=5 cols=50 required>
</textarea>
</li>
<li>
<input type="submit" value="Add Post">
</li>
</ul>
</form>
<!-- Cycle through entries -->
{% for post in Posts %}
<h2> {{ post.title }} </h2>
<p>{{ post.last_update }}</p>
<p>{{ post.content }}</p>
<form method="get" action="http://127.0.0.1:8000/update">
<input type="hidden" name="id" value="{{ post.id }}">
<input type="hidden" name="title" value="{{ post.title }}">
<input type="hidden" name="last_update" value="{{ post.last_update }}">
<input type="hidden" name="content" value="{{ post.content }}">
<input type="submit" name="" value="update">
</form>
<form method="get" action="http://127.0.0.1:8000/delete">
<input type="hidden" name="id" value="{{post.id}}">
<input type="submit" value="delete">
</form>
{% endfor %}
</body>
</html>

<!-- update.html -->
<!DOCTYPE html>
<html>
<head>
<link href="{{STATIC_URL}}blog.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1>Blongo - Update Entry</h1>
<form method="post" action="http://127.0.0.1:8000/update/">
{% csrf_token %}
<ul>
<li><input type="hidden" name="id" value="{{post.id}}"></li>
<li>
<input type="text" name="title" placeholder="Post Title"
value="{{post.title}}" required>
<input type="text" name="last_update"
value="{{post.last_update}}" required>
</li>
<li>
<textarea name="content" placeholder="Enter Content"
rows=5 cols=50 required>
{{post.content}}
</textarea>
</li>
<li>
<input type="submit" value="Save Changes">
</li>
</ul>
</form>
</body>
</html>
<!-- delete.html -->
<!DOCTYPE html>
<html>
<head>
<link href="{{STATIC_URL}}blog.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1>Blongo - Delete Entry</h1>
<form method="post" action="http://127.0.0.1:8000/delete/">
{% csrf_token %}
<input type="hidden" name="id" value="{{id}}">
<p>Are you sure you want to delete this post?</p>
<input type="submit" value="Delete">
</form>
</body>
</html>

Lista 15. Código para os arquivos de modelo index.html, update.html e delete.html.

Em seguida, altere os mapeamentos de URL para o código mostrado na Listagem 16, que aponta para as visualizações para o índice, atualização e exclusão. Se você deseja que o blog de amostra crie novas entradas de blog (no índice), atualize as postagens de blog existentes e as exclua quando desejar. Cada ação é realizada pela postagem para uma URL específica.

from django.conf.urls.defaults import patterns, include, url

urlpatterns = patterns('',
url(r'^
, 'blog.blogapp.views.index'),
url(r'^update/', 'blog.blogapp.views.update'),
url(r'^delete/', 'blog.blogapp.views.delete'),
)

Lista 16. Mapeamentos de URL para índice, atualização e exclusão.

Observe que não é necessário executar o comando syncdb do Django. Para integrar o MongoDB ao seu aplicativo, é necessário o MongoEngine. No arquivo models.py do diretório blogapp, inclua o código mostrado na Listagem 17.

from mongoengine import *
from blog.settings import DBNAME

connect(DBNAME)

class Post(Document):
title = StringField(max_length=120, required=True)
content = StringField(max_length=500, required=True)
last_update = DateTimeField(required=True)

Lista 17. Incluindo MongoEngine na camada de dados.

O nome do banco de dados é obtido a partir do arquivo de definições para separar os interesses. Cada postagem do Blog contém três campos obrigatórios: title, content e o last_update. Se você comparar e contrastar esta listagem com o que você faria normalmente no Django, a diferença não será enorme. Em vez de ter uma classe que herda do django.db.models.Model, esta listagem usa a classe mongoengine.Document em seu lugar. A diferença entre os tipos de dados não será detalhada aqui, mas sinta-se a vontade para verificar os documentos do MongoEngine (consulte “Recursos”).

Tabela 2 lista os tipos de campo MongoEngine e mostra o tipo de campo Django ORM equivalente, se houver.

Tipo de campo MongoEngine Django ORM equivalente
StringField CharField
URLField URLField
EmailField EmailField
IntField IntegerField
FloatField FloatField
DecimalField DecimalField
BooleanField BooleanField
DateTimeField DateTimeField
EmbeddedDocumentField Nenhum
DictField Nenhum
ListField Nenhum
SortedListField Nenhum
BinaryField Nenhum
ObjectIdField Nenhum
FileField FileField

Tablela 2. Tipos de campo MongoEngine e Django ORM equivalentes.

Finalmente, é possível configurar as suas visualizações. Seguem três métodos de visualização: index, update e o delete. Para executar a ação desejada, deve ser feita uma solicitação de postagem para a URL específica. Por exemplo, para atualizar um documento deve ser feita uma postagem para localhost:8000/update. Executar uma solicitação http ‘GET’ não salvará, atualizará e assim por diante. As novas postagens do blog são inseridas a partir da visualização de índice. Listagem 18 mostra as implementações para as visualizações de índice, atualização e exclusão.

    if request.method == 'POST':
# save new post
title = request.POST['title']
content = request.POST['content']

post = Post(title=title)
post.last_update = datetime.datetime.now()
post.content = content
post.save()

# Get all posts from DB
posts = Post.objects
return render_to_response('index.html', {'Posts': posts},
context_instance=RequestContext(request))


def update(request):
id = eval("request." + request.method + "['id']")
post = Post.objects(id=id)[0]

if request.method == 'POST':
# update field values and save to mongo
post.title = request.POST['title']
post.last_update = datetime.datetime.now()
post.content = request.POST['content']
post.save()
template = 'index.html'
params = {'Posts': Post.objects}

elif request.method == 'GET':
template = 'update.html'
params = {'post':post}

return render_to_response(template, params, context_instance=RequestContext(request))


def delete(request):
id = eval("request." + request.method + "['id']")

if request.method == 'POST':
post = Post.objects(id=id)[0]
post.delete()
template = 'index.html'
params = {'Posts': Post.objects}
elif request.method == 'GET':
template = 'delete.html'
params = { 'id': id }

return render_to_response(template, params, context_instance=RequestContext(request))

Lista 18. As visualizações do Django.

Você deve ter notado as instruções eval usadas para recuperar os IDs do documento. Isso é usado para evitar a necessidade de gravar a instrução if mostrada na Listagem 19.

    if request.method == 'POST':
id = request.POST['id']
elif request.method == 'GET':
id = request.GET['id']

Lista 19. Forma alternativa de recuperar o ID do documento.

Também é possível escrever dessa maneira. Isso é tudo o que preciso para ter um blog simples ativo e funcionando. Obviamente, faltam muitos componentes para um produto final, tais como usuários, um login, tags e assim por diante.

Conclusão

Como você pode ver, não há realmente muito para chamar o MongoDB a partir do Django. Neste artigo, apresentei rapidamente o MongoDB e expliquei como acessá-lo e manipular suas coleções e documentos a partir do Python por meio do wrapper PyMongo e o mapeador de objeto para documento MongoEngine. Finalmente, ofereci uma rápida demonstração de como criar um formulário CRUD básico usando o Django. Embora esta seja apenas a primeira etapa, espero que você entenda agora como aplicar esta configuração em seus próprios projetos.

Download

Descrição Nome Tamanho Método de download
Sample Django application with MongoEngine blongo.zip 12KB HTTP

Recursos

Aprender

Obter produtos e tecnologias

  • Saiba mais e faça o download do MongoDB.
  • Faça o download e explore o Django.
  • Visite o website Python para obter os downloads e a documentação.
  • Confira MongoEngine.
  • Aprofunde-se em PyMongo.
  • Avalie produtos IBM da maneira que for melhor para você: faça download da versão de avaliação de um produto, avalie um produto on-line, use-o em um ambiente de nuvem ou passe algumas horas na SOA Sandbox aprendendo a implementar Arquitetura Orientada a Serviços de forma eficiente.

Discutir

  • Participe da comunidade do developerWorks. Entre em contato com outros usuários do developerWorks, enquanto explora os blogs, fóruns, grupos e wikis orientados ao desenvolvedor. 

***

Sobre o autor: Cesar Otero é consultor Java e Python freelance. Ele é formado em engenharia elétrica com especialização em matemática.

, 'blog.blogapp.views.index'),\u003Cbr\u003E url(r'^update\u002F', 'blog.blogapp.views.update'),\u003Cbr\u003E url(r'^delete\u002F', 'blog.blogapp.views.delete'),\u003Cbr\u003E)\u003C\u002Fpre\u003E\n\u003Cp\u003E\u003Cem\u003ELista 16. Mapeamentos de URL para índice, atualização e exclusão.\u003C\u002Fem\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EObserve que não é necessário executar o comando syncdb do Django. Para integrar o MongoDB ao seu aplicativo, é necessário o MongoEngine. No arquivo models.py do diretório blogapp, inclua o código mostrado na Listagem 17.\u003C\u002Fp\u003E\n\u003Cpre\u003Efrom mongoengine import *\u003Cbr\u003Efrom blog.settings import DBNAME\u003Cbr\u003E\u003Cbr\u003Econnect(DBNAME)\u003Cbr\u003E\u003Cbr\u003Eclass Post(Document):\u003Cbr\u003E title = StringField(max_length=120, required=True)\u003Cbr\u003E content = StringField(max_length=500, required=True)\u003Cbr\u003E last_update = DateTimeField(required=True)\u003Cbr\u003E\u003C\u002Fpre\u003E\n\u003Cp\u003E\u003Cem\u003ELista 17. Incluindo MongoEngine na camada de dados.\u003C\u002Fem\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EO nome do banco de dados é obtido a partir do arquivo de definições para separar os interesses. Cada postagem do Blog contém três campos obrigatórios: title, content e o last_update. Se você comparar e contrastar esta listagem com o que você faria normalmente no Django, a diferença não será enorme. Em vez de ter uma classe que herda do django.db.models.Model, esta listagem usa a classe mongoengine.Document em seu lugar. A diferença entre os tipos de dados não será detalhada aqui, mas sinta-se a vontade para verificar os documentos do MongoEngine (consulte “Recursos”).\u003C\u002Fp\u003E\n\u003Cp\u003ETabela 2 lista os tipos de campo MongoEngine e mostra o tipo de campo Django ORM equivalente, se houver.\u003C\u002Fp\u003E\n\u003Ctable\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n\u003Cth\u003ETipo de campo MongoEngine\u003C\u002Fth\u003E\n\u003Cth\u003EDjango ORM equivalente\u003C\u002Fth\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EStringField\u003C\u002Ftd\u003E\n\u003Ctd\u003ECharField\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EURLField\u003C\u002Ftd\u003E\n\u003Ctd\u003EURLField\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EEmailField\u003C\u002Ftd\u003E\n\u003Ctd\u003EEmailField\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EIntField\u003C\u002Ftd\u003E\n\u003Ctd\u003EIntegerField\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EFloatField\u003C\u002Ftd\u003E\n\u003Ctd\u003EFloatField\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EDecimalField\u003C\u002Ftd\u003E\n\u003Ctd\u003EDecimalField\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EBooleanField\u003C\u002Ftd\u003E\n\u003Ctd\u003EBooleanField\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EDateTimeField\u003C\u002Ftd\u003E\n\u003Ctd\u003EDateTimeField\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EEmbeddedDocumentField\u003C\u002Ftd\u003E\n\u003Ctd\u003ENenhum\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EDictField\u003C\u002Ftd\u003E\n\u003Ctd\u003ENenhum\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EListField\u003C\u002Ftd\u003E\n\u003Ctd\u003ENenhum\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ESortedListField\u003C\u002Ftd\u003E\n\u003Ctd\u003ENenhum\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EBinaryField\u003C\u002Ftd\u003E\n\u003Ctd\u003ENenhum\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EObjectIdField\u003C\u002Ftd\u003E\n\u003Ctd\u003ENenhum\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EFileField\u003C\u002Ftd\u003E\n\u003Ctd\u003EFileField\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003C\u002Ftbody\u003E\n\u003C\u002Ftable\u003E\n\u003Cp\u003E\u003Cem\u003ETablela 2. Tipos de campo MongoEngine e Django ORM equivalentes.\u003C\u002Fem\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EFinalmente, é possível configurar as suas visualizações. Seguem três métodos de visualização: index, update e o delete. Para executar a ação desejada, deve ser feita uma solicitação de postagem para a URL específica. Por exemplo, para atualizar um documento deve ser feita uma postagem para localhost:8000\u002Fupdate. Executar uma solicitação http ‘GET’ não salvará, atualizará e assim por diante. As novas postagens do blog são inseridas a partir da visualização de índice. Listagem 18 mostra as implementações para as visualizações de índice, atualização e exclusão.\u003C\u002Fp\u003E\n\u003Cpre\u003E if request.method == 'POST':\u003Cbr\u003E # save new post\u003Cbr\u003E title = request.POST['title']\u003Cbr\u003E content = request.POST['content']\u003Cbr\u003E\u003Cbr\u003E post = Post(title=title)\u003Cbr\u003E post.last_update = datetime.datetime.now() \u003Cbr\u003E post.content = content\u003Cbr\u003E post.save()\u003Cbr\u003E\u003Cbr\u003E # Get all posts from DB\u003Cbr\u003E posts = Post.objects \u003Cbr\u003E return render_to_response('index.html', {'Posts': posts},\u003Cbr\u003E context_instance=RequestContext(request))\u003Cbr\u003E\u003Cbr\u003E\u003Cbr\u003Edef update(request):\u003Cbr\u003E id = eval(\"request.\" + request.method + \"['id']\")\u003Cbr\u003E post = Post.objects(id=id)[0]\u003Cbr\u003E \u003Cbr\u003E if request.method == 'POST':\u003Cbr\u003E # update field values and save to mongo\u003Cbr\u003E post.title = request.POST['title']\u003Cbr\u003E post.last_update = datetime.datetime.now() \u003Cbr\u003E post.content = request.POST['content']\u003Cbr\u003E post.save()\u003Cbr\u003E template = 'index.html'\u003Cbr\u003E params = {'Posts': Post.objects} \u003Cbr\u003E\u003Cbr\u003E elif request.method == 'GET':\u003Cbr\u003E template = 'update.html'\u003Cbr\u003E params = {'post':post}\u003Cbr\u003E \u003Cbr\u003E return render_to_response(template, params, context_instance=RequestContext(request))\u003Cbr\u003E \u003Cbr\u003E\u003Cbr\u003Edef delete(request):\u003Cbr\u003E id = eval(\"request.\" + request.method + \"['id']\")\u003Cbr\u003E\u003Cbr\u003E if request.method == 'POST':\u003Cbr\u003E post = Post.objects(id=id)[0]\u003Cbr\u003E post.delete() \u003Cbr\u003E template = 'index.html'\u003Cbr\u003E params = {'Posts': Post.objects} \u003Cbr\u003E elif request.method == 'GET':\u003Cbr\u003E template = 'delete.html'\u003Cbr\u003E params = { 'id': id } \u003Cbr\u003E\u003Cbr\u003E return render_to_response(template, params, context_instance=RequestContext(request))\u003Cbr\u003E\u003C\u002Fpre\u003E\n\u003Cp\u003E\u003Cem\u003ELista 18. As visualizações do Django.\u003C\u002Fem\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EVocê deve ter notado as instruções eval usadas para recuperar os IDs do documento. Isso é usado para evitar a necessidade de gravar a instrução if mostrada na Listagem 19.\u003C\u002Fp\u003E\n\u003Cpre\u003E if request.method == 'POST':\u003Cbr\u003E id = request.POST['id']\u003Cbr\u003E elif request.method == 'GET':\u003Cbr\u003E id = request.GET['id']\u003C\u002Fpre\u003E\n\u003Cp\u003E\u003Cem\u003ELista 19. Forma alternativa de recuperar o ID do documento.\u003C\u002Fem\u003E\u003C\u002Fp\u003E\n\u003Cp\u003ETambém é possível escrever dessa maneira. Isso é tudo o que preciso para ter um blog simples ativo e funcionando. Obviamente, faltam muitos componentes para um produto final, tais como usuários, um login, tags e assim por diante.\u003C\u002Fp\u003E\n\u003Ch4\u003EConclusão\u003C\u002Fh4\u003E\n\u003Cp\u003EComo você pode ver, não há realmente muito para chamar o MongoDB a partir do Django. Neste artigo, apresentei rapidamente o MongoDB e expliquei como acessá-lo e manipular suas coleções e documentos a partir do Python por meio do wrapper PyMongo e o mapeador de objeto para documento MongoEngine. Finalmente, ofereci uma rápida demonstração de como criar um formulário CRUD básico usando o Django. Embora esta seja apenas a primeira etapa, espero que você entenda agora como aplicar esta configuração em seus próprios projetos.\u003C\u002Fp\u003E\n\u003Ch4\u003EDownload\u003C\u002Fh4\u003E\n\u003Ctable\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n\u003Cth\u003EDescrição\u003C\u002Fth\u003E\n\u003Cth\u003ENome\u003C\u002Fth\u003E\n\u003Cth\u003ETamanho\u003C\u002Fth\u003E\n\u003Cth\u003EMétodo de download\u003C\u002Fth\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ESample Django application with MongoEngine\u003C\u002Ftd\u003E\n\u003Ctd\u003Eblongo.zip\u003C\u002Ftd\u003E\n\u003Ctd\u003E12KB\u003C\u002Ftd\u003E\n\u003Ctd\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fapps\u002Fdownload\u002Findex.jsp?contentid=800572&filename=blongo.zip&method=http&locale=pt_BR\"\u003EHTTP\u003C\u002Fa\u003E\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003C\u002Ftbody\u003E\n\u003C\u002Ftable\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Flibrary\u002Fwhichmethod.html\"\u003EInformações sobre métodos de download\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch4\u003ERecursos\u003C\u002Fh4\u003E\n\u003Cp\u003E\u003Cstrong\u003EAprender\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003ESaiba mais sobre o JavaScript por meio do tutorial do Mozilla: “\u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen\u002FA_re-introduction_to_JavaScript\"\u003EUma reintrodução ao JavaScript\u003C\u002Fa\u003E,” e pelo livro de Douglas Crockford: \u003Cem\u003E\u003Ca href=\"http:\u002F\u002Foreilly.com\u002Fcatalog\u002F9780596517748\"\u003EJavaScript: The Good Parts\u003C\u002Fa\u003E\u003C\u002Fem\u003E (O’Reilly Media\u002FYahoo Press, maio de 2008). \u003C\u002Fli\u003E\n\u003Cli\u003ENos \u003Ca href=\"https:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fopensource\u002F\"\u003Ezona de software livre\u003C\u002Fa\u003E, encontre muitas informações de uso, ferramentas e atualizações de projetos para ajudá-lo a desenvolver tecnologias de software livre e usá-las com produtos IBM.\u003C\u002Fli\u003E\n\u003Cli\u003E Fique por dentro dos\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Foffers\u002Ftechbriefings\u002Fevents.html\"\u003Eeventos e webcasts técnicos do developerWorks\u003C\u002Fa\u003E com foco em uma variedade de produtos IBM e tópicos do segmento de mercado de TI. \u003C\u002Fli\u003E\n\u003Cli\u003E Participe de um \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Foffers\u002Ftechbriefings\u002F\"\u003Ebriefing ao vivo e gratuito do developerWorks\u003C\u002Fa\u003E para atualizar-se rapidamente sobre produtos e ferramentas IBM e tendências do segmento de mercado de TI. \u003C\u002Fli\u003E\n\u003Cli\u003E Siga o \u003Ca href=\"http:\u002F\u002Fwww.twitter.com\u002Fdeveloperworks\u002F\"\u003EDeveloperWorks no Twitter\u003C\u002Fa\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003E Acompanhe as \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Foffers\u002Flp\u002Fdemos\u002F\"\u003EDemos do developerWorks\u003C\u002Fa\u003E que abrangem desde demos de instalação e configuração de produtos para iniciantes até funcionalidade avançada para desenvolvedores experientes. \u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Cstrong\u003EObter produtos e tecnologias\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E Saiba mais e faça o download do \u003Ca href=\"http:\u002F\u002Fwww.mongodb.org\u002F\"\u003EMongoDB\u003C\u002Fa\u003E. \u003C\u002Fli\u003E\n\u003Cli\u003E Faça o download e explore o \u003Ca href=\"https:\u002F\u002Fwww.djangoproject.com\u002F\"\u003EDjango\u003C\u002Fa\u003E. \u003C\u002Fli\u003E\n\u003Cli\u003E Visite o website \u003Ca href=\"http:\u002F\u002Fwww.python.org\u002F\"\u003EPython\u003C\u002Fa\u003E para obter os downloads e a documentação. \u003C\u002Fli\u003E\n\u003Cli\u003E Confira \u003Ca href=\"http:\u002F\u002Fwww.mongoengine.org\u002F\"\u003EMongoEngine\u003C\u002Fa\u003E. \u003C\u002Fli\u003E\n\u003Cli\u003E Aprofunde-se em \u003Ca href=\"http:\u002F\u002Fapi.mongodb.org\u002Fpython\u002F1.11\u002F\"\u003EPyMongo\u003C\u002Fa\u003E. \u003C\u002Fli\u003E\n\u003Cli\u003E \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fdownloads\u002F\"\u003EAvalie produtos IBM\u003C\u002Fa\u003E da maneira que for melhor para você: faça download da versão de avaliação de um produto, avalie um produto on-line, use-o em um ambiente de nuvem ou passe algumas horas na \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fdownloads\u002Fsoasandbox\u002Findex.html\"\u003ESOA Sandbox\u003C\u002Fa\u003E aprendendo a implementar Arquitetura Orientada a Serviços de forma eficiente. \u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Cstrong\u003EDiscutir\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E Participe da \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fcommunity\u002F\"\u003Ecomunidade do developerWorks\u003C\u002Fa\u003E. Entre em contato com outros usuários do developerWorks, enquanto explora os blogs, fóruns, grupos e wikis orientados ao desenvolvedor. \u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E***\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003E\u003Cem\u003ESobre o autor:\u003C\u002Fem\u003E\u003C\u002Fstrong\u003E\u003Cem\u003E Cesar Otero é consultor Java e Python freelance. Ele é formado em engenharia elétrica com especialização em matemática.\u003C\u002Fem\u003E\u003C\u002Fp\u003E\n","excerpt":"","link":"https:\u002F\u002Fimasters.com.br\u002Fback-end\u002Fveja-como-usar-o-mongodb-com-django","date":"19 mar, 2012","thumbnail":"","externalMention":null,"author":{"id":421,"thumbnail":"https:\u002F\u002Fsecure.gravatar.com\u002Favatar\u002Fbe5bc6f39606ac453a07bd2eb7ab21af?s=96&d=mm&r=g","name":"developerWorks Brasil","description":"é o portal de tecnologia da IBM para profissionais de TI de todo o mundo. Colabore, aprenda a criar aplicativos inovadores e compreenda tecnologias avançadas. Acesse mais artigos e tutoriais em www.ibm.com\u002Fdeveloperworks\u002Fbr","slug":"developerworks_brasil","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdeveloperworks_brasil","registered":"2010-07-07 17:06:45","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002Fsoudw","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002F","mail":"dwbr@br.ibm.com"},"articles_count":217,"views_count":4709798,"certifications":null,"conquests":null,"office":null,"articles":[{"id":46105,"title":"Como sobreviver com requisitos de compliance em projetos ágeis?","content":"\u003Cp\u003EA adoção de práticas ágeis está se tornando cada vez mais realidade nas empresas, e diferente como alguns pensam, não somente as pequenas e médias empresas de tecnologia estão adotando o método. Muitas instituições financeiras, indústrias e empresas de grande porte estão em processo de implantação. Mas para essas grandes instituições não temos como escapar de algumas exigências obrigatórias que impactam o desenvolvimento de software podendo torna-lo improdutivo ou burocrático. Essas exigências na maioria das vezes estão relacionadas ao atendimento de requisitos regulatórios, como por exemplo Sarbanes Oxley (SOX) ou Basileia.\u003C\u002Fp\u003E\n\u003Cp\u003EVamos focar este artigo nos principais itens regulatórios de instituições financeiras onde apresentaremos um breve resumo que poderá ajudar desenvolvedores a entenderem de forma simples quais os principais requisitos a serem obrigatoriamente seguidos e como não tornar o processo de desenvolvimento ágil burocrático e não produtivo.\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"1.2.Sarbanes-Oxley,Seção404:Avaliaçãodecontrolesinternos(apartemaisimportanteparaTI)|outline\"\u003E\u003C\u002Fa\u003ESarbanes-Oxley, Seção 404: Avaliação de controles internosv (a parte mais importante para TI)\u003C\u002Fh2\u003E\n\u003Cp\u003EA Lei Sarbanes-Oxley (em \u003Ca href=\"http:\u002F\u002Fpt.wikipedia.org\u002Fwiki\u002FL%C3%ADngua_inglesa\"\u003Einglês\u003C\u002Fa\u003E, Sarbanes-Oxley Act) é uma lei assinada em 30 de julho de 2002. Motivada por escândalos financeiros corporativos (dentre eles, o da \u003Ca href=\"http:\u002F\u002Fpt.wikipedia.org\u002Fwiki\u002FEnron\"\u003EEnron\u003C\u002Fa\u003E, que acabou por afetar drasticamente a empresa de auditoria Arthur Andersen), essa lei foi redigida com o objetivo de evitar o esvaziamento dos investimentos financeiros e a fuga dos investidores causada pela aparente insegurança a respeito da governança adequada das empresas.\u003C\u002Fp\u003E\n\u003Cp\u003EA lei Sarbanes-Oxley, apelidada de Sarbox ou ainda de SOX, visa garantir a criação de mecanismos de auditoria e segurança confiáveis nas empresas, incluindo ainda regras para a criação de comitês encarregados de supervisionar suas atividades e operações, de modo a mitigar riscos aos negócios, evitar a ocorrência de fraudes ou assegurar que haja meios de identificá-las quando ocorrem, garantindo a transparência na gestão das empresas.\u003C\u002Fp\u003E\n\u003Ch2\u003EO que meu desenvolvimento tem a ver com isso?\u003C\u002Fh2\u003E\n\u003Cp\u003EApesar do SOX não abordar diretamente a informática, as implicações para TI são enormes, uma vez que a maioria dos dados financeiros da organização flui através dos sistemas de informação e do código que você escreve. Logo, podemos dizer que qualquer manipulação incorreta no código fonte dos sistemas de TI poderá causar danos e\u002Fou prejuízos financeiros para a instituição.\u003C\u002Fp\u003E\n\u003Cp\u003EPodemos então dizer que, o principal requisito da SOX é controlar a criação, edição e versionamento de ativos que podem estar associados à seção 404 (seção que determina uma avaliação anual dos controles e procedimentos internos para emissão de relatórios financeiros), ou seja, qualquer alteração dos softwares desenvolvidos deverá ser devidamente documentada e controlada, gerando evidências que a empresa está tomando os cuidados necessários com os dados críticos e informações sensíveis.\u003C\u002Fp\u003E\n\u003Cp\u003EA seção 302 da Lei exige que os CEO e CFO façam declarações periódicas incluindo auditoria externas para evidenciar que os controles estão adequados para as informações financeiras da organização.\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"1.3.AcordoBasileiaII|outline\"\u003E\u003C\u002Fa\u003EAcordo Basiléia II\u003C\u002Fh2\u003E\n\u003Cp\u003EO acordo de Capital de Basiléia II, também conhecido como Basiléia II, trata-se de um framework estabelecido pelo Comitê de Basiléia, um consórcio de Bancos Centrais de Governo de vários países. O objetivo de Basiléia II é a revisão das normas internacionais existentes usadas para medir a exequibilidade ou simplesmente qualidade do capital de um banco. O acordo Basiléia anterior é considerado ultrapassado, pois não se adequa à nova realidade e modernizações do sistema financeiro.\u003C\u002Fp\u003E\n\u003Ch3\u003EO que meu desenvolvimento tem a ver com isso?\u003C\u002Fh3\u003E\n\u003Cp\u003EGrande parte do conteúdo do acordo Basiléia II foi redigido por profissionais do setor financeiro, de tal forma que pode ser aplicado em uma variedade de sistemas bancários do mundo. Os requisitos são vagos na perspectiva de TI, no entanto há uma série de medidas de mitigação de riscos para serviços financeiros.\u003C\u002Fp\u003E\n\u003Cp\u003EPortanto, podemos dizer que no ponto de vista de desenvolvimento, a grande questão está relacionada à gestão de riscos operacionais que visam à criação de políticas de gerenciamento de riscos para garantir segurança e confidencialidade das aplicações de TI que manipulam dados de clientes.\u003C\u002Fp\u003E\n\u003Cp\u003EDe forma não exaustiva, segue um resumo de alguns requisitos que apoiam no cumprimento da Basiléia II para tratamento de possíveis riscos operacionais:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EConstrução de sistemas de alta confidencialidade garantindo a criptrografia de dados confidenciais e evitando vulnerabilidade no código desenvolvido;\u003C\u002Fli\u003E\n\u003Cli\u003EDisponibilidade do serviço, evitando interrupções devido a falhas de hardware ou software;\u003C\u002Fli\u003E\n\u003Cli\u003EControle de alterações no software indevidos, não registrados e\u002Fou autorizados;\u003C\u002Fli\u003E\n\u003Cli\u003EControle de transações não autorizadas seja inserido no código dos sistemas.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003EUm bom processo de Gerência de Mudanças e Configuração pode ajudar bastante na redução dos riscos operacionais que podem ser gerados nas aplicações de TI.\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"1.4.DesafiosnoDesenvolvimentoÁgil|outline\"\u003E\u003C\u002Fa\u003EDesafios no Desenvolvimento Ágil\u003C\u002Fh2\u003E\n\u003Cp\u003EApesar de muitos dizerem que ágil é sinônimo de liberdade e bagunça, não é bem verdade. Eu diria exatamente o contrário, agile é um método muito mais organizado e disciplinado do que muitos desenvolvimentos tradicionais que tenho visto nas empresas.\u003C\u002Fp\u003E\n\u003Cp\u003EA conformidade com essas regulamentações exige relatórios financeiros precisos dos custos de desenvolvimento dos projetos e uma extensa documentação do processo. De fato, quanto maior o projeto, time ou quantidade de áreas envolvidas, maior será a exigência por controles formais e documentação.\u003C\u002Fp\u003E\n\u003Cp\u003EO principal paradigma quebrado na adoção do desenvolvimento ágil, é que o foco passa a ser do produto gerado, ou seja, a medida primária de gestão é teste ou software funcionando, diferente dos desenvolvimentos tradicionais onde boa parte do controle do progresso está associado à geração de documentos e reportes formais. Podemos perceber que muitas vezes passamos boa parte do tempo produzindo documentos de solução de problemas que nem sequer existem.\u003C\u002Fp\u003E\n\u003Cp\u003EO grande desafio aqui é encontrar o “ponto doce”, ou seja, não devemos implementar controles excessivos ou produzir muito para nada. A prática de captura de requisitos, por exemplo, não é o ato de construção de um documento de especificação funcional, mas sim a negociação contínua da definição de um escopo.\u003C\u002Fp\u003E\n\u003Cp\u003ESeguem listados aqui alguns dos principais objetivos exigidos pelas normas de auditoria e como podemos endereçá-los para o desenvolvimento ágil:\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EObjetivo\u003C\u002Fstrong\u003E: Processo de desenvolvimento definido\u003Cbr \u002F\u003E\n\u003Cstrong\u003ERealização\u003C\u002Fstrong\u003E: Estabelecer práticas padronizadas e um processo a ser seguido pelo time. Exemplo de práticas: desenvolvimento orientado a User Stories, visão geral de requisitos, planejamento de release, visão compartilhada, gerência de riscos orientada a valor, etc..\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EObjetivo: \u003C\u002Fstrong\u003EProcesso de planejamento de release definido\u003Cbr \u002F\u003E\n\u003Cstrong\u003ERealização: \u003C\u002Fstrong\u003EAdotar a prática de planejamento de release integrada ao planejamento e revisões das iterações\u002Fsprints\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EObjetivo\u003C\u002Fstrong\u003E: Prevenção de manipulação\u003Cbr \u002F\u003E\n\u003Cstrong\u003ERealização\u003C\u002Fstrong\u003E: Controlar os acesso a dados críticos de sistemas e implantação de user stories de aplicação para criptografia de dados\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EObjetivo\u003C\u002Fstrong\u003E: Execução de testes\u003Cbr \u002F\u003E\n\u003Cstrong\u003ERealização\u003C\u002Fstrong\u003E: Evidenciar testes automatizados, definições de testes e arquivar os relatórios com segurança. A adoção da prática de build e teste contínuos também é recomendada.\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EObjetivo:\u003C\u002Fstrong\u003E Documentação de usuários\u003Cbr \u002F\u003E\n\u003Cstrong\u003ERealização\u003C\u002Fstrong\u003E: Descrever as user stories adicionalmente os critérios de aceite, definição de pronto, metas de iterações\u002Fsprints ou até casos de uso (opcional) complementam a documentação exigida\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EObjetivo:\u003C\u002Fstrong\u003E Arquivamento\u003Cbr \u002F\u003E\n\u003Cstrong\u003ERealização\u003C\u002Fstrong\u003E: Implantar um sistema de gerência de configuração e versionamento com seus elementos rastreados às user stories implementadas. Necessidade de arquivamento de pelo menos 10 (dez) anos.\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EObjetivo:\u003C\u002Fstrong\u003E Impedir alterações não autorizadas de software\u003Cbr \u002F\u003E\n\u003Cstrong\u003ERealização\u003C\u002Fstrong\u003E: Implantar um sistema de gerência de configuração e versionamento integrado aos itens de trabalho registrados (ex. defeitos, tarefas, user stories) evidenciam que a empresa está tomando cuidados necessários para evitar a injeção de rotinas que permitam transações fraudulentas no seu código.\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EObjetivo\u003C\u002Fstrong\u003E: Autenticação segura\u003Cbr \u002F\u003E\n\u003Cstrong\u003ERealização\u003C\u002Fstrong\u003E: Implantar users stories de aplicação de criação de mecanismos seguros de autenticação nos sistemas utilizando senhas fortes e armazenamento de senhas seguro.\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=46110\" rel=\"attachment wp-att-46110\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-46110\" alt=\"image001 (3)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage001-3.jpg\" width=\"580\" height=\"234\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage001-3.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage001-3-300x121.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E \u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"1.5.Ambientecolaborativoéessencial|outline\"\u003E\u003C\u002Fa\u003EAmbiente colaborativo é essencial\u003C\u002Fh2\u003E\n\u003Cp\u003EDiferente das metodologias tradicionais, que são fortemente focadas em processos e geração de documentação, um dos principais fundamentos do Manifesto Ágil é o foco nos indivíduos e suas interações. Não se trata de desprezar elementos e ferramentas tradicionais de desenvolvimento de software, mas sim de estabelecermos uma escala de valores, na qual a flexibilidade e a colaboração são mais relevantes do que a rigidez de processos e planejamento clássicos.\u003C\u002Fp\u003E\n\u003Cp\u003EPosso fortemente afirmar que não é possível sobreviver com ferramentas tradicionais para um ambiente ágil de desenvolvimento. Para isso é necessário um ambiente que facilite o atendimento dos requisitos regulatórios sem onerar o dia-a-dia dos desenvolvedores.\u003C\u002Fp\u003E\n\u003Cp\u003EUma solução talvez mais racional e simples seja a adoção de ferramentas que suportam a interação entre pessoas, também chamamos de ferramentas colaborativas de ALM (Application Lifecycle Managment). Essas ferramentas além de suportar o ambiente colaborativo de desenvolvimento permitem o registro e as evidências necessárias para o processo de auditoria dos requisitos regulatórios, através, por exemplo, de relatórios automatizados e dahsboards.\u003C\u002Fp\u003E\n\u003Cp\u003EFalando ainda de ferramentas, vale mencionar que existem empresas que optam por adotar o papel de “documentador”, antigamente também chamado de “Escriba” somente para atuar na geração e arquivamento das evidências e artefatos obrigatórios para atender a requisitos regulatórios com o objetivo de eliminar essa carga de trabalho dos times ágeis. Francamente, não sei dizer se seria ou não a melhor solução.\u003C\u002Fp\u003E\n\u003Cp\u003EUtilizaremos neste artigo o ambiente colaborativo de desenvolvimento Jazz para exemplificar alguns cenários de como uma ferramenta poderá apoiar no atendimento a esses requisitos sem impactar a produtividade dos times:\u003C\u002Fp\u003E\n\u003Ch2\u003ERastreabilidade\u003C\u002Fh2\u003E\n\u003Cp\u003EO código alterado em coerência com as varias disciplinas como requisitos, design, testes e deploy é essencial. A rastreabilidade estabelece relações entre os artefatos de software garantindo a cobertura em todas as disciplinas.\u003C\u002Fp\u003E\n\u003Cp\u003EPodemos citar alguns dos exemplos mais comuns de visões de rastreabilidade como requisitos e código, casos de testes e requisitos, elementos de design e requisitos.\u003C\u002Fp\u003E\n\u003Cp\u003EO auditor quer ver:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EMatrizes de rastreabilidade entre as disciplinas de desenvolvimento;\u003C\u002Fli\u003E\n\u003Cli\u003EEvidências de análise de impacto de mudanças em uma disciplina afetando outra;\u003C\u002Fli\u003E\n\u003Cli\u003EEvidências da realização de análises adequadas e medidas corretivas associadas à mudanças que causam impactos.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003EA ferramenta deve estar preparada para:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EUtilizar dashboards para manter e rastrear as visões:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=46111\" rel=\"attachment wp-att-46111\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-46111\" alt=\"image002 (2)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage002-2.jpg\" width=\"521\" height=\"265\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage002-2.jpg 521w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage002-2-300x152.jpg 300w\" sizes=\"(max-width: 521px) 100vw, 521px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EConfigurar visões de análise de impacto:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=46112\" rel=\"attachment wp-att-46112\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-46112\" alt=\"image003 (2)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage003-2.jpg\" width=\"573\" height=\"257\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage003-2.jpg 573w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage003-2-300x134.jpg 300w\" sizes=\"(max-width: 573px) 100vw, 573px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E Utilizar revisões e comentários para suportar análises e ações corretivas:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=46113\" rel=\"attachment wp-att-46113\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-46113\" alt=\"image004 (3)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage004-3.jpg\" width=\"580\" height=\"444\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage004-3.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage004-3-300x229.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch2\u003EAutorização do trabalho\u003C\u002Fh2\u003E\n\u003Cp\u003EProcessos ágeis e iterativos devem ser suportados por “gates” de autorização e gerência de mudanças para garantir que apenas o trabalho aprovado é incluído em um release de produção.\u003C\u002Fp\u003E\n\u003Cp\u003EA Sarbanes Oxley, por exemplo, exige que controles internos apropriados sejam estabelecidos para mitigação de riscos de alterações não desejadas nos sistemas que manipulam dados de negócio. A aprovação do conteúdo e da release a ser implantada em produção é um dos principais controles a serem auditados.\u003C\u002Fp\u003E\n\u003Cp\u003EO auditor quer ver:\u003C\u002Fp\u003E\n\u003Col\u003E\n\u003Cli\u003EQuem (usuário e papel) autorizou o conteúdo de uma release.\u003C\u002Fli\u003E\n\u003Cli\u003EQuem (usuário e papel) autorizou a implantação de uma release em produção.\u003C\u002Fli\u003E\n\u003Cli\u003EOs Requisitos a serem implantados foram devidamente validados e autorizados pelo usuário que irá utiliza-lo.\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cp\u003EA ferramenta deve estar preparada para:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EFornecer um mecanismo de autorização do trabalho ou aprovação de requisitos através de assinatura eletrônica:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=46114\" rel=\"attachment wp-att-46114\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-46114\" alt=\"image005 (3)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage005-3.jpg\" width=\"575\" height=\"333\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage005-3.jpg 575w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage005-3-300x173.jpg 300w\" sizes=\"(max-width: 575px) 100vw, 575px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch2\u003EControle do processo e segregação de papéis\u003C\u002Fh2\u003E\n\u003Cp\u003EEm um ambiente regulado, é necessário que os controles internos implementados nos processos sejam seguidos e qualquer mudança relacionada a esses controles sejam devidamente registradas e controladas.\u003C\u002Fp\u003E\n\u003Cp\u003EUma pessoa de um determinado time pode receber diferentes atribuições, principalmente quando se trata de desenvolvimento ágil, portanto o processo que orienta o desenvolvimento de sistemas deve permitir a segregação clara dos papéis e responsabilidades de acesso. Existem determinadas regras a serem seguidas quando se trata da definição de papéis e responsabilidades. Por exemplo:\u003C\u002Fp\u003E\n\u003Cp\u003EA utilização de usuários genéricos para realizar diferentes operações como desenvolvimento de código, testes ou aprovação não é permitida para manter o controle do ambiente. Outro exemplo seria termos o aprovador de uma user story responsável pela tarefa de desenvolvimento desta ou mesmo uma mesma pessoa testar o trabalho que ela tenha desenvolvido.\u003C\u002Fp\u003E\n\u003Cp\u003EO auditor quer ver:\u003C\u002Fp\u003E\n\u003Col\u003E\n\u003Cli\u003EO balanceamento sobre os papéis e responsabilidades executadas pelos times.\u003C\u002Fli\u003E\n\u003Cli\u003EComo a configuração do processo e controles estão definidos.\u003C\u002Fli\u003E\n\u003Cli\u003EQuais mudanças feitas, por quem, quando e quem autorizou (como estava antes e como está depois).\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cp\u003EA ferramenta deve estar preparada para:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EPermitir a definição do processo de desenvolvimento e suas devidas regras:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=46115\" rel=\"attachment wp-att-46115\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-46115\" alt=\"image006 (2)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage006-2.jpg\" width=\"497\" height=\"286\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage006-2.jpg 497w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage006-2-300x172.jpg 300w\" sizes=\"(max-width: 497px) 100vw, 497px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=46116\" rel=\"attachment wp-att-46116\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-46116\" alt=\"image007 (2)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage007-2.jpg\" width=\"414\" height=\"245\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage007-2.jpg 414w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage007-2-300x177.jpg 300w\" sizes=\"(max-width: 414px) 100vw, 414px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E Permitir a configuração de regras que controlam a violação dos requisitos de segurança a serem auditados:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=46117\" rel=\"attachment wp-att-46117\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-46117\" alt=\"image008 (2)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage008-2.jpg\" width=\"580\" height=\"340\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage008-2.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage008-2-300x175.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=46118\" rel=\"attachment wp-att-46118\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-46118\" alt=\"image009 (3)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage009-3.jpg\" width=\"451\" height=\"306\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage009-3.jpg 451w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage009-3-300x203.jpg 300w\" sizes=\"(max-width: 451px) 100vw, 451px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EControlar o histórico de mudanças das definições do processo a ser seguido pelos times:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=46119\" rel=\"attachment wp-att-46119\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-46119\" alt=\"image010 (2)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage010-2.jpg\" width=\"565\" height=\"292\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage010-2.jpg 565w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage010-2-300x155.jpg 300w\" sizes=\"(max-width: 565px) 100vw, 565px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"1.7.Conclusão|outline\"\u003E\u003C\u002Fa\u003EConclusão\u003C\u002Fh2\u003E\n\u003Cp\u003EO objetivo deste artigo foi mostrar que as normas regulatórias aqui citadas estão relacionadas à transações que afetam ativos da empresa. Em uma instituição financeira onde grande parte dos os processos de negócio estão automatizados por uma ferramenta de software, o papel de TI passa a ser fundamental para o atendimento destes requisitos, ressaltando que nenhuma ferramenta de software poderá de forma individual e exclusiva tornar a empresa compatível com SOX.\u003C\u002Fp\u003E\n\u003Cp\u003EDe uma forma resumida para ajudarmos no entendimento destas normas, do ponto de vista do desenvolvedor precisamos entender que é necessário:\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cem\u003E“Dizer o que você faz:”\u003C\u002Fem\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003ETer evidências documentadas que você possui um processo completo, bem comunicado e de fácil compreensão, definido para construir seu código\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Cem\u003E“Fazer o que você diz:”\u003C\u002Fem\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EUtilize o processo definido, bem como seus controles\u003C\u002Fli\u003E\n\u003Cli\u003ECapture e aprove seus requisitos com integridade\u003C\u002Fli\u003E\n\u003Cli\u003ERastreie seus requisitos da implementação ao teste\u003C\u002Fli\u003E\n\u003Cli\u003EGerencie suas entregas de software para prevenir mudanças não autorizadas\u003C\u002Fli\u003E\n\u003Cli\u003EUtilize os controles de mudanças do seu processo bem como a utilização de métricas de execução e monitoração de uso\u003C\u002Fli\u003E\n\u003Cli\u003EAutomatize o seu processo para garantir que suas regras serão seguidas\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Cem\u003E“Esteja preparado para provar”\u003C\u002Fem\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EUtilize um ambiente de desenvolvimento colaborativo onde será possível documentar evidências e histórico de aderência aos controles internos através de dashboards, relatórios, histórico de eventos para o processo de auditoria.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch2\u003E\u003Ca name=\"1.8.Referência|outline\"\u003E\u003C\u002Fa\u003EReferência\u003C\u002Fh2\u003E\n\u003Cul\u003E\n\u003Cli\u003ESoftware Development Compliance for Regulated Industries\u003Cbr \u002F\u003E\nNik Teshima – Rational IT Risk Management and Compliance Solution Lead\u003C\u002Fli\u003E\n\u003Cli\u003EDisciplined Agile Delivery\u003Cbr \u002F\u003E\n\u003Ca href=\"https:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fmydeveloperworks\u002Fblogs\u002Fambler\u002Fentry\u002Fdisciplined_agile_delivery?lang=en_us\"\u003Ehttps:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fmydeveloperworks\u002Fblogs\u002Fambler\u002Fentry\u002Fdisciplined_agile_delivery?lang=en_us\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003Cli\u003EDisciplined Agile Delivery (DAD) Lifecycles\u003Cbr \u002F\u003E\n\u003Ca href=\"https:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fmydeveloperworks\u002Fblogs\u002Fambler\u002Fentry\u002Fdisciplined_agile_delivery_dad_lifecycle14?lang=en\"\u003Ehttps:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fmydeveloperworks\u002Fblogs\u002Fambler\u002Fentry\u002Fdisciplined_agile_delivery_dad_lifecycle14?lang=en\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003Cli\u003ESurviving SOX with Scrum\u003Cbr \u002F\u003E\nSimon Roberts MBA and. Dr. Christoph Mathis – Scrum Alliance\u003Cbr \u002F\u003E\n\u003Ca href=\"http:\u002F\u002Fwww.scrumalliance.org\u002F\"\u003Ehttp:\u002F\u002Fwww.scrumalliance.org\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003Cli\u003EDisciplined Agile Delivery (DAD) Lifecycles\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fmydeveloperworks\u002Fblogs\u002Fambler\u002Fentry\u002Fdisciplined_agile_delivery_dad_lifecycle14?lang=en_us\"\u003Ehttps:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fmydeveloperworks\u002Fblogs\u002Fambler\u002Fentry\u002Fdisciplined_agile_delivery_dad_lifecycle14?lang=en_us\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E***\u003C\u002Fp\u003E\n\u003Cp\u003ESobre a autora: Sandra Sergi Santos é formada pela Universidade Mackenzie e Pós-graduada pela FAAP, atua na área de desenvolvimento de sistemas a 15 anos . Certificada em Scrum Master, RUP (Rational Unified Process) , PMP (Project Management Professional), Gerência de Requisitos e Gerência de Configuração de Mudanças (IBM Rational Team Concert, Requirements Composer, Clearcase e Clearquest). Atualmente trabalha como Especialista em Engenharia de Software na brand Rational da IBM Brasil.\u003C\u002Fp\u003E\n\u003Cp\u003E***\u003C\u002Fp\u003E\n\u003Cp\u003EA versão original deste artigo está em: \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Flocal\u002Frational\u002Fagile_projects_compliance_reqs\u002Findex.html\"\u003Ehttp:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Flocal\u002Frational\u002Fagile_projects_compliance_reqs\u002Findex.html\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n","excerpt":"\u003Cp\u003EVamos focar este artigo nos principais itens regulatórios de instituições financeiras.\u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fagile\u002Fcomo-sobreviver-com-requisitos-de-compliance-em-projetos-ageis","date":"15 ago, 2013","thumbnail":"","externalMention":null,"author":{"id":421,"thumbnail":"https:\u002F\u002Fsecure.gravatar.com\u002Favatar\u002Fbe5bc6f39606ac453a07bd2eb7ab21af?s=96&d=mm&r=g","name":"developerWorks Brasil","description":"é o portal de tecnologia da IBM para profissionais de TI de todo o mundo. Colabore, aprenda a criar aplicativos inovadores e compreenda tecnologias avançadas. Acesse mais artigos e tutoriais em www.ibm.com\u002Fdeveloperworks\u002Fbr","slug":"developerworks_brasil","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdeveloperworks_brasil","registered":"2010-07-07 17:06:45","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002Fsoudw","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002F","mail":"dwbr@br.ibm.com"},"articles_count":217,"views_count":4709798,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"Agile","slug":"agile","id":7247,"link":"https:\u002F\u002Fimasters.com.br\u002Fagile"},{"title":"DevSecOps","slug":"devsecops","id":1,"link":"https:\u002F\u002Fimasters.com.br\u002Fdevsecops"},{"title":"Gerência de Projetos Dev & TI","slug":"gerencia-de-projetos-dev-e-ti","id":7246,"link":"https:\u002F\u002Fimasters.com.br\u002Fgerencia-de-projetos-dev-e-ti"}],"tags":[{"title":"agile","slug":"agile-2","id":358,"link":"https:\u002F\u002Fimasters.com.br\u002Fagile-2"},{"title":"compliance","slug":"compliance","id":2021,"link":"https:\u002F\u002Fimasters.com.br\u002Fcompliance"},{"title":"gerência de TI","slug":"gerencia-de-ti-2","id":221,"link":"https:\u002F\u002Fimasters.com.br\u002Fgerencia-de-ti-2"},{"title":"instituições financeiras","slug":"instituicoes-financeiras","id":2023,"link":"https:\u002F\u002Fimasters.com.br\u002Finstituicoes-financeiras"},{"title":"projetos ágeis","slug":"projetos-ageis","id":2022,"link":"https:\u002F\u002Fimasters.com.br\u002Fprojetos-ageis"}],"seo":{"open_graph":{"title":"Como sobreviver com requisitos de compliance em projetos ágeis? - iMasters - We are Developers","description":"Vamos focar este artigo nos principais itens regulatórios de instituições financeiras.","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":false,"modified_time":"2013-08-14T13:50:53-03:00","published_time":"2013-08-15T09:00:03-03:00"},"twitter":{"title":"Como sobreviver com requisitos de compliance em projetos ágeis? - iMasters - We are Developers","description":"Vamos focar este artigo nos principais itens regulatórios de instituições financeiras.","type":"summary_large_image","image":false}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fagile\u002Fcomo-sobreviver-com-requisitos-de-compliance-em-projetos-ageis","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fagile\u002Fcomo-sobreviver-com-requisitos-de-compliance-em-projetos-ageis","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fagile\u002Fcomo-sobreviver-com-requisitos-de-compliance-em-projetos-ageis"},"type":"post"},{"id":45850,"title":"Saindo do básico com Git","content":"\u003Cp\u003EGit é um sistema de controle de versão reconhecidamente poderoso e flexível para usuário. Entretanto para se ter acesso a todo esse poder ou ao menos parte dele é essencial dominar alguns comandos. Sem um ferramental, mínimo é muito comum sentir-se travado, vítima de sua própria ferramenta. Esse artigo, pretender trazer conceitos e comandos na sua maioria de nível intermediário a um usuário que já tenha uma certa experiência com Git.\u003C\u002Fp\u003E\n\u003Cp\u003EQuando trabalha-se no dia a dia com um projeto Git, é muito comum fazer um \u003Cem\u003Ecommit\u003C\u002Fem\u003E de algumas mudanças mesmo que elas ainda não estejam prontas para um \u003Cem\u003Ecode review\u003C\u002Fem\u003E ou para serem integradas em uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E de referência. Por isso, é muito importante que o usuário sinta-se confortável com os comandos capazes de reescrever o histórico no escopo de sua \u003Cem\u003Ebranch\u003C\u002Fem\u003Ede desenvolvimento. Pode ser interessante simplesmente mudar a mensagem de \u003Cem\u003Ecommit\u003C\u002Fem\u003E ou até mesmo quebrar um \u003Cem\u003Ecommit\u003C\u002Fem\u003Eanterior em vários menores.\u003C\u002Fp\u003E\n\u003Cp\u003EUm outro ponto importante deve-se a natureza distribuída de Git em que o desenvolvimento ocorre paralelamente em múltiplas \u003Cem\u003Ebranches\u003C\u002Fem\u003E, sendo assim é de suma importância saber como combinar os múltiplos \u003Cem\u003Ecommits\u003C\u002Fem\u003E com toda a flexibilidade possível. Pode ser interessante aplicar os \u003Cem\u003Ecommits\u003C\u002Fem\u003E de uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E no topo de outra ou até ir alem ao pegar uma “fatia” de \u003Cem\u003Ecommits\u003C\u002Fem\u003E de uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E e aplicá-la em outra.\u003C\u002Fp\u003E\n\u003Cp\u003EEssas duas habilidades de reescrever o histórico e rearranjar os \u003Cem\u003Ecommits\u003C\u002Fem\u003E já trazem uma boa parte do poder de Git ao domínio do usuário. Consequentemente, elas serão tratadas mais a fundo nesse artigo.\u003C\u002Fp\u003E\n\u003Cdiv\u003E\n\u003Ch2\u003E\u003Ca name=\"N100C3\"\u003E\u003C\u002Fa\u003ERecapitulando conceitos básicos\u003C\u002Fh2\u003E\n\u003Cp\u003ENesta seção recapitularemos alguns conceitos e comandos básicos necessário à uma melhor compreensão do restante do artigo. O leitor que sentir-se mais confiante pode optar por ir diretamente à próxima seção.\u003C\u002Fp\u003E\n\u003Cp\u003ECom apenas pouco tempo de Git já é possível notar a presença de longas cadeias hexadecimais por toda parte. Essas cadeias são o resultado da função de \u003Cem\u003Ehash\u003C\u002Fem\u003E SHA-1 que resulta em 40 casas hexadecimais. Elas são de extrema importância, visto que Git é, em essência, um repositório de objetos em que cada sequência SHA-1 mapeia a um objeto. Como em um dicionário Python, uma \u003Cem\u003Ehash\u003C\u002Fem\u003E Perl ou HashMap Java, é esse número que nos leva ao objeto desejado.\u003C\u002Fp\u003E\n\u003Cp\u003EInformações e meta-informações do repositório git são em geral armazenadas em objetos no diretorio “.git\u002Fobjects” (exceto no caso de compactação). Esses objetos podem ser de vários tipos: \u003Cem\u003Eblobs, trees, commits\u003C\u002Fem\u003E e \u003Cem\u003Etags\u003C\u002Fem\u003E. Os \u003Cem\u003Eblobs \u003C\u002Fem\u003Ecomo em base de dados SQL são capazes de armazenar qualquer tipo de informação como por exemplo o contudo de um arquivo. Já o objeto \u003Cem\u003Etree\u003C\u002Fem\u003E é muito semelhante a um diretório, podendo apontar para \u003Cem\u003Eglobs\u003C\u002Fem\u003E e recursivamente para outros objetos \u003Cem\u003Etrees\u003C\u002Fem\u003E. Os outros dois últimos objetos estão mais relacionados às meta-informações do controle de versão. É sabido que cada \u003Cem\u003Ecommit\u003C\u002Fem\u003E representa uma foto do estado do repositório. Por isso, cada um deles aponta para um objeto do tipo \u003Cem\u003Etree\u003C\u002Fem\u003E cujas entradas são \u003Cem\u003Eblobs \u003C\u002Fem\u003Erepresentando o conteúdo dos arquivos naquele momento ou outros \u003Cem\u003Etrees\u003C\u002Fem\u003E representando os diretórios do repositório e assim recursivamente. Por fim, tem-se o objeto t\u003Cem\u003Eag\u003C\u002Fem\u003E que permite fazer uma referência a um \u003Cem\u003Ecommit\u003C\u002Fem\u003E, por exemplo, usando uma \u003Cem\u003Estring\u003C\u002Fem\u003Emais amigável do que o SHA-1.\u003C\u002Fp\u003E\n\u003Cp\u003EComo cada um dos objetos vistos anteriormente possui um \u003Cem\u003Ehash\u003C\u002Fem\u003E associado fica claro que ele desempenha um papel fundamental no Git, mesmo que nem sempre o manipulamos diretamente. Lidar com um número hexadecimal de 40 dígitos pode não ser muito prático, por isso existe a liberdade de utilizar seus prefixos. Mesmo assim, pode ser mais interessante lidar com uma referência textual. Para cada uma das cabeças de desenvolvimento a funcionalidade de \u003Cem\u003Ebranches\u003C\u002Fem\u003E desempenha esse papel. Uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E nada mais é do que um ponteiro para um \u003Cem\u003Ecommit\u003C\u002Fem\u003E cabeça. Como todo ponteiro que se preze, ele precisa armazenar um endereço, que no caso de Git é o SHA-1. Se inspecionarmos o conteúdo do ponteiro \u003Cem\u003Emaster\u003C\u002Fem\u003E de um repositório é possível notar a presença do \u003Cem\u003Ehash\u003C\u002Fem\u003E. Na nomeclatura de Git denomina-se revisão (rev) um referência arbitrária a um \u003Cem\u003Ecommit\u003C\u002Fem\u003E, seja por \u003Cem\u003Ehash\u003C\u002Fem\u003E, por nome de \u003Cem\u003Ebranch\u003C\u002Fem\u003E ou qualquer outra forma.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ cat .git\u002Frefs\u002Fheads\u002Fmaster \r\nc32ca8a9f01ad9436d28e3abfe36808de2e2ec3f\u003C\u002Fpre\u003E\n\u003Cfigure id=\"attachment_45852\" aria-describedby=\"caption-attachment-45852\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45852\" rel=\"attachment wp-att-45852\"\u003E\u003Cimg class=\"size-full wp-image-45852\" alt=\"image001 (2)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage001-2.jpg\" width=\"580\" height=\"341\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage001-2.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage001-2-300x176.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45852\" class=\"wp-caption-text\"\u003EFigure 1: Representação de um Repositório\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003EQuando se utiliza o comando “git branch <nova_branch>” ou algum outro que crie uma nova \u003Cem\u003Ebranch,\u003C\u002Fem\u003E o que ocorre na realidade é uma simples criação de ponteiro em geral para último \u003Cem\u003Ecommit\u003C\u002Fem\u003E da \u003Cem\u003Ebranch\u003C\u002Fem\u003E corrente. Como cada \u003Cem\u003Ecommit\u003C\u002Fem\u003E guarda consigo apontadores para seus pais, é possível reconstruir todo o histórico até chegar a ele. Além disso, como cada \u003Cem\u003Ecommit\u003C\u002Fem\u003E é uma fotografia, é possível “voltar ao tempo” ou mudar de \u003Cem\u003Ebranch\u003C\u002Fem\u003E usando o comando “git checkout <rev>” – seja com um SHA-1 ou com um nome mais amigável.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git checkout master\u003C\u002Fpre\u003E\n\u003Cp\u003ESe voltarmos usando um SHA-1, nos encontraremos potencialmente sem \u003Cem\u003Ebranch\u003C\u002Fem\u003E, pois não temos um ponteiro para o \u003Cem\u003Ecommit \u003C\u002Fem\u003Edessa nova cabeça . Caso queira iniciar o desenvolvimento a partir desse ponto é recomendável criar uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E (ponteiro). Para isso basta usar:\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git checkout -b <nome_da_branch>\u003C\u002Fpre\u003E\n\u003Cp\u003EAgora que conseguimos nos posicionar com tranquilidade em qualquer parte do histórico, vamos passar para a parte de criar novos \u003Cem\u003Ecommits\u003C\u002Fem\u003E. Antes que um \u003Cem\u003Ecommit\u003C\u002Fem\u003E efetivamente aconteça é necessário que as modificações passem pela \u003Cem\u003Estaging area. \u003C\u002Fem\u003EEssa é uma área em que o programador tem total liberdade de manipulação para que o \u003Cem\u003Ecommit\u003C\u002Fem\u003E saia precisamente da maneira desejada. Após um número suficiente de alterações que devam resultar em um \u003Cem\u003Ecommit\u003C\u002Fem\u003E, use o comando “git status” para entender qual o estado atual de sua arvore de trabalho. Com ele é possível ver quais arquivos foram alterados, renomeados, adicionados, deletados e assim por diante. É possível também ver quais arquivos estão na \u003Cem\u003Estaging area\u003C\u002Fem\u003E prontos para um\u003Cem\u003Ecommit\u003C\u002Fem\u003E. Toda vez que precisar adicionar um arquivo a essa área use:\u003C\u002Fp\u003E\n\u003Cpre\u003Egit add <caminho>\u003C\u002Fpre\u003E\n\u003Cp\u003ESe por acaso estiver arrependido e quiser remover um arquivo da \u003Cem\u003Estaging area\u003C\u002Fem\u003E, mas conservando suas modificações, use o comando de \u003Cem\u003Eunstage,\u003C\u002Fem\u003E que infelizmente não há em uma forma compacta (entretanto, pode-se criar \u003Cem\u003Ealias\u003C\u002Fem\u003E no \u003Cem\u003Eshell\u003C\u002Fem\u003E).\u003C\u002Fp\u003E\n\u003Cpre\u003Egit reset HEAD <caminho>\u003C\u002Fpre\u003E\n\u003Cp\u003ESe estiver insatisfeito com as alterações nesse arquivo e quiser desfazê-las, observe que não haverá volta.\u003C\u002Fp\u003E\n\u003Cpre\u003Egit checkout -- <caminho>\u003C\u002Fpre\u003E\n\u003Cp\u003EObserve que no comando de \u003Cem\u003Eunstage\u003C\u002Fem\u003E foi usado a referência simbólica HEAD (cabeça). HEAD na verdade é um ponteiro de ponteiro que aponta para a variável da \u003Cem\u003Ebranch\u003C\u002Fem\u003E corrente. Sendo assim, esse ponteiro provê muita praticidade já que evita a utilização explícita do nome dessa \u003Cem\u003Ebranch\u003C\u002Fem\u003E.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git symbolic-ref HEAD\r\nrefs\u002Fheads\u002Fmaster\r\n$ git branch\r\n* master\u003C\u002Fpre\u003E\n\u003Ch2\u003E\u003Ca name=\"N101A2\"\u003E\u003C\u002Fa\u003ESalvando modificações temporárias com Stash\u003C\u002Fh2\u003E\n\u003Cp\u003EMuitas vezes estamos no meio do desenvolvimento com árvore de trabalho suja e precisamos corrigir um \u003Cem\u003Ebug\u003C\u002Fem\u003E urgente em outra \u003Cem\u003Ebranch\u003C\u002Fem\u003E. O que fazer? O ideal seria armazenar as modificações em alguma área temporária para retomá-las depois. Visando simplificar esse processo, Git criou a família de comandos “git stash”.\u003C\u002Fp\u003E\n\u003Cp\u003ECom “git status” verificamos que o arquivo a.txt foi modificado, mas ainda não gostaríamos de commitá-lo.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git status\r\n# On branch user\u002Ffeature\r\n# Changed but not updated:\r\n# (use \"git add <file>...\" to update what will be committed)\r\n# (use \"git checkout -- <file>...\" to discard changes in working directory\r\n#\r\n# modified: a.txt\r\n#\r\nno changes added to commit (use \"git add\" and\u002For \"git commit -a\")\u003C\u002Fpre\u003E\n\u003Cp\u003ECom o “git stash” salvamos essa modificações e com isso o diretório de trabalho fica limpo. Dessa forma estamos prontos para mudar para outra \u003Cem\u003Ebranch\u003C\u002Fem\u003E.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git stash\r\nSaved working directory and index state WIP on user\u002Ffeature: f0be6e8 File\r\nHEAD is now at f0be6e8 File\r\n$ git status\r\n# On branch user\u002Ffeature\r\nnothing to commit (working directory clean)\u003C\u002Fpre\u003E\n\u003Cp\u003EDepois de feita a correção do \u003Cem\u003Ebug\u003C\u002Fem\u003E crítico, voltamos a \u003Cem\u003Ebranch\u003C\u002Fem\u003E de desenvolvimento. Agora vamos ver a pilha de \u003Cem\u003Estash\u003C\u002Fem\u003E e como não criamos nenhum outro nesse meio tempo, ele será o último. Nesse caso, “stash@{0}”.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git stash list\r\nstash@{0}: WIP on user\u002Ffeature: f0be6e8 File\u003C\u002Fpre\u003E\n\u003Cp\u003EVamos aplicar o \u003Cem\u003Estash\u003C\u002Fem\u003E salvo e confirmar que o arquivo a.txt foi atualizado.\u003C\u002Fp\u003E\n\u003Cpre\u003E>git stash apply stash@{0}\r\n# On branch user\u002Ffeature\r\n# Changed but not updated:\r\n# (use \"git add <file>...\" to update what will be committed)\r\n# (use \"git checkout -- <file>...\" to discard changes in working directory)\r\n#\r\n# modified: a.txt\r\n#\r\nno changes added to commit (use \"git add\" and\u002For \"git commit -a\")\u003C\u002Fpre\u003E\n\u003Ch2\u003E\u003Ca name=\"N101DB\"\u003E\u003C\u002Fa\u003EReescrevendo o histórico\u003C\u002Fh2\u003E\n\u003Cp\u003EReescrever o histórico no escopo de uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E pode ser importante por vários motivos como reordenar alguns \u003Cem\u003Ecommits\u003C\u002Fem\u003E, melhorar algumas mensagens, quebrar \u003Cem\u003Ecommits\u003C\u002Fem\u003E grandes em partes atômicas ou até mesmo juntar \u003Cem\u003Ecommits\u003C\u002Fem\u003E de uma mesma funcionalidade. Alguma dessas necessidades pode surgir como resultado de \u003Cem\u003Ecode review\u003C\u002Fem\u003E ou até mesmo devido ao processo de desenvolvimento não ser completamente previsível. Por isso, é muito importante contar com um sistema de controle de versão flexível como Git.\u003C\u002Fp\u003E\n\u003Cp\u003EÉ importante notar que o histórico só deve ser reescrito em faixas de \u003Cem\u003Ecommits\u003C\u002Fem\u003E criadas localmente e que ainda não foram publicadas, ou seja, que ainda não foram potencialmente integradas por outro usuário. Toda vez que parte do histórico é reescrita novos objetos de \u003Cem\u003Ecommit\u003C\u002Fem\u003E com SHA-1 completamente diferentes dos antigos são criados o que pode conflitar com os antigos \u003Cem\u003Ecommits\u003C\u002Fem\u003E que foram incorporados por outro usuário.\u003C\u002Fp\u003E\n\u003Cp\u003EUm dos motivos que torna a remoção forçada de um \u003Cem\u003Ecommit\u003C\u002Fem\u003E de uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E de referência algo altamente indesejado é justamente o conflito que poderá ocorrer com outros usuário que potencialmente já incorporaram esse \u003Cem\u003Ecommit\u003C\u002Fem\u003E. Por isso é mais recomendável usar “git revert” que criará um novo \u003Cem\u003Ecommit\u003C\u002Fem\u003E desfazendo alterações anteriores.\u003C\u002Fp\u003E\n\u003Cp\u003ECom certos cuidados em mente, vamos agora ao ferramental para manipular o histórico. Se estiver inseguro com relação às mudanças, pode ser interessante criar uma outra \u003Cem\u003Ebranch\u003C\u002Fem\u003E (“git checkout -b <nome_da_branch>”) para mudar o histórico, deixando a \u003Cem\u003Ebranch\u003C\u002Fem\u003E original intacta.\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"N10216\"\u003E\u003C\u002Fa\u003EMudando a mensagem do último \u003Cem\u003Ecommit\u003C\u002Fem\u003E\u003C\u002Fh2\u003E\n\u003Cp\u003EUma das alterações mais simples é a mudança da mensagem do último \u003Cem\u003Ecommit\u003C\u002Fem\u003E. Muitas vezes percebemos um erro de ortografia ou simplesmente queremos melhorá-la. Antes vamos fazer um pequeno desvio para assegurar um mínimo de configuração. Certifique-se que seu editor preferido está configurado.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git config --global core.editor\r\nvi\u003C\u002Fpre\u003E\n\u003Cp\u003EAs configurações são um conjunto de chaves (keys) e valores (\u003Cem\u003Evalues\u003C\u002Fem\u003E) sendo o comando “git config” capaz de exibir o valor de uma chave ou alterá-lo quando se passa mais um argumento para o comando anterior, que é justamente o novo valor. Observe que a opção “–goblal” faz com que as alterações fiquem disponíveis para todos os repositório daquele usuário na máquina em questão.\u003C\u002Fp\u003E\n\u003Cpre\u003Egit config --global core.editor \"emacs -nw\"\u003C\u002Fpre\u003E\n\u003Cp\u003ENão se esqueça também de incluir o nome e o email, já que eles são muito importante para atribuir os créditos e as responsabilidades do \u003Cem\u003Ecommiter\u003C\u002Fem\u003E.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git config --global user.name \"Meu Nome\"\r\n$ git config --global user.email 'meuemail@meudominio.com'\u003C\u002Fpre\u003E\n\u003Cp\u003EAgora vamos, voltar ao nosso propósito original que era o comando para edição da mensagem do ultimo \u003Cem\u003Ecommit\u003C\u002Fem\u003E.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git commit –amend\u003C\u002Fpre\u003E\n\u003Cp\u003EAgora será aberto automaticamente seu editor preferido. Basta reescrever a mensagem da forma desejada, salvar as alterações e sair do editor. Repare que o SHA-1 do \u003Cem\u003Ecommit\u003C\u002Fem\u003E foi alterado. Pode-se conferir o resultado com “git log”.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git log\u003C\u002Fpre\u003E\n\u003Cp\u003ESe preferir o conforto de uma interface gráfica é possível usar programas como o gitk.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ gitk\u003C\u002Fpre\u003E\n\u003Ch2\u003E\u003Ca name=\"N10256\"\u003E\u003C\u002Fa\u003ERebase interativo\u003C\u002Fh2\u003E\n\u003Cp\u003ESem dúvida o comando de dia a dia mais importante para reescrever o histórico no escopo de uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E é o \u003Cem\u003Erebase \u003C\u002Fem\u003Einterativo. Com ele é possível fazer praticamente qualquer alteração em uma faixa de \u003Cem\u003Ecommits\u003C\u002Fem\u003E. Para usá-lo é necessário passar como referência um \u003Cem\u003Ecommit\u003C\u002Fem\u003E de base, já que os \u003Cem\u003Ecommits\u003C\u002Fem\u003E filhos até o \u003Cem\u003Ecommit\u003C\u002Fem\u003E cabeça (apontado indiretamente por HEAD) serão mostrados para manipulação. Se por exemplo pegarmos o pai do antepenúltimo \u003Cem\u003Ecommit,\u003C\u002Fem\u003E cujo prefixo de SHA-1 é 0bc7ae0, podemos usar esse comando da seguinte maneira (note a presença do “-i”):\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git rebase -i 0bc7ae0\u003C\u002Fpre\u003E\n\u003Cp\u003ECom isso, um editor será laçado mostrando os \u003Cem\u003Ecommits\u003C\u002Fem\u003E a partir de 0bc7ae0 até o \u003Cem\u003Ecommit\u003C\u002Fem\u003E cabeça (inclusive). Note que essa ordem é a inversa da mostrada por “git log”. Como sempre o Git tentará ajudar colocando informações em comentários, linhas começadas por ‘#’. Vamos analisar cada um desses comandos por vez.\u003C\u002Fp\u003E\n\u003Cpre\u003Epick dd33a13 Meu Antepenúltimo Commit \r\npick f6bd651 Meu Penúltimo Commit \r\npick e33196d Meu Último Commit \r\n\r\n# Rebase 0bc7ae0..e33196d onto 0bc7ae0 \r\n# \r\n# Commands: \r\n# p, pick = use commit \r\n# r, reword = use commit, but edit the commit message \r\n# e, edit = use commit, but stop for amending \r\n# s, squash = use commit, but meld into previous commit \r\n# f, fixup = like \"squash\", but discard this commit's log message \r\n# \r\n# If you remove a line here THAT COMMIT WILL BE LOST. \r\n# However, if you remove everything, the rebase will be aborted. \r\n#\u003C\u002Fpre\u003E\n\u003Ch3\u003EPick\u003C\u002Fh3\u003E\n\u003Cp\u003EO comando \u003Cem\u003Epick,\u003C\u002Fem\u003E do inglês “pegar”, informa que o \u003Cem\u003Ecommit\u003C\u002Fem\u003E especificado pelo prefixo de SHA-1 será conservado. Observe que esse é o comportamento padrão. Para simplificar ainda mais, Git permite que seja usado a primeira letra ao invés do nome inteiro de cada comando.\u003C\u002Fp\u003E\n\u003Ch3\u003EReword\u003C\u002Fh3\u003E\n\u003Cp\u003EEsse é um atalho relativamente novo e que permite mudar o texto de um \u003Cem\u003Ecommit\u003C\u002Fem\u003E. Lembra-se do “git commit –amend” que permitia mudar a mensagem do ultimo \u003Cem\u003Ecommit?\u003C\u002Fem\u003E Com o \u003Cem\u003Ereword\u003C\u002Fem\u003E podemos mudar qualquer mensagem que esteja dentro da faixa do nosso \u003Cem\u003Erebase\u003C\u002Fem\u003E interativo inclusive do último. Dessa forma, temos uma versão mais poderosa do comando visto anteriormente. Antes de \u003Cem\u003Ereword\u003C\u002Fem\u003E existir era necessário passar por uma combinação de outros comandos como veremos a seguir.\u003C\u002Fp\u003E\n\u003Ch3\u003EEdit\u003C\u002Fh3\u003E\n\u003Cp\u003EEsse comando é bem poderoso, permitindo voltar no tempo à fotografia do \u003Cem\u003Ecommit\u003C\u002Fem\u003E que deseja-se editar, depois pode-se realizar qualquer tipo de alteração e potencialmente reaplicar os \u003Cem\u003Ecommits\u003C\u002Fem\u003E mais novos da faixa de \u003Cem\u003Erebase \u003C\u002Fem\u003Einterativo. Como o próprio nome indica um rebase interativo pode ser formado por algumas interações de mudança de histórico. Para navegar de nesse processo de potencialmente múltiplas etapas, o comando “git rebase –continue” indica que a etapa corrente pode ser encerrada, já o comando “git rebase –abort” serve para se desistir de todo processo.\u003C\u002Fp\u003E\n\u003Cp\u003EVamos passar agora para alguns exemplos que ilustram a utilização de \u003Cem\u003Eedit\u003C\u002Fem\u003E. Suponha que o comando \u003Cem\u003Ereword\u003C\u002Fem\u003E não existe, como você poderia criá-lo? Sabemos que com o \u003Cem\u003Eedit\u003C\u002Fem\u003E podemos voltar ao tempo para um \u003Cem\u003Ecommit\u003C\u002Fem\u003E que se deseja editar, e o processo interativo para com esse \u003Cem\u003Ecommi\u003C\u002Fem\u003Et sendo o mais recente do histórico. Com isso basta aplicar o velho conhecido “git commit –amend”, já que ele é capaz de modificar o último \u003Cem\u003Ecommit,\u003C\u002Fem\u003E que no caso é o \u003Cem\u003Ecommit\u003C\u002Fem\u003E especificado no comando \u003Cem\u003Eedit\u003C\u002Fem\u003E. Para dar continuidade ao processo iterativo não se esqueça de usar o “git rebase –continue”. Com isso, os \u003Cem\u003Ecommits\u003C\u002Fem\u003E mais recentes que o \u003Cem\u003Ecommit\u003C\u002Fem\u003E editado serão aplicados ao seu topo.\u003C\u002Fp\u003E\n\u003Cp\u003EVamos agora para um caso um pouco mais interessante, e se quisermos quebrar um \u003Cem\u003Ecommit\u003C\u002Fem\u003E em vários menores\u003Cem\u003E?\u003C\u002Fem\u003E Voltar no tempo podendo reaplicar \u003Cem\u003Ecommits\u003C\u002Fem\u003E mais novos de forma automática já está claro usando o comando \u003Cem\u003Eedit\u003C\u002Fem\u003E.\u003C\u002Fp\u003E\n\u003Cp\u003ENo caso usamos o \u003Cem\u003Ecommi\u003C\u002Fem\u003Et cinza como base para o rebase.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git rebase -i 0bc7ae0\u003C\u002Fpre\u003E\n\u003Cp\u003ENo editor vamos apenas mudar a opção de \u003Cem\u003Epick\u003C\u002Fem\u003E para \u003Cem\u003Eedit\u003C\u002Fem\u003E na linha do penúltimo \u003Cem\u003Ecommit\u003C\u002Fem\u003E (note que poderíamos perfeitamente usar como base o \u003Cem\u003Ecommit\u003C\u002Fem\u003E HEAD~2).\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45856\" rel=\"attachment wp-att-45856\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-45856\" alt=\"image002 (1)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage002-1.jpg\" width=\"580\" height=\"266\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage002-1.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage002-1-300x137.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003ECom isso voltaremos no tempo, para a fotografia do penúltimo \u003Cem\u003Ecommit\u003C\u002Fem\u003E. Sendo que o \u003Cem\u003Ecommit\u003C\u002Fem\u003E marcado para edição encontra-se no topo do histórico.\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45857\" aria-describedby=\"caption-attachment-45857\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45857\" rel=\"attachment wp-att-45857\"\u003E\u003Cimg class=\"size-full wp-image-45857\" alt=\"Figure 3: Etapa de Edit\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage003-1.jpg\" width=\"580\" height=\"212\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage003-1.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage003-1-300x109.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45857\" class=\"wp-caption-text\"\u003EFigure 3: Etapa de Edit\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003EAgora basta combinar outro comando capaz de quebrar um \u003Cem\u003Ecommit\u003C\u002Fem\u003E e deixar suas alterações na árvore de trabalho. Esse último comando é o “git reset”:\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git reset HEAD^1\u003C\u002Fpre\u003E\n\u003Cp\u003EObserve que com o HEAD^1 estamos referenciando o \u003Cem\u003Ecommit\u003C\u002Fem\u003E anterior ao HEAD. Quando o \u003Cem\u003Ecommit\u003C\u002Fem\u003E corrente for resultado de um \u003Cem\u003Emerge\u003C\u002Fem\u003E (caso em que há múltiplos pais), HEAD^n quer dizer o \u003Cem\u003En\u003C\u002Fem\u003E-ésimo pai. Entretanto, para acessar níveis mais profundos do histórico como avô e bisavô é possível usar HEAD~n com \u003Cem\u003En\u003C\u002Fem\u003E igual a 2 e 3 respectivamente (nesse caso se houver múltiplos pais sempre é escolhido o primeiro). Note que HEAD^1 e equivalente a HEAD~1.\u003C\u002Fp\u003E\n\u003Cp\u003EAgora basta fazer um “git status” para ver que as alterações introduzidas pelo antigo \u003Cem\u003Ecommit\u003C\u002Fem\u003E HEAD estão de fato espalhadas na árvore de trabalho. Com “git log”, vemos que o antigo \u003Cem\u003Ecommit\u003C\u002Fem\u003E HEAD sumiu dando lugar ao seu pai como mais recente.\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45858\" aria-describedby=\"caption-attachment-45858\" style=\"width: 502px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45858\" rel=\"attachment wp-att-45858\"\u003E\u003Cimg class=\"size-full wp-image-45858\" alt=\"Figure 4: Após quebrar o commit de topo\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage004-2.jpg\" width=\"502\" height=\"214\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage004-2.jpg 502w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage004-2-300x127.jpg 300w\" sizes=\"(max-width: 502px) 100vw, 502px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45858\" class=\"wp-caption-text\"\u003EFigure 4: Após quebrar o commit de topo\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003EAgora basta adicionar as mudanças com “git add” para colocá-las na \u003Cem\u003Estaging area\u003C\u002Fem\u003E e efetivamente fazer o \u003Cem\u003Ecommit\u003C\u002Fem\u003E, com a mesma liberdade de sempre. No exemplo, geramos dois novos \u003Cem\u003Ecommits:\u003C\u002Fem\u003E “Novo 1” e “Novo 2”.\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45859\" aria-describedby=\"caption-attachment-45859\" style=\"width: 502px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45859\" rel=\"attachment wp-att-45859\"\u003E\u003Cimg class=\"size-full wp-image-45859\" alt=\"Figure 5: Dois novos commits criados\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage005-2.jpg\" width=\"502\" height=\"392\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage005-2.jpg 502w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage005-2-300x234.jpg 300w\" sizes=\"(max-width: 502px) 100vw, 502px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45859\" class=\"wp-caption-text\"\u003EFigure 5: Dois novos commits criados\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003ESe estiver contente com o resultado, basta continuar o processo com:\u003C\u002Fp\u003E\n\u003Cpre\u003E  $ git rebase –continue\u003C\u002Fpre\u003E\n\u003Cp\u003ESe estiver arrependido, não tem problema; basta fazer:\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git rebase –abort\u003C\u002Fpre\u003E\n\u003Cp\u003ECom o “git rebase –continue”, o processo continua. No caso tínhamos escolhido conservar o ultimo \u003Cem\u003Ecommit\u003C\u002Fem\u003E, por isso ele é aplicado automaticamente no topo de “Novo 2”.\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45860\" aria-describedby=\"caption-attachment-45860\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45860\" rel=\"attachment wp-att-45860\"\u003E\u003Cimg class=\"size-full wp-image-45860\" alt=\"Figure 6: Último pick é aplicado ao topo\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage006-1.jpg\" width=\"580\" height=\"341\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage006-1.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage006-1-300x176.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45860\" class=\"wp-caption-text\"\u003EFigure 6: Último pick é aplicado ao topo\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Ch3\u003ESquash\u003C\u002Fh3\u003E\n\u003Cp\u003EAprendemos como quebrar um \u003Cem\u003Ecommit\u003C\u002Fem\u003E em vários, porém é possível fazer o caminho inverso: combinar vários \u003Cem\u003Ecommits\u003C\u002Fem\u003E em um único. Para isso pode-se usar o comando \u003Cem\u003Esquash\u003C\u002Fem\u003E. Cada \u003Cem\u003Ecommit\u003C\u002Fem\u003E marcado para \u003Cem\u003Esquash\u003C\u002Fem\u003E será combinado com o \u003Cem\u003Ecommit\u003C\u002Fem\u003E anterior. E para cada \u003Cem\u003Ecommit\u003C\u002Fem\u003E resultante será mostrado um editor, para que as mensagens dos \u003Cem\u003Ecommits\u003C\u002Fem\u003E envolvidos possam ser aproveitadas da melhor maneira possível.\u003C\u002Fp\u003E\n\u003Cp\u003EÉ possível combinar os três últimos \u003Cem\u003Ecommits\u003C\u002Fem\u003E da seguinte forma:\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git rebase -i  0bc7ae0\u003C\u002Fpre\u003E\n\u003Cp\u003EUsamos \u003Cem\u003Epick\u003C\u002Fem\u003E para o antepenúltimo \u003Cem\u003Ecommit\u003C\u002Fem\u003E para que os dois mais recentes se fundam a ele com \u003Cem\u003Esquash\u003C\u002Fem\u003E.\u003C\u002Fp\u003E\n\u003Cpre\u003Epick dd33a13 Meu Antepenúltimo Commit \r\nsquash f6bd651 Meu Penúltimo Commit \r\nsquash e33196d Meu Último Commit\u003C\u002Fpre\u003E\n\u003Cp\u003EEssa operação resultará em apenas um único \u003Cem\u003Ecommit\u003C\u002Fem\u003E e na tela do editor, poderão ser vistas as três mensagens.\u003C\u002Fp\u003E\n\u003Cpre\u003E# This is a combination of 3 commits. \r\n# The first commit's message is: \r\nMeu Antepenúltimo Commit\r\n\r\n# This is the 2nd commit message:\r\n\r\nMeu Penúltimo Commit \r\n\r\n# This is the 3rd commit message: \r\n\r\nMeu Último Commit\u003C\u002Fpre\u003E\n\u003Ch3\u003EFixup\u003C\u002Fh3\u003E\n\u003Cp\u003EUm outro comando também relativamente recente é o \u003Cem\u003Efixup,\u003C\u002Fem\u003E que assim como o \u003Cem\u003Ereword\u003C\u002Fem\u003E, ele nada mais é do que um atalho. No desenvolvimento é muito comum fazer alguma correção relativa a um \u003Cem\u003Ecommit\u003C\u002Fem\u003E anterior e que por isso deve ser integrada a ele. Como o \u003Cem\u003Ecommit\u003C\u002Fem\u003E que contem a correção vai ser integrado ao \u003Cem\u003Ecommit\u003C\u002Fem\u003E principal, em geral, a mensagem daquele não é muito relevante. Se usarmos o comando \u003Cem\u003Esquash\u003C\u002Fem\u003E, teremos que remover inteiramente a mensagem do \u003Cem\u003Ecommit\u003C\u002Fem\u003E de correção. Já no caso do \u003Cem\u003Efixup\u003C\u002Fem\u003E, esta mensagem é descartada automaticamente restando apenas a mensagem do \u003Cem\u003Ecommit\u003C\u002Fem\u003E original. Como podemos ver, esse novo comando traz apenas mais comodidade ao processo de \u003Cem\u003Esquash\u003C\u002Fem\u003E.\u003C\u002Fp\u003E\n\u003Ch3\u003EComandos implícitos\u003C\u002Fh3\u003E\n\u003Cp\u003EHá dois comandos que são implícitos: reordenação de comandos e remoção de \u003Cem\u003Ecommits\u003C\u002Fem\u003E. Se usarmos apenas o comando\u003Cem\u003Epick\u003C\u002Fem\u003E em um \u003Cem\u003Erebase\u003C\u002Fem\u003E interativo, reordenando as linhas de comandos, os \u003Cem\u003Ecommits\u003C\u002Fem\u003E serão reordenados. Note que nesta operação é possível que haja conflitos. No caso da remoção, se um \u003Cem\u003Ecommit\u003C\u002Fem\u003E for suprimido no editor, ou seja, se ele não aparecer em nenhum comando, ele será suprimido. Pode ocorrer do \u003Cem\u003Ecommit \u003C\u002Fem\u003Esuprimido ficar “inacessível”, caso em que não exista nenhum caminho de uma das cabeças do repositório até ele. Entretanto para recuperar sua referência é possível usar “git reflog” desde que não tenha sido feita nenhuma coleta de lixo.\u003C\u002Fp\u003E\n\u003Cp\u003EÉ desejável que cada \u003Cem\u003Ecommit\u003C\u002Fem\u003E de uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E de referência represente um estado consistente do código. Com reordenação é possível, por acidente, deixar arquivos que dependam de outros mais antigos, em um \u003Cem\u003Ecommit\u003C\u002Fem\u003E anterior ao \u003Cem\u003Ecommit\u003C\u002Fem\u003E que cria suas dependências, deixando o repositório com uma faixa de \u003Cem\u003Ecommits\u003C\u002Fem\u003E inconsistente. Por ser um problema que não está sob o controle de Git, é responsabilidade do usuário zelar para que nenhum erro ocorra com essas operações delicadas.\u003C\u002Fp\u003E\n\u003Ch3\u003ERearranjando \u003Cem\u003ECommits\u003C\u002Fem\u003E\u003C\u002Fh3\u003E\n\u003Cp\u003ENo Git existe uma certa dualidade na natureza do \u003Cem\u003Ecommit\u003C\u002Fem\u003E. Ao mesmo tempo que um \u003Cem\u003Ecommit\u003C\u002Fem\u003E é uma fotografia precisa do repositório, ele pode ser encarado como um conjunto de alterações. Quando se compara a fotografia do\u003Cem\u003E commit\u003C\u002Fem\u003E corrente com a de seus pais é possível determinar precisamente as alterações introduzidas pelo \u003Cem\u003Ecommit\u003C\u002Fem\u003E em questão. Na condição de portador de mudança, pode ser extremamente desejável incorporar \u003Cem\u003Ecommits\u003C\u002Fem\u003E de uma \u003Cem\u003Ebranchs\u003C\u002Fem\u003E em uma outra, trazendo assim as alterações introduzidas por esse \u003Cem\u003Ecommit\u003C\u002Fem\u003E. Dependendo da maneira como é incorporado, esse \u003Cem\u003Ecommit\u003C\u002Fem\u003E pode não mais simbolizar a mesma fotografia que simbolizava na \u003Cem\u003Ebranch\u003C\u002Fem\u003E original, por isso um novo \u003Cem\u003Ecommit\u003C\u002Fem\u003E pode ser gerando resultando assim em um novo \u003Cem\u003Ehash\u003C\u002Fem\u003E SHA-1.\u003C\u002Fp\u003E\n\u003Cp\u003ENessa seção serão abordadas algumas das formas mais comuns de manipular \u003Cem\u003Ecommits\u003C\u002Fem\u003E. Podemos delicadamente selecionar um único \u003Cem\u003Ecommit\u003C\u002Fem\u003E para ser incorporado ou faixas de commit com mais ou menos controle sobre a operação. Normalmente o comandos mais indicados para cada situação vem do balanço entre controle e praticidade.\u003C\u002Fp\u003E\n\u003Ch3\u003ECherry Pick\u003C\u002Fh3\u003E\n\u003Cp\u003ETalvez o comando \u003Cem\u003Echerry pick\u003C\u002Fem\u003E seja um dos mais precisos para manipulação de commits. Ele é muito usado quando se necessita incorporar cirurgicamente um \u003Cem\u003Ecommit\u003C\u002Fem\u003E de uma outra \u003Cem\u003Ebranch\u003C\u002Fem\u003E no topo da \u003Cem\u003Ebranch\u003C\u002Fem\u003E corrente (apontado por HEAD).\u003C\u002Fp\u003E\n\u003Cp\u003EUm típico caso de uso é quando precisa-se incorporar uma correção de uma \u003Cem\u003Ebranch \u003C\u002Fem\u003Ede desenvolvimento mais nova quando esta correção também impacta uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E estável mais antiga. Nesse caso é bem provável que a \u003Cem\u003Ebranch\u003C\u002Fem\u003E de desenvolvimento tenha divergido muito da \u003Cem\u003Ebranch\u003C\u002Fem\u003E estável, não sendo nem um pouco interessante incorporar mais do que o \u003Cem\u003Ecommit\u003C\u002Fem\u003E de correção.\u003C\u002Fp\u003E\n\u003Cp\u003EA figura abaixo mostra uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E estável versão 2.2 e uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E de desenvolvimento devel3.1 contendo a correção crítica (em laranja) que também é válida para a versão 2.2.\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45861\" aria-describedby=\"caption-attachment-45861\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45861\" rel=\"attachment wp-att-45861\"\u003E\u003Cimg class=\"size-full wp-image-45861\" alt=\"Figure 7: Antes do Cherry Pick\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage007-1.jpg\" width=\"580\" height=\"378\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage007-1.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage007-1-300x195.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45861\" class=\"wp-caption-text\"\u003EFigure 7: Antes do Cherry Pick\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003ECertifique-se de que esteja na \u003Cem\u003Ebranch\u003C\u002Fem\u003E em que deseja incorporar o \u003Cem\u003Ecommit –\u003C\u002Fem\u003E se não estiver basta usar o “git checkout <branch>”. Agora, com o comando “git cherry-pick” vamos incorporar o \u003Cem\u003Ecommit\u003C\u002Fem\u003E de correção que sabemos ter “c33d21a” como prefixo de SHA-1.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git cherry-pick c33d21a\u003C\u002Fpre\u003E\n\u003Cp\u003EPoderíamos ter usado como alternativa para revisão o nome da \u003Cem\u003Ebranch,\u003C\u002Fem\u003E já que o \u003Cem\u003Ecommit\u003C\u002Fem\u003E que desejamos está seu topo.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git cherry-pick devel3.1\u003C\u002Fpre\u003E\n\u003Cfigure id=\"attachment_45863\" aria-describedby=\"caption-attachment-45863\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45863\" rel=\"attachment wp-att-45863\"\u003E\u003Cimg class=\"size-full wp-image-45863\" alt=\"Figure 8: Após o Cherry Pick\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage008-1.jpg\" width=\"580\" height=\"372\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage008-1.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage008-1-300x192.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45863\" class=\"wp-caption-text\"\u003EFigure 8: Após o Cherry Pick\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003ECom isso, vemos que o \u003Cem\u003Ecommit\u003C\u002Fem\u003E foi incorporado na \u003Cem\u003Ebranch\u003C\u002Fem\u003E estável 2.2. Observe que como incorporamos as alterações trazidas por ele e que nosso histórico pode não ter nenhuma relação com o histórico original do \u003Cem\u003Ecommit\u003C\u002Fem\u003E, esse novo \u003Cem\u003Ecommit \u003C\u002Fem\u003Epode não mais representar a mesma fotografia, por isso um novo objeto \u003Cem\u003Ecommit\u003C\u002Fem\u003E foi criado, como pode-se constatar pelo novo SHA-1.\u003C\u002Fp\u003E\n\u003Ch3\u003ERebase\u003C\u002Fh3\u003E\n\u003Cp\u003EÉ muito comum que o desenvolvimento gire em torno de uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E, potencialmente a \u003Cem\u003Emaster\u003C\u002Fem\u003E. Nela os\u003Cem\u003E commits\u003C\u002Fem\u003E de vários usuários são incorporados para que fiquem disponíveis a todos.\u003C\u002Fp\u003E\n\u003Cp\u003ELocalmente quando um usuário vai criar uma nova funcionalidade ou fazer uma correção, é boa prática criar uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E a partir da \u003Cem\u003Ebranch\u003C\u002Fem\u003E de referência justamente com essa finalidade. Com isso tem-se um ponto de bifurcação. Se ao mesmo tempo em que o usuário cria novos \u003Cem\u003Ecommits\u003C\u002Fem\u003E em sua \u003Cem\u003Ebranch\u003C\u002Fem\u003E local, outros \u003Cem\u003Ecommits\u003C\u002Fem\u003E são incorporados à \u003Cem\u003Ebranch\u003C\u002Fem\u003E de referência, pode-se dizer que essas duas \u003Cem\u003Ebranches\u003C\u002Fem\u003E divergiram.\u003C\u002Fp\u003E\n\u003Cp\u003EDo ponto de vista do usuário que possui a \u003Cem\u003Ebranch\u003C\u002Fem\u003E local, pode ser interessante ou até mesmo obrigatório incorporar as alterações da \u003Cem\u003Ebranch\u003C\u002Fem\u003E de referência antes de submeter seus \u003Cem\u003Ecommits\u003C\u002Fem\u003E. É possível que algum novo \u003Cem\u003Ecommit\u003C\u002Fem\u003E da \u003Cem\u003Ebranch\u003C\u002Fem\u003E (de referência) corrija algum \u003Cem\u003Ebug\u003C\u002Fem\u003E ou que exista um política de “f\u003Cem\u003East foward\u003C\u002Fem\u003E“.\u003C\u002Fp\u003E\n\u003Cp\u003ENo caso de correção de \u003Cem\u003Ebugs\u003C\u002Fem\u003E, o interesse em incorporar os \u003Cem\u003Ecommits\u003C\u002Fem\u003E é claro. Já no caso da política “f\u003Cem\u003East foward\u003C\u002Fem\u003E” o responsável pela \u003Cem\u003Ebranch \u003C\u002Fem\u003Epretende simplificar o histórico evitando \u003Cem\u003Emerges\u003C\u002Fem\u003E complicados em que um \u003Cem\u003Ecommit \u003C\u002Fem\u003Etenha múltiplos pais. Com essa política espera-se que os \u003Cem\u003Ecommits\u003C\u002Fem\u003E de cada usuário se apliquem de forma natural ao topo da \u003Cem\u003Ebranch\u003C\u002Fem\u003E de referência, resultando em um linha contínua de \u003Cem\u003Ecommits\u003C\u002Fem\u003E. Para simplificar esse processo, antes que um usuário submeta seus \u003Cem\u003Ecommits\u003C\u002Fem\u003E é necessário que eles estejam aplicados ao topo da \u003Cem\u003Ebranch\u003C\u002Fem\u003E de referência.\u003C\u002Fp\u003E\n\u003Cp\u003EA figura abaixo mostra os novos \u003Cem\u003Ecommits\u003C\u002Fem\u003E (em laranja) criados na \u003Cem\u003Ebranch\u003C\u002Fem\u003E local de um usuário.\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45864\" aria-describedby=\"caption-attachment-45864\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45864\" rel=\"attachment wp-att-45864\"\u003E\u003Cimg class=\"size-full wp-image-45864\" alt=\"Figure 9: Antes do Rebase\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage009-2.jpg\" width=\"580\" height=\"320\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage009-2.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage009-2-300x165.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45864\" class=\"wp-caption-text\"\u003EFigure 9: Antes do Rebase\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003EO comando “git rebase” tem justamente a finalidade de “recriar” a \u003Cem\u003Ebranch\u003C\u002Fem\u003E local aplicando os novos \u003Cem\u003Ecommits\u003C\u002Fem\u003E introduzidos por ela (em laranja) no topo de uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E de referência. Como o próprio nome do comando indica, estamos mudando a base de alguns \u003Cem\u003Ecommits\u003C\u002Fem\u003E, no caso a base dos \u003Cem\u003Ecommits\u003C\u002Fem\u003E introduzidos na \u003Cem\u003Ebranch\u003C\u002Fem\u003E local. No exemplo a \u003Cem\u003Ebranch\u003C\u002Fem\u003E de referencia é a \u003Cem\u003Emaster\u003C\u002Fem\u003E, então pode-se fazer:\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git rebase master\u003C\u002Fpre\u003E\n\u003Cp\u003ECom isso tem-se a \u003Cem\u003Ebranch\u003C\u002Fem\u003E local formado pelos novos \u003Cem\u003Ecommits\u003C\u002Fem\u003E da \u003Cem\u003Ebranch\u003C\u002Fem\u003E de referência com seus próprios \u003Cem\u003Ecommits\u003C\u002Fem\u003E aplicados ao topo.\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45865\" aria-describedby=\"caption-attachment-45865\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45865\" rel=\"attachment wp-att-45865\"\u003E\u003Cimg class=\"size-full wp-image-45865\" alt=\"Figure 10: Após o Rebase\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage010-1.jpg\" width=\"580\" height=\"320\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage010-1.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage010-1-300x165.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45865\" class=\"wp-caption-text\"\u003EFigure 10: Após o Rebase\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Ch3\u003ERebase –onto\u003C\u002Fh3\u003E\n\u003Cp\u003EPodemos estar interessados em pegar uma faixa de \u003Cem\u003Ecommits\u003C\u002Fem\u003E de uma \u003Cem\u003Ebranch\u003C\u002Fem\u003E e aplicá-la ao topo de um \u003Cem\u003Ecommit\u003C\u002Fem\u003E de referência. Para isso existe o comando “git rebase –onto” na sua forma de três revisões como argumento.\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git rebase –onto <base> <pai_do_inicio_da_faixa> <final_da_faixa>\u003C\u002Fpre\u003E\n\u003Cp\u003EAo aplicar esse comando, a \u003Cem\u003Ebranch\u003C\u002Fem\u003E corrente conterá a faixa de \u003Cem\u003Ecommits\u003C\u002Fem\u003E aplicada ao \u003Cem\u003Ecommit\u003C\u002Fem\u003E de base. Vamos ilustrar com um exemplo gráfico para simplificar. Suponha que queremos transformar nossa \u003Cem\u003Ebranch\u003C\u002Fem\u003E corrente na aplicação dos \u003Cem\u003Ecommits\u003C\u002Fem\u003E em laranja no topo da \u003Cem\u003Ebranch master\u003C\u002Fem\u003E. Para isto, primeiramente nos posicionamos na branch em que essas modificações devem ocorrer. Identificamos os SHA-1 da nossa base que é “43edac2”. Agora faltar determinar os SHA-1 que delimitam nossa faixa de \u003Cem\u003Ecommit\u003C\u002Fem\u003E. Para o pai do início da faixa tem-se “c71da12” e como final de faixa tem-se “a1c87d1”.\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45866\" aria-describedby=\"caption-attachment-45866\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45866\" rel=\"attachment wp-att-45866\"\u003E\u003Cimg class=\"size-full wp-image-45866\" alt=\"Figure 11: Antes do Rebase --onto\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage011-1.jpg\" width=\"580\" height=\"503\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage011-1.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage011-1-300x260.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45866\" class=\"wp-caption-text\"\u003EFigure 11: Antes do Rebase –onto\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003ECom as três informações de revisão em mãos basta fazer:\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git rebase –onto  43edac2  c71da12  a1c87d1\u003C\u002Fpre\u003E\n\u003Cp\u003EOu alternativamente:\u003C\u002Fp\u003E\n\u003Cpre\u003E$ git rebase –onto  master c71da12  HEAD~1\u003C\u002Fpre\u003E\n\u003Cp\u003EEsse comando resulta na seguinte mudança mostrada na figura a abaixo:\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45867\" aria-describedby=\"caption-attachment-45867\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45867\" rel=\"attachment wp-att-45867\"\u003E\u003Cimg class=\"size-full wp-image-45867\" alt=\"Figure 12: Após o Rebase --onto\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage012-1.jpg\" width=\"580\" height=\"499\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage012-1.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Fimage012-1-300x258.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45867\" class=\"wp-caption-text\"\u003EFigure 12: Após o Rebase –onto\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Ch3\u003EMerge\u003C\u002Fh3\u003E\n\u003Cp\u003EO comando “git merge” também é um ferramenta chave para se rearranjar \u003Cem\u003Ecommits\u003C\u002Fem\u003E, com ele é possível combinar múltiplas linhas de desenvolvimento. Por questões de espaço não o detalharemos aqui.\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"N10657\"\u003E\u003C\u002Fa\u003EConclusão\u003C\u002Fh2\u003E\n\u003Cp\u003EO sistema Git é bem poderoso, mas para se ter acesso a parte desse poder é preciso conhecer algumas ferramentas-chave. Neste artigo foi abordado com mais profundidade o ferramental de reescrever o histórico e rearranjar os \u003Cem\u003Ecommits\u003C\u002Fem\u003E. Com isso espera-se que um usuário básico tome conhecimento de algumas funcionalidade mais avançadas, podendo melhor explorar esse fabuloso sistema de controle de versão.\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"N10662\"\u003E\u003C\u002Fa\u003EReferências\u003C\u002Fh2\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.perlmonks.org\u002F\"\u003Ehttp:\u002F\u002Fgit-scm.com\u002Fbook\u002F\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.perlmonks.org\u002F\"\u003Ehttp:\u002F\u002Fwww.kernel.org\u002Fpub\u002Fsoftware\u002Fscm\u002Fgit\u002Fdocs\u002F\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E***\u003C\u002Fp\u003E\n\u003Cp\u003ESobre o autor: Fernando é formado em Engenharia da Computação pela UNICAMP e possui Duplo-Diploma em Engenharia pela Universidade Francesa Télécom ParisTech. Trabalha há um ano no Linux Technology Center da IBM.\u003Cbr \u002F\u003E\n\u003Ca href=\"https:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fcommunity\u002Fprofiles\u002Fhtml\u002FprofileView.do?key=edabdc20-5592-4077-b457-de1742ae1b98&lang=pt_br\"\u003EPerfil My DeveloperWorks\u003C\u002Fa\u003E.\u003C\u002Fp\u003E\n\u003Cp\u003E***\u003C\u002Fp\u003E\n\u003Cp\u003EO artigo original está disponível em: \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Flocal\u002Fopensource\u002Fsaindo_basico_git\u002Findex.html\"\u003Ehttp:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Flocal\u002Fopensource\u002Fsaindo_basico_git\u002Findex.html\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003C\u002Fdiv\u003E\n","excerpt":"\u003Cp\u003EEste artigo começa com a revisão de alguns conceitos de Git para depois aprofundar em dois tópicos muito importantes.\u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fsaindo-do-basico-com-git","date":"12 ago, 2013","thumbnail":"","externalMention":null,"author":{"id":421,"thumbnail":"https:\u002F\u002Fsecure.gravatar.com\u002Favatar\u002Fbe5bc6f39606ac453a07bd2eb7ab21af?s=96&d=mm&r=g","name":"developerWorks Brasil","description":"é o portal de tecnologia da IBM para profissionais de TI de todo o mundo. Colabore, aprenda a criar aplicativos inovadores e compreenda tecnologias avançadas. Acesse mais artigos e tutoriais em www.ibm.com\u002Fdeveloperworks\u002Fbr","slug":"developerworks_brasil","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdeveloperworks_brasil","registered":"2010-07-07 17:06:45","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002Fsoudw","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002F","mail":"dwbr@br.ibm.com"},"articles_count":217,"views_count":4709798,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"Desenvolvimento","slug":"desenvolvimento","id":7234,"link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento"}],"tags":[{"title":"branch","slug":"branch","id":235,"link":"https:\u002F\u002Fimasters.com.br\u002Fbranch"},{"title":"commits","slug":"commits","id":2002,"link":"https:\u002F\u002Fimasters.com.br\u002Fcommits"},{"title":"fundamentos","slug":"fundamentos","id":2001,"link":"https:\u002F\u002Fimasters.com.br\u002Ffundamentos"},{"title":"git","slug":"git","id":257,"link":"https:\u002F\u002Fimasters.com.br\u002Fgit"}],"seo":{"open_graph":{"title":"Saindo do básico com Git - iMasters - We are Developers","description":"Este artigo começa com a revisão de alguns conceitos de Git para depois aprofundar em dois tópicos muito importantes.","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":false,"modified_time":"2013-08-08T16:14:18-03:00","published_time":"2013-08-12T14:00:31-03:00"},"twitter":{"title":"Saindo do básico com Git - iMasters - We are Developers","description":"Este artigo começa com a revisão de alguns conceitos de Git para depois aprofundar em dois tópicos muito importantes.","type":"summary_large_image","image":false}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fsaindo-do-basico-com-git","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fsaindo-do-basico-com-git","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fsaindo-do-basico-com-git"},"type":"post"},{"id":45682,"title":"Desenvolva um aplicativo de análise e visualização de texto","content":"\u003Cp\u003EA visualização de texto é uma maneira eficiente e às vezes reveladora de verificar rapidamente o que um texto específico está dizendo. Como um subproduto, a visualização também fornece um meio para as análises ad hoc de um texto. O artigo mostra como desenvolver um software de análise e visualização de texto com bibliotecas e ferramentas de software livre. O aplicativo compara e analisa dois textos com um contexto igual ou semelhante, permitindo que os usuários obtenham um novo insight sobre esses textos ou seu contexto.\u003C\u002Fp\u003E\n\u003Cp\u003EO aplicativo desenvolvido é baseado na visualização de nuvem de palavras. Uma visualização de nuvem de palavras analisa um texto específico e classifica suas palavras na proporção em com qual frequência elas ocorrem. As palavras classificadas são, então, baseadas no tamanho em suas classificações. A palavra com a classificação mais alta é exibida com a maior fonte na visualização. A posição das palavras na visualização pode avariar, mas normalmente elas lembram uma nuvem, como na Figura 1:\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45684\" aria-describedby=\"caption-attachment-45684\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45684\" rel=\"attachment wp-att-45684\"\u003E\u003Cimg class=\"size-full wp-image-45684\" alt=\"figure001 (1)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure001-1.jpg\" width=\"580\" height=\"239\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure001-1.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure001-1-300x123.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45684\" class=\"wp-caption-text\"\u003EFigura 1. Uma nuvem de palavras\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003EPara gerar a nuvem de palavras na Figura 1, usei o IBM Many Eyes para analisar a carta do President e CEO no Relatório Anual da IBM de 2011.\u003C\u002Fp\u003E\n\u003Cp\u003EO aplicativo nesse artigo gera uma onda de palavras — uma visualização de texto que tem o formato semelhante ao de uma nuvem. Essa onda de palavras coloca as palavras com maior classificação no canto superior esquerdo. Figura 2 mostra um exemplo que usa o mesmo texto que é visualizado na Figura 1:\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45685\" aria-describedby=\"caption-attachment-45685\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45685\" rel=\"attachment wp-att-45685\"\u003E\u003Cimg class=\"size-full wp-image-45685\" alt=\"figure002\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure002.jpg\" width=\"580\" height=\"326\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure002.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure002-300x168.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45685\" class=\"wp-caption-text\"\u003EFigura 2. Onda de palavras de amostra\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003EA visualização de um texto revela as palavras de classificação alta. A análise do texto, que é baseada na visualização, assume que as palavras de classificação alta têm uma hierarquia de importância. A comparação acontece quando duas visualizações de texto são exibidas juntas. Se os contextos de ambos os textos forem iguais ou semelhantes, a comparação é especialmente significativa. Por exemplo, uma comparação de textos que descrevem as estratégias de duas empresas no mesmo segmento de mercado deve revelar semelhanças e diferenças entre as prioridades dessas duas empresas.\u003C\u002Fp\u003E\n\u003Cp\u003EA Figura 3 é um rascunho grosseiro de uma comparação final de dois textos. A visualização do primeiro texto está na parte superior e a visualização do segundo está na parte inferior. As palavras de classificação alta em ambas estão no lado esquerdo.\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45686\" aria-describedby=\"caption-attachment-45686\" style=\"width: 469px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45686\" rel=\"attachment wp-att-45686\"\u003E\u003Cimg class=\"size-full wp-image-45686\" alt=\"Figura 3. Rascunho da comparação de textos em uma visualização\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure003.jpg\" width=\"469\" height=\"302\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure003.jpg 469w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure003-300x193.jpg 300w\" sizes=\"(max-width: 469px) 100vw, 469px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45686\" class=\"wp-caption-text\"\u003EFigura 3. Rascunho da comparação de textos em uma visualização\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003EOs objetivos do artigo e seu código são mostrar como:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EDesenvolver um aplicativo de linha de comando para visualizar e comparar textos com bibliotecas e ferramentas de software livre;\u003C\u002Fli\u003E\n\u003Cli\u003ECriar uma visualização (semelhante a Figura 2) de um texto especificado com uma visualização de onda de palavras;\u003C\u002Fli\u003E\n\u003Cli\u003ECombinar duas visualizações na mesma imagem para comparação e análise;\u003C\u002Fli\u003E\n\u003Cli\u003ECriar um vídeo visualmente atraente a partir da visualização.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003EO artigo não se aprofunda nos detalhes de desenvolvimento, então a experiência com o desenvolvimento em Java™ e com o modelo de programação do Eclipse é útil para os leitores. Todo o código-fonte do aplicativo — os projetos do Eclipse para o aplicativo e um site de atualização pronto para implementação — estão disponíveis para download.\u003C\u002Fp\u003E\n\u003Cp\u003EIniciarei com uma visão geral dos componentes do ambiente de desenvolvimento.\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"N1015D\"\u003E\u003C\u002Fa\u003EAmbiente de desenvolvimento\u003C\u002Fh2\u003E\n\u003Cp\u003EO ambiente de desenvolvimento consiste em várias bibliotecas e ferramentas de software livre que, combinadas, fazem com que seja fácil de criar vídeos e ondas de palavras. O aplicativo em si é relativamente curto. As bibliotecas e ferramentas cuidam do processamento pesado de imagens, vídeos e da interface da linha de comandos.\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N10165\"\u003E\u003C\u002Fa\u003EEclipse\u003C\u002Fh3\u003E\n\u003Cp\u003EQuando o Eclipse é usado como um IDE, é possível aproveitar o Command Line Program.\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N1016D\"\u003E\u003C\u002Fa\u003ECommand Line Program\u003C\u002Fh3\u003E\n\u003Cp\u003EO Command Line Program é um aplicativo Rich Client Platform (RCP) Eclipse de terceiros para a criação de aplicativos de linha de comando. Ele usa o modelo de programação de plug-in do Eclipse, incluindo \u003Cem\u003Efeatures\u003C\u002Fem\u003E e \u003Cem\u003Esites de atualização \u003C\u002Fem\u003E(consulte ‘Recursos’  para encontrar um link para os conceitos do Eclipse). O Command Line Program fornece a infraestrutura para os aplicativos de linha de comando, como análise de linha de comando, um comando de ajuda, criação de log e outras funções básicas. A ideia é desenvolver um software de análise e visualização como um comando de extensão para o Command Line Program.\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N10182\"\u003E\u003C\u002Fa\u003EProcessing e WordCram\u003C\u002Fh3\u003E\n\u003Cp\u003EO Processing é uma linguagem e um ambiente de desenvolvimento para a criação de animações e imagens. Para uma introdução ao Processing, consulte “\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fopensource\u002Flibrary\u002Fos-datavis\u002Findex.html\"\u003EVisualização de dados com Processing – Parte 1\u003C\u002Fa\u003E“. O Processing é fácil de aprender e usar, embora seja possível realizar grandes feitos com ele (consulte ‘Recursos’ para encontrar um link para exemplos no OpenProcessing.org). O WordCram é uma biblioteca customizável para a criação de nuvens de palavras no Processing.\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N10192\"\u003E\u003C\u002Fa\u003EMonte Media Library\u003C\u002Fh3\u003E\n\u003Cp\u003EA Monte Media Library é uma biblioteca de software livre simples e excelente para escrever, ler e manipular vídeos e imagens. O autor, Werner Randelshofer, diz em seu website que a Monte Media Library é experimental para seus estudos pessoais. Apesar disso, felizmente ele decidiu publicá-la para que outras pessoas também possam usá-la. Diferente de outras bibliotecas disponíveis que parecem complicadas e requerem um código nativo, a Monte Media Library é fácil de usar e é puramente em código Java.\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"N1019A\"\u003E\u003C\u002Fa\u003EDesenvolvendo o aplicativo\u003C\u002Fh2\u003E\n\u003Cp\u003EAgora que está familiarizado com as ferramentas, é possível começar a desenvolver um aplicativo chamado\u003Ccode\u003ETextVisualizationAndAnalysis\u003C\u002Fcode\u003E e um comando de extensão chamado \u003Ccode\u003ECompare\u003C\u002Fcode\u003E — para o Command Line Program.\u003C\u002Fp\u003E\n\u003Cp\u003EO projeto do Command Line Program é necessário para que seja possível desenvolver a extensão para ele. \u003Ca href=\"http:\u002F\u002Fsoftabar.com\u002Fhome\u002Fcommand-line-program-download\u002F\"\u003EFaça o download do código fonte do módulo \u003Ccode\u003ECLP_Plugin_Main\u003C\u002Fcode\u003E project\u003C\u002Fa\u003E e importe na área de trabalho do Eclipse. O projeto inclui o código fonte para o Command Line Program e fornece pontos de extensão para desenvolver extensões em seus próprios projetos.\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N101B7\"\u003E\u003C\u002Fa\u003ECrie um projeto de plug-in\u003C\u002Fh3\u003E\n\u003Cp\u003EPara desenvolver um comando de extensão pra o Command Line Program, primeiro crie um projeto de plug-in, como seria necessário com qualquer outro projeto de extensão do Eclipse:\u003C\u002Fp\u003E\n\u003Col\u003E\n\u003Cli\u003ECrie um novo projeto de plug-in e insira \u003Ccode\u003ETextVisualizationAndAnalysis\u003C\u002Fcode\u003E como o nome do projeto;\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione 3.5 or greater como a versão do Eclipse e clique em Próximo;\u003C\u002Fli\u003E\n\u003Cli\u003EInsira \u003Ccode\u003E0.0.1\u003C\u002Fcode\u003E como o número da versão, desmarque (se estiver selecionada) a opção This plug-in will make contributions to the UI e aceite os padrões nos outros campos. Clique em Próximo para chegar à tela final;\u003C\u002Fli\u003E\n\u003Cli\u003EDesmarque (se estiver selecionada) a opção Create a plug-in using one of the templatese clique em Concluir para criar o projeto;\u003C\u002Fli\u003E\n\u003Cli\u003EO novo projeto agora está na área de trabalho do Eclipse e o arquivo plugin.xml está aberto na tela. (Se não estiver e se o plugin.xml não existir no diretório do projeto, abra o arquivo META-INF\u002FMANIFEST.MF no lugar dele);\u003C\u002Fli\u003E\n\u003Cli\u003EAbra a guia Dependencies e na seção Required Plug-ins adicione \u003Ccode\u003Ecom.softabar.clpp.application\u003C\u002Fcode\u003E ao projeto. Esse plug-in é fornecido com o projeto Command Line Program Eclipse que foi importado na área de trabalho do Eclipse;\u003C\u002Fli\u003E\n\u003Cli\u003EAcesse a guia Extensions e adicione uma extensão que amplia o ponto de extensão\u003Ccode\u003Ecom.softabar.clpp.application.command\u003C\u002Fcode\u003E, que é fornecido com o Command Line Program;\u003C\u002Fli\u003E\n\u003Cli\u003EInsira os detalhes da extensão. Insira \u003Ccode\u003Ecompare\u003C\u002Fcode\u003E na seção nome . Insira \u003Ccode\u003EVisualize and compare two text files\u003C\u002Fcode\u003E na seção help. Insira \u003Ccode\u003Etextvisualizationandanalysis.Compare Command\u003C\u002Fcode\u003E na seção. Consulte Figura 4:\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cfigure id=\"attachment_45687\" aria-describedby=\"caption-attachment-45687\" style=\"width: 424px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45687\" rel=\"attachment wp-att-45687\"\u003E\u003Cimg class=\"size-full wp-image-45687\" alt=\"Figura 4. Novo comando para o Command Line Program \" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure004.jpg\" width=\"424\" height=\"148\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure004.jpg 424w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure004-300x104.jpg 300w\" sizes=\"(max-width: 424px) 100vw, 424px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45687\" class=\"wp-caption-text\"\u003EFigura 4. Novo comando para o Command Line Program\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003ECrie a classe posteriormente. Além disso, adicione novas informações ao plug-in posteriormente, conforme o necessário.\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N10227\"\u003E\u003C\u002Fa\u003EAdicione as bibliotecas necessárias\u003C\u002Fh3\u003E\n\u003Cp\u003EPara criar o procedimento \u003Ccode\u003ECompare\u003C\u002Fcode\u003E, adicione essas bibliotecas ao plug-in:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003Ecore.jar, do Processing;\u003C\u002Fli\u003E\n\u003Cli\u003EWordCram.jar, jsoup-1.3.3.jar, e (opcionalmente) cue.language.jar do WordCram;\u003C\u002Fli\u003E\n\u003Cli\u003Emonte-cc.jar, da Monte Media Library.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003EPara adicioná-las:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003ECrie um diretório lib no projeto de plug-in e adicione os arquivos JAR a esse diretório;\u003C\u002Fli\u003E\n\u003Cli\u003EPara incluir o diretório lib no desenvolvimento do plug-in, abra o plugin.xml e selecione a guia Compilação. Para selecionar o diretório lib no diálogo Binary Build, clique em sua caixa de seleção, como naFigura 5:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cfigure id=\"attachment_45689\" aria-describedby=\"caption-attachment-45689\" style=\"width: 418px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45689\" rel=\"attachment wp-att-45689\"\u003E\u003Cimg class=\"size-full wp-image-45689\" alt=\"Figura 5. Binary Build do plug-in \" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure005.jpg\" width=\"418\" height=\"280\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure005.jpg 418w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure005-300x200.jpg 300w\" sizes=\"(max-width: 418px) 100vw, 418px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45689\" class=\"wp-caption-text\"\u003EFigura 5. Binary Build do plug-in\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cul\u003E\n\u003Cli\u003EAbra a guia Runtime no diálogo Classpath, selecione Incluir para adicionar as bibliotecas ao caminho de classe do plug-in. Figura 6 mostra o diálogo Classpath com todas as bibliotecas (não incluindo a cue.language.jar) incluídas:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cfigure id=\"attachment_45690\" aria-describedby=\"caption-attachment-45690\" style=\"width: 380px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45690\" rel=\"attachment wp-att-45690\"\u003E\u003Cimg class=\"size-full wp-image-45690\" alt=\"Figura 6. Adicionando as bibliotecas ao caminho de classe do plug-in\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure006.jpg\" width=\"380\" height=\"240\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure006.jpg 380w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure006-300x189.jpg 300w\" sizes=\"(max-width: 380px) 100vw, 380px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45690\" class=\"wp-caption-text\"\u003EFigura 6. Adicionando as bibliotecas ao caminho de classe do plug-in\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cul\u003E\n\u003Cli\u003ESalve o arquivo plugin.xml.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch3\u003E\u003Ca name=\"N10280\"\u003E\u003C\u002Fa\u003EEscreva o código\u003C\u002Fh3\u003E\n\u003Cp\u003EAgora é possível escrever o código real para o comando. O código-fonte para o comando está nas listagens a seguir (com as instruções de importação e pacote intencionalmente omitidas). Também é necessário incluir algumas informações no arquivo plugin.xml file, que mostrarei após passarmos pelas listagens de código.\u003C\u002Fp\u003E\n\u003Cp\u003ELista 1 contém as variáveis e a declaração de classe:\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]<\u002Fp>\u003Cbr \u002F\u003E\n<p>public class CompareCommand extends PApplet implements ICommand, WordColorer {<br \u002F>\u003Cbr \u002F\u003E\n private static final long serialVersionUID = -188003470351748783L;<br \u002F>\u003Cbr \u002F\u003E\n private static CLPPLogger logger = CLPPLogger.getLogger(CompareCommand.class);<br \u002F>\u003Cbr \u002F\u003E\n private static boolean testing = true;<br \u002F>\u003Cbr \u002F\u003E\n private static boolean processingDone = false;<br \u002F>\u003Cbr \u002F\u003E\n private static String fileName;<br \u002F>\u003Cbr \u002F\u003E\n private static String outputDir;<br \u002F>\u003Cbr \u002F\u003E\n private static File inputTextFile1;<br \u002F>\u003Cbr \u002F\u003E\n private static File inputTextFile2;<br \u002F>\u003Cbr \u002F\u003E\n private static boolean drawTitle;<br \u002F>\u003Cbr \u002F\u003E\n private static String title1;<br \u002F>\u003Cbr \u002F\u003E\n private static String title2;<br \u002F>\u003Cbr \u002F\u003E\n private static boolean createVideo = false;<br \u002F>\u003Cbr \u002F\u003E\n private static int frameRate;<br \u002F>\u003Cbr \u002F\u003E\n private int frameWidth = 1280;<br \u002F>\u003Cbr \u002F\u003E\n private int frameHeight = 720;<br \u002F>\u003Cbr \u002F\u003E\n private int maxWords = 50;<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F font to be used<br \u002F>\u003Cbr \u002F\u003E\n private String font = &quot;c:\u002Fwindows\u002Ffonts\u002Fgeorgiab.ttf&quot;;<br \u002F>\u003Cbr \u002F\u003E\n private WordCram wordCram1;<br \u002F>\u003Cbr \u002F\u003E\n private PGraphics buffer1;<br \u002F>\u003Cbr \u002F\u003E\n private WordCram wordCram2;<br \u002F>\u003Cbr \u002F\u003E\n private PGraphics buffer2;<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F colors used in word waves<\u002Fp>\u003Cbr \u002F\u003E\n<p>private int[] colors = { 0x22992A, 0x9C3434, 0x257CCD, 0x950C9E } [xml]<\u002Fp>\u003Cbr \u002F\u003E\n<p>Em Lista 1, a classe processing.core.PApplet é estendida para aproveitar os métodos do Processing. Em seguida, são implementadas duas interfaces: com.softabar.clpp.program.ICommand e wordcram.WordColorer. A opçãocom.softabar.clpp.program.ICommand de interface é para o Command Line Program. Ela é chamada pelo Command Line Program quando o comando é executado. A opção wordcram.WordColorer de interface manipula as cores das nuvens (ou ondas) de palavras. Algumas das variáveis são declaradas &lt;code&gt;estático&lt;\u002Fcode&gt; , pois precisam estar visíveis no código de Processing durante a execução.<\u002Fp>\u003Cbr \u002F\u003E\n<p>Lista 2 mostra a classe execute() da função ICommand:<\u002Fp>\u003Cbr \u002F\u003E\n<p>[xml]<\u002Fp>\u003Cbr \u002F\u003E\n<p>public void execute(CommandLine commandLine, IProgramContext programContext) {<br \u002F>\u003Cbr \u002F\u003E\n testing = false;<br \u002F>\u003Cbr \u002F\u003E\n String inputFileStr = commandLine.getOptionValue(&quot;input1&quot;);<br \u002F>\u003Cbr \u002F\u003E\n inputTextFile1 = new File(inputFileStr);<br \u002F>\u003Cbr \u002F\u003E\n if (!inputTextFile1.exists()) {<br \u002F>\u003Cbr \u002F\u003E\n Output.error(inputFileStr + &quot; does not exist.&quot;);<br \u002F>\u003Cbr \u002F\u003E\n return;<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n inputFileStr = commandLine.getOptionValue(&quot;input2&quot;);<br \u002F>\u003Cbr \u002F\u003E\n inputTextFile2 = new File(inputFileStr);<br \u002F>\u003Cbr \u002F\u003E\n if (!inputTextFile2.exists()) {<br \u002F>\u003Cbr \u002F\u003E\n Output.error(inputFileStr + &quot; does not exist.&quot;);<br \u002F>\u003Cbr \u002F\u003E\n return;<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n drawTitle = commandLine.hasOption(&quot;title&quot;);<br \u002F>\u003Cbr \u002F\u003E\n fileName = commandLine.getOptionValue(&quot;filename&quot;, &quot;results&quot;);<br \u002F>\u003Cbr \u002F\u003E\n outputDir = commandLine.getOptionValue(&quot;outputdir&quot;, &quot;.&quot;);<br \u002F>\u003Cbr \u002F\u003E\n if (!outputDir.endsWith(&quot;\u002F&quot;)) {<br \u002F>\u003Cbr \u002F\u003E\n outputDir = outputDir + &quot;\u002F&quot;;<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n title1 = commandLine.getOptionValue(&quot;title1&quot;, inputTextFile1.getName());<br \u002F>\u003Cbr \u002F\u003E\n title2 = commandLine.getOptionValue(&quot;title2&quot;, inputTextFile2.getName());<br \u002F>\u003Cbr \u002F\u003E\n String frate = commandLine.getOptionValue(&quot;framerate&quot;, &quot;5&quot;);<br \u002F>\u003Cbr \u002F\u003E\n frameRate = Integer.parseInt(frate);<br \u002F>\u003Cbr \u002F\u003E\n createVideo = commandLine.hasOption(&quot;video&quot;);<br \u002F>\u003Cbr \u002F\u003E\n Output.println(&quot;Generating comparison word waves…&quot;);<br \u002F>\u003Cbr \u002F\u003E\n generateWordCloud();<br \u002F>\u003Cbr \u002F\u003E\n createVideo();<br \u002F>\u003Cbr \u002F\u003E\n}[\u002Fxml]\u003C\u002Fp\u003E\n\u003Cp\u003EIn Lista 2, o método \u003Ccode\u003Eexecute()\u003C\u002Fcode\u003E recebe uma instância \u003Ccode\u003Eorg.apache.commons.cli.CommandLine\u003C\u002Fcode\u003E como um parâmetro. O parâmetro obtém as opções para o comando. Adicione as opções suportadas ao plugin.xml posteriormente. Após obter e configurar as opções, crie a nuvem de palavras ao chamar o método \u003Ccode\u003EgenerateWordCloud()\u003C\u002Fcode\u003E usual. Em seguida, crie o vídeo ao chamar o método \u003Ccode\u003EcreateVideo()\u003C\u002Fcode\u003E.\u003C\u002Fp\u003E\n\u003Cp\u003ELista 3 mostra a classe \u003Ccode\u003EgenerateWordCloud()\u003C\u002Fcode\u003E (método) que chama o método \u003Ccode\u003Emain\u003C\u002Fcode\u003E na classe \u003Ccode\u003Eprocessing.PApplet\u003C\u002Fcode\u003E e então espera até que o Processing\u002FWordCram conclua a renderização da nuvem de palavras:\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]<\u002Fp>\u003Cbr \u002F\u003E\n<p>private void generateWordCloud() {<br \u002F>\u003Cbr \u002F\u003E\n try {<br \u002F>\u003Cbr \u002F\u003E\n main(new String[] { &quot;–present&quot;, getClass().getName() });<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F wait until word wave is finished<br \u002F>\u003Cbr \u002F\u003E\n while (!processingDone) {<br \u002F>\u003Cbr \u002F\u003E\n try {<br \u002F>\u003Cbr \u002F\u003E\n Thread.sleep(0, 1);<br \u002F>\u003Cbr \u002F\u003E\n } catch (InterruptedException e) {<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n } catch (Exception e) {<br \u002F>\u003Cbr \u002F\u003E\n logger.error(e.toString(), e);<br \u002F>\u003Cbr \u002F\u003E\n Output.error(e.toString());<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n}[\u002Fxml]\u003C\u002Fp\u003E\n\u003Cp\u003ELista 4 mostra a configuração para a geração de nuvens de palavras:\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]<\u002Fp>\u003Cbr \u002F\u003E\n<p>public void setup() {<br \u002F>\u003Cbr \u002F\u003E\n if (testing) {<br \u002F>\u003Cbr \u002F\u003E\n logger.debug(&quot;testing&quot;);<br \u002F>\u003Cbr \u002F\u003E\n inputTextFile1 = new File(&quot;c:\u002FCocaCola_MissionVisionValues.txt&quot;);<br \u002F>\u003Cbr \u002F\u003E\n inputTextFile2 = new File(&quot;c:\u002FPepsiCo_MissionVisionValues.txt&quot;);<br \u002F>\u003Cbr \u002F\u003E\n outputDir = &quot;c:\u002Foutput\u002F&quot;;<br \u002F>\u003Cbr \u002F\u003E\n fileName = &quot;results&quot;;<br \u002F>\u003Cbr \u002F\u003E\n drawTitle = true;<br \u002F>\u003Cbr \u002F\u003E\n createVideo = false;<br \u002F>\u003Cbr \u002F\u003E\n title1 = &quot;Coke&quot;;\u002F\u002F inputTextFile1.getName();<br \u002F>\u003Cbr \u002F\u003E\n title2 = &quot;Pepsi&quot;;\u002F\u002F inputTextFile2.getName();<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n logger.debug(&quot;frameWidth: {}, frameHeight: {}&quot;, frameWidth, frameHeight);<br \u002F>\u003Cbr \u002F\u003E\n size(frameWidth, frameHeight);<br \u002F>\u003Cbr \u002F\u003E\n background(255);<br \u002F>\u003Cbr \u002F\u003E\n logger.debug(&quot;setup&quot;);<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F create buffer to draw the upper word wave<br \u002F>\u003Cbr \u002F\u003E\n buffer1 = createGraphics(frameWidth, frameHeight \u002F 2, JAVA2D);<br \u002F>\u003Cbr \u002F\u003E\n buffer1.beginDraw();<br \u002F>\u003Cbr \u002F\u003E\n buffer1.background(255);<br \u002F>\u003Cbr \u002F\u003E\n wordCram1 = initWordCram(inputTextFile1, buffer1);<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F create buffer to draw the lower word wave<br \u002F>\u003Cbr \u002F\u003E\n buffer2 = createGraphics(frameWidth, frameHeight \u002F 2, JAVA2D);<br \u002F>\u003Cbr \u002F\u003E\n buffer2.beginDraw();<br \u002F>\u003Cbr \u002F\u003E\n buffer2.background(255);<br \u002F>\u003Cbr \u002F\u003E\n wordCram2 = initWordCram(inputTextFile2, buffer2);<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F set up font for titles<br \u002F>\u003Cbr \u002F\u003E\n fill(0);<br \u002F>\u003Cbr \u002F\u003E\n textFont(createFont(font, 40));<br \u002F>\u003Cbr \u002F\u003E\n textAlign(CENTER);<br \u002F>\u003Cbr \u002F\u003E\n}[\u002Fxml]\u003C\u002Fp\u003E\n\u003Cp\u003EIn Lista 4, o método \u003Ccode\u003Esetup()\u003C\u002Fcode\u003E é chamado pelo Processing antes de ele iniciar o desenho. Aqui são inicializados o tamanho da tela e a cor do plano de fundo e são criados os buffers de gráfico em que a nuvem de palavras gerada pelo WordCram é desenhada . Esse código também especifica as variáveis para teste a partir do Eclipse.\u003C\u002Fp\u003E\n\u003Cp\u003EWordCram, a biblioteca responsável por gerar as nuvens de palavras é inicializada na Lista 5. É possível especificar os aspectos da nuvem de palavras como as cores e a localização. A WordCram fornece alguns posicionadores, como a nuvem usada aqui, além de algumas colorações para as palavras. Aqui, use sua própria coloração.\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]<\u002Fp>\u003Cbr \u002F\u003E\n<p>private WordCram initWordCram(File inputFile, PGraphics buffer) {<br \u002F>\u003Cbr \u002F\u003E\n WordCram wordCram = new WordCram(this);<br \u002F>\u003Cbr \u002F\u003E\n if (buffer != null) {<br \u002F>\u003Cbr \u002F\u003E\n wordCram = wordCram.withCustomCanvas(buffer);<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F initialize WordCram with specified placer, text file,<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F colorer, and other details<br \u002F>\u003Cbr \u002F\u003E\n wordCram = wordCram.fromTextFile(inputFile.getPath());<br \u002F>\u003Cbr \u002F\u003E\n wordCram = wordCram.withColorer(this);<br \u002F>\u003Cbr \u002F\u003E\n wordCram = wordCram.withWordPadding(2);<br \u002F>\u003Cbr \u002F\u003E\n wordCram = wordCram.withPlacer(Placers.wave());<br \u002F>\u003Cbr \u002F\u003E\n wordCram = wordCram.withAngler(Anglers.randomBetween(-0.15f, 0.15f));<br \u002F>\u003Cbr \u002F\u003E\n wordCram = wordCram.withFont(createFont(font, 40));<br \u002F>\u003Cbr \u002F\u003E\n wordCram = wordCram.sizedByWeight(7, 52);<br \u002F>\u003Cbr \u002F\u003E\n wordCram = wordCram.maxNumberOfWordsToDraw(maxWords);<br \u002F>\u003Cbr \u002F\u003E\n return wordCram;<br \u002F>\u003Cbr \u002F\u003E\n}[\u002Fxml]\u003C\u002Fp\u003E\n\u003Cp\u003ELista 6 mostra a nuvem de palavras que é gerada pelo método draw() do operador:\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]<\u002Fp>\u003Cbr \u002F\u003E\n<p>public void draw() {<br \u002F>\u003Cbr \u002F\u003E\n logger.debug(&quot;Draw..&quot;);<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F draw one word at a time<br \u002F>\u003Cbr \u002F\u003E\n if (wordCram1.hasMore()) {<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F draw next word in upper word wave<br \u002F>\u003Cbr \u002F\u003E\n wordCram1.drawNext();<br \u002F>\u003Cbr \u002F\u003E\n buffer1.endDraw();<br \u002F>\u003Cbr \u002F\u003E\n image(buffer1, 0, 0);<\u002Fp>\u003Cbr \u002F\u003E\n<p>buffer1.beginDraw();<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F draw next word in lower word wave<br \u002F>\u003Cbr \u002F\u003E\n wordCram2.drawNext();<br \u002F>\u003Cbr \u002F\u003E\n buffer2.endDraw();<br \u002F>\u003Cbr \u002F\u003E\n image(buffer2, 0, frameHeight \u002F 2);<br \u002F>\u003Cbr \u002F\u003E\n buffer2.beginDraw();<br \u002F>\u003Cbr \u002F\u003E\n } else {<br \u002F>\u003Cbr \u002F\u003E\n buffer1.endDraw();<br \u002F>\u003Cbr \u002F\u003E\n buffer2.endDraw();<br \u002F>\u003Cbr \u002F\u003E\n image(buffer1, 0, 0);<br \u002F>\u003Cbr \u002F\u003E\n image(buffer2, 0, frameHeight \u002F 2);<br \u002F>\u003Cbr \u002F\u003E\n listSkippedWords(inputTextFile1.getName(), wordCram1);<br \u002F>\u003Cbr \u002F\u003E\n listSkippedWords(inputTextFile2.getName(), wordCram2);<br \u002F>\u003Cbr \u002F\u003E\n noLoop();<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F if no video then<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F save only last frame result<br \u002F>\u003Cbr \u002F\u003E\n if (!createVideo) {<br \u002F>\u003Cbr \u002F\u003E\n saveFrame(outputDir + fileName + &quot;.png&quot;);<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F for testing purposes within Eclipse<br \u002F>\u003Cbr \u002F\u003E\n if (testing) {<br \u002F>\u003Cbr \u002F\u003E\n createVideo();<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n processingDone = true;<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n if (drawTitle) {<br \u002F>\u003Cbr \u002F\u003E\n color(0);<br \u002F>\u003Cbr \u002F\u003E\n textSize(20);<br \u002F>\u003Cbr \u002F\u003E\n text(title1, 0, 0, frameWidth, 50);<br \u002F>\u003Cbr \u002F\u003E\n text(title2, 0, frameHeight \u002F 2, frameWidth, 50);<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n if (createVideo) {<br \u002F>\u003Cbr \u002F\u003E\n saveFrame(outputDir + fileName + &quot;-####.png&quot;);<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n}[\u002Fxml]\u003C\u002Fp\u003E\n\u003Cp\u003EA geração da nuvem de palavras acontece com uma palavra de cada vez. A Lista 6 usa dois buffers diferentes para duas nuvens de palavras e, então, ambos os buffers são desenhados na tela. Após a nuvem de palavras ser concluída, termine o desenho e liste todas as palavras ignoradas. Caso crie um vídeo, salve cada frame como uma imagem. Essas imagens são usadas para gerar o vídeo.\u003C\u002Fp\u003E\n\u003Cp\u003EO propósito do método \u003Ccode\u003ElistSkippedWords()\u003C\u002Fcode\u003E na Lista 7, é imprimir uma lista de palavras que não podem ser colocadas na visualização:\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]<\u002Fp>\u003Cbr \u002F\u003E\n<p>private void listSkippedWords(String desc, WordCram wordcram) {<br \u002F>\u003Cbr \u002F\u003E\n Word[] words = wordcram.getWords();<br \u002F>\u003Cbr \u002F\u003E\n int skipped = 0;<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F for each word check whether it was skipped<br \u002F>\u003Cbr \u002F\u003E\n List&lt;String&gt; skippedWords = new Vector&lt;String&gt;();<br \u002F>\u003Cbr \u002F\u003E\n for (Word word : words) {<br \u002F>\u003Cbr \u002F\u003E\n if (word.wasSkipped()) {<br \u002F>\u003Cbr \u002F\u003E\n int skippedBecause = word.wasSkippedBecause();<br \u002F>\u003Cbr \u002F\u003E\n if (skippedBecause == WordCram.NO_SPACE) {<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F increase number of skipped words<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F only if no space for word<br \u002F>\u003Cbr \u002F\u003E\n skippedWords.add(word.word);<br \u002F>\u003Cbr \u002F\u003E\n skipped++;<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F print number of skipped words<br \u002F>\u003Cbr \u002F\u003E\n if (skipped &gt; 0) {<br \u002F>\u003Cbr \u002F\u003E\n logger.debug(&quot;skippedWords: {}, {}&quot;, desc, skippedWords);<br \u002F>\u003Cbr \u002F\u003E\n Output.println(desc + &quot;: no space for &quot; + skipped + &quot; words: &quot;<br \u002F>\u003Cbr \u002F\u003E\n + skippedWords);<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n}[\u002Fxml]\u003C\u002Fp\u003E\n\u003Cp\u003ESe qualquer palavra ignorada for retornada, isso potencialmente significa que a visualização tem palavras importantes ausentes. Análises posteriores que são baseadas na visualização podem ser enganosas ou até mesmo falsas. Se qualquer palavra ignorada for retornada, é possível executar o programa novamente para que ele possa tentar posicionar todas as palavras na nuvem de palavras.\u003C\u002Fp\u003E\n\u003Cp\u003EA opção \u003Ccode\u003EcolorFor()\u003C\u002Fcode\u003E da Lista 8 implementa o método \u003Ccode\u003EWordColorer\u003C\u002Fcode\u003E da interface do WordCram. O método retorna cores escolhidas aleatoriamente a partir de uma lista predefinida.\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]<\u002Fp>\u003Cbr \u002F\u003E\n<p>public int colorFor(Word w) {<br \u002F>\u003Cbr \u002F\u003E\n int index = (int) random(colors.length);<br \u002F>\u003Cbr \u002F\u003E\n int colorHex = colors[index];<br \u002F>\u003Cbr \u002F\u003E\n int r = colorHex &gt;&gt; 16;<br \u002F>\u003Cbr \u002F\u003E\n int g = (colorHex &gt;&gt; 8) &amp; 0x0000ff;<br \u002F>\u003Cbr \u002F\u003E\n int b = colorHex &amp; 0x0000ff;<br \u002F>\u003Cbr \u002F\u003E\n logger.debug(&quot;R: {}, G: {}, B: {}&quot;, new Integer[] { r, g, b });<br \u002F>\u003Cbr \u002F\u003E\n return color(r, g, b);<br \u002F>\u003Cbr \u002F\u003E\n}[\u002Fxml]\u003C\u002Fp\u003E\n\u003Cp\u003ELista 9 mostra \u003Ccode\u003EcreateVideo()\u003C\u002Fcode\u003E, o método final que é chamado na Lista 6:\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]<\u002Fp>\u003Cbr \u002F\u003E\n<p>private void createVideo() {<br \u002F>\u003Cbr \u002F\u003E\n if (createVideo) {<br \u002F>\u003Cbr \u002F\u003E\n Output.println(&quot;Generating video…&quot;);<br \u002F>\u003Cbr \u002F\u003E\n try {<br \u002F>\u003Cbr \u002F\u003E\n File aviFile = new File(outputDir, fileName + &quot;.avi&quot;);<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F format specifies the type of video we are creating<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F video encoding, frame rate, and size is specified here<br \u002F>\u003Cbr \u002F\u003E\n Format format = new Format(org.monte.media.FormatKeys.EncodingKey,<br \u002F>\u003Cbr \u002F\u003E\n org.monte.media.VideoFormatKeys.ENCODING_AVI_PNG,<br \u002F>\u003Cbr \u002F\u003E\n org.monte.media.VideoFormatKeys.DepthKey, 24,<br \u002F>\u003Cbr \u002F\u003E\n org.monte.media.FormatKeys.MediaTypeKey, MediaType.VIDEO,<br \u002F>\u003Cbr \u002F\u003E\n org.monte.media.FormatKeys.FrameRateKey,<br \u002F>\u003Cbr \u002F\u003E\n new Rational(frameRate, 1),<br \u002F>\u003Cbr \u002F\u003E\n org.monte.media.VideoFormatKeys.WidthKey, width,<br \u002F>\u003Cbr \u002F\u003E\n org.monte.media.VideoFormatKeys.HeightKey, height);<br \u002F>\u003Cbr \u002F\u003E\n logger.debug(&quot;Framerate: {}&quot;, frameRate);<br \u002F>\u003Cbr \u002F\u003E\n AVIWriter out = null;<br \u002F>\u003Cbr \u002F\u003E\n try {<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F create new AVI writer with previously specified format<br \u002F>\u003Cbr \u002F\u003E\n out = new AVIWriter(aviFile);<br \u002F>\u003Cbr \u002F\u003E\n out.addTrack(format);<br \u002F>\u003Cbr \u002F\u003E\n int i = 1;<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F read the first image file<br \u002F>\u003Cbr \u002F\u003E\n String frameFileName = String.format(fileName + &quot;-%04d.png&quot;, i);<br \u002F>\u003Cbr \u002F\u003E\n File frameFile = new File(outputDir, frameFileName);<br \u002F>\u003Cbr \u002F\u003E\n while (frameFile.exists()) {<br \u002F>\u003Cbr \u002F\u003E\n logger.debug(&quot;Frame filename: {}&quot;, frameFileName);<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F while frame images exist<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F create a Buffer and write it to AVI writer<br \u002F>\u003Cbr \u002F\u003E\n Buffer buf = new Buffer();<br \u002F>\u003Cbr \u002F\u003E\n buf.format = new Format(org.monte.media.FormatKeys.EncodingKey,<br \u002F>\u003Cbr \u002F\u003E\n org.monte.media.VideoFormatKeys.ENCODING_BUFFERED_IMAGE,<br \u002F>\u003Cbr \u002F\u003E\n org.monte.media.VideoFormatKeys.DataClassKey,<br \u002F>\u003Cbr \u002F\u003E\n BufferedImage.class).append(format);<br \u002F>\u003Cbr \u002F\u003E\n buf.sampleDuration = format.get(<br \u002F>\u003Cbr \u002F\u003E\n org.monte.media.FormatKeys.FrameRateKey).inverse();<br \u002F>\u003Cbr \u002F\u003E\n buf.data = ImageIO.read(frameFile);<br \u002F>\u003Cbr \u002F\u003E\n out.write(0, buf);<br \u002F>\u003Cbr \u002F\u003E\n \u002F\u002F read next frame image<br \u002F>\u003Cbr \u002F\u003E\n i++;<br \u002F>\u003Cbr \u002F\u003E\n frameFileName = String.format(fileName + &quot;-%04d.png&quot;, i);<br \u002F>\u003Cbr \u002F\u003E\n frameFile = new File(outputDir, frameFileName);<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n } finally {<br \u002F>\u003Cbr \u002F\u003E\n if (out != null) {<br \u002F>\u003Cbr \u002F\u003E\n out.close();<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n Output.println(&quot;Done.&quot;);<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n } catch (IOException e) {<br \u002F>\u003Cbr \u002F\u003E\n logger.error(e.toString(), e);<br \u002F>\u003Cbr \u002F\u003E\n Output.error(e.toString());<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n }<br \u002F>\u003Cbr \u002F\u003E\n}[\u002Fxml]\u003C\u002Fp\u003E\n\u003Cp\u003EA Lista 9 demonstra a simplicidade de criar um vídeo a partir de imagens. É necessário apenas especificar um formato de vídeo e, em seguida, criar o vídeo com uma imagem de cada vez.\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N103C6\"\u003E\u003C\u002Fa\u003EAdicione opções de linha de comando ao plugin.xml\u003C\u002Fh3\u003E\n\u003Cp\u003EAgora, o código está pronto. Antes de implementá-lo, adicione as opções de linha de comando ao arquivo plugin.xml para que o Command Line Program possa analisá-las:\u003C\u002Fp\u003E\n\u003Col\u003E\n\u003Cli\u003EAbra o plugin.xml e abra a guia Extensions;\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione \u003Ccode\u003E\u003Cstrong\u003Ecompare-command\u003C\u002Fstrong\u003E\u003C\u002Fcode\u003E, clique com o botão direito do mouse e selecione New > option;\u003C\u002Fli\u003E\n\u003Cli\u003EA opção \u003Ccode\u003Einput1\u003C\u002Fcode\u003E, \u003Ccode\u003Einput2\u003C\u002Fcode\u003E e \u003Ccode\u003Evideo\u003C\u002Fcode\u003E são necessárias para o aplicativo. \u003Ccode\u003Einput1\u003C\u002Fcode\u003E e \u003Ccode\u003Einput2\u003C\u002Fcode\u003E especificam os nomes de arquivo dos dois arquivos de texto que se deseja comparar. \u003Ccode\u003Evideo\u003C\u002Fcode\u003E gera o vídeo (ou, caso seja omitido, não gera o vídeo). Figura 7 mostra a classe \u003Ccode\u003Einput1\u003C\u002Fcode\u003E de definição de opção (\u003Ccode\u003EText 1 file to compare\u003C\u002Fcode\u003E) e outras opções que podem ser adicionadas caso desejado:\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cfigure id=\"attachment_45693\" aria-describedby=\"caption-attachment-45693\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45693\" rel=\"attachment wp-att-45693\"\u003E\u003Cimg class=\"size-full wp-image-45693\" alt=\"Figura 7. Opções de comando\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure007.jpg\" width=\"580\" height=\"347\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure007.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure007-300x179.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45693\" class=\"wp-caption-text\"\u003EFigura 7. Opções de comando\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003EA opção \u003Ccode\u003ECompare\u003C\u002Fcode\u003E para o Command Line Program agora está concluída e é possível implementá-la.\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"N1041C\"\u003E\u003C\u002Fa\u003EInstalando o aplicativo\u003C\u002Fh2\u003E\n\u003Cp\u003EPara usar a classe \u003Ccode\u003ETextVisualizationAndAnalysis\u003C\u002Fcode\u003E (aplicativo), é necessário implementá-la no Command Line Program. Crie um recurso e um site de atualização para o plug-in \u003Ccode\u003ETextVisualizationAndAnalysis\u003C\u002Fcode\u003E e instale-o no Command Line Program.\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"N1042C\"\u003E\u003C\u002Fa\u003ECrie um recurso\u003C\u002Fh2\u003E\n\u003Cp\u003EOs recursos no Eclipse são coleções de plug-ins que podem ser instaladas e atualizadas. O Command Line Program usa a funcionalidade de recurso padrão do Eclipse para permitir a instalação e a atualização de novos comandos de extensão. As etapas rápidas para criar um recurso para o comando \u003Ccode\u003ECompare\u003C\u002Fcode\u003E são:\u003C\u002Fp\u003E\n\u003Col\u003E\n\u003Cli\u003ECrie um projeto de recurso e atribua o nome de \u003Ccode\u003ETextVisualizationAndAnalysisFeature;\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003EDefina o número da versão para 0.0.1 e clique em Próximo;\u003C\u002Fli\u003E\n\u003Cli\u003ESelecionar o ponto de rastreamento \u003Ccode\u003ETextVisualizationAndAnalysis\u003C\u002Fcode\u003E (plug-in) e clique em Concluir;\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Ch2\u003E\u003Ca name=\"N10452\"\u003E\u003C\u002Fa\u003EGere um site de atualização\u003C\u002Fh2\u003E\n\u003Cp\u003EOs sites de atualização incluem recursos que podem ser instalados nos aplicativos. O site de atualização pode ser um diretório local ou um servidor da web remoto. Para gerar um site de atualização para o programa TextVisualizationAndAnalysis:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003ECrie um projeto de site de atualização e atribua o nome de \u003Ccode\u003ETextVisualizationAndAnalysisUpdateSite;\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003ENa página Update Site Map, em Managing the Site, selecione Add Feature para adicionar\u003Ccode\u003ETextVisualizationAndAnalysisFeature\u003C\u002Fcode\u003E, como mostra a Figura 8:\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cfigure id=\"attachment_45694\" aria-describedby=\"caption-attachment-45694\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45694\" rel=\"attachment wp-att-45694\"\u003E\u003Cimg class=\"size-full wp-image-45694\" alt=\"Figura 8. Página Update Site Map\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure008.jpg\" width=\"580\" height=\"313\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure008.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure008-300x161.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45694\" class=\"wp-caption-text\"\u003EFigura 8. Página Update Site Map\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cul\u003E\n\u003Cli\u003EClique em Build All.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch2\u003EInstale o comando\u003C\u002Fh2\u003E\n\u003Cp\u003ENão é possível executar o comando independentemente porque é necessário instalá-lo no Command Line Program. A instalação é feita com o Command Line Program em si. Insira o \u003Ccode\u003Eadmin,\u003C\u002Fcode\u003E (comando) (que aqui assume que o site de atualização criado está no diretório c:\u002Fworkspace\u002F):\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]clp.cmd admin –install –dir=’c:\\workspace\\TextVisualizationAndAnalysisUpdateSite'[\u002Fxml]\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"runapp\"\u003E\u003C\u002Fa\u003EExecutar o aplicativo\u003C\u002Fh2\u003E\n\u003Cp\u003EAqui estão alguns comandos de amostra que mostram como executar o aplicativo.\u003C\u002Fp\u003E\n\u003Cp\u003EGerar e mostrar uma imagem de comparação de texto:\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]clp.cmd compare –input1=’c:\u002Fpath\u002Ffile1.txt’ –input2=’c:\u002Fpath\u002Ffile2.txt'[\u002Fxml]\u003C\u002Fp\u003E\n\u003Cp\u003EUsar os nomes de arquivos como um título para a visualização:\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]clp.cmd compare –input1=’c:\u002Fpath\u002Ffile1.txt’ –input2=’c:\u002Fpath\u002Ffile2.txt’ –title[\u002Fxml]\u003C\u002Fp\u003E\n\u003Cp\u003EUsar títulos customizados:\u003C\u002Fp\u003E\n\u003Cp\u003E[xml]<\u002Fp>\u003Cbr \u002F\u003E\n<p>clp.cmd compare –input1=’c:\u002Fpath\u002Ffile1.txt’ –input2=’c:\u002Fpath\u002Ffile2.txt'<br \u002F>\u003Cbr \u002F\u003E\n –title –title1=’Text1′ –title2=’Text2′ [\u002Fxml]\u003C\u002Fp\u003E\n\u003Cp\u003EGerar uma imagem e um vídeo:\u003C\u002Fp\u003E\n\u003Cp\u003E[xml] clp.cmd compare –input1=’c:\u002Fpath\u002Ffile1.txt’ -–input2=’c:\u002Fpath\u002Ffile2.txt’ -title –video [\u002Fxml]\u003C\u002Fp\u003E\n\u003Ch2\u003EResultados e análises\u003C\u002Fh2\u003E\n\u003Cp\u003EAgora é possível colocar o aplicativo\u003Ccode\u003ETextVisualizationAndAnalysis\u003C\u002Fcode\u003E em funcionamento. Eu o utilizei para visualizar dois textos semelhantes: as declarações de missão publicamente disponíveis de duas corporações no mesmo segmento de mercado, a — Coca Cola Company e a o PepsiCo (consulte Recursos). Em seguida, usei a visualização para fazer uma análise. A suposição é de que as ondas de palavras irão visualizar o que essas corporações acreditam que seja mais importante para elas, agora e no futuro. (Para obter os textos de origem e o código de aplicativo completo no projeto de plug-in consulte Downloads).\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"N1051A\"\u003E\u003C\u002Fa\u003EVisualização\u003C\u002Fh2\u003E\n\u003Cp\u003EUsei o último comando na seção anterior, Executar o aplicativo, para gerar a imagem e o vídeo. A Figura 9 é uma comparação de visualização dos dois textos:\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45695\" aria-describedby=\"caption-attachment-45695\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45695\" rel=\"attachment wp-att-45695\"\u003E\u003Cimg class=\"size-full wp-image-45695\" alt=\"Figura 9. Visualização de dois textos semelhantes\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure009.jpg\" width=\"580\" height=\"326\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure009.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure009-300x168.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45695\" class=\"wp-caption-text\"\u003EFigura 9. Visualização de dois textos semelhantes\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003EA onda de palavras superior na Figura 9 visualiza a declaração Mission, Vision & Values da Coca-Cola, que aponta sua missão, visão e valores. A da parte inferior visualiza a declaração Value & Philosophy da PepsiCo, que aponta seus valores e filosofia. As ondas de palavras mostram as 50 palavras mais usadas nos textos, com as palavras mencionadas com maior frequência no canto superior esquerdo. O tamanho da fonte diminui para a direita, indicando que as palavras no canto inferior direito são mencionadas com menor frequência do que as palavras na parte superior esquerda.\u003C\u002Fp\u003E\n\u003Cp\u003ENa barra lateral, veja um vídeo de dez segundos da geração palavra a palavra da visualização\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"N1054E\"\u003E\u003C\u002Fa\u003EAnálise\u003C\u002Fh2\u003E\n\u003Cp\u003EPara analisar a comparação da visualização na Figura 9, atribua a maior importância às palavras no quarto mais a esquerda. Primeiro desenhei uma linha vertical na visualização aproximadamente em um quarto a partir da esquerda de cada onda de palavras, como na Figura 10:\u003C\u002Fp\u003E\n\u003Cfigure id=\"attachment_45696\" aria-describedby=\"caption-attachment-45696\" style=\"width: 580px\" class=\"wp-caption aligncenter\"\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=45696\" rel=\"attachment wp-att-45696\"\u003E\u003Cimg class=\"size-full wp-image-45696\" alt=\"Figura 10. Análises de dois textos\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure010.jpg\" width=\"580\" height=\"326\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure010.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F08\u002Ffigure010-300x168.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003Cfigcaption id=\"caption-attachment-45696\" class=\"wp-caption-text\"\u003EFigura 10. Análises de dois textos\u003C\u002Ffigcaption\u003E\u003C\u002Ffigure\u003E\n\u003Cp\u003EPresumo que as palavras à esquerda da linha são o que ambas as corporações consideram o mais importante.\u003C\u002Fp\u003E\n\u003Cp\u003EA Coca-Cola parece ter o foco em sua visão e ter um roteiro para conquistar essa visão. Ela também parece ver o mundo como seus negócios e valoriza ações e a qualidade de seu trabalho para conquistar sua visão.\u003C\u002Fp\u003E\n\u003Cp\u003EA PepsiCo parece dizer que seu propósito comercial é o crescimento da empresa, incluindo o desempenho financeiro. Ela também parece valorizar os aspectos ambientais e sociais.\u003C\u002Fp\u003E\n\u003Cp\u003EEssa rápida comparação das visualizações nos mostra, então, como duas corporações no mesmo segmento de mercado podem ser diferentes em seu pensamento. Uma conclusão razoável da análise é a de que a Coca-Cola Company está mais preocupada com seu lugar no mundo futuro e que a PepsiCo está mais preocupada com os negócios e seu crescimento.\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"N1057A\"\u003E\u003C\u002Fa\u003EAtualizando o aplicativo\u003C\u002Fh2\u003E\n\u003Cp\u003EEm algum momento pode-se desejar atualizar o aplicativo \u003Ccode\u003ETextVisualizationAndAnalysis\u003C\u002Fcode\u003E . A atualização usa o mesmo mecanismo que a instalação. Siga essas etapas para atualizar o aplicativo:\u003C\u002Fp\u003E\n\u003Col\u003E\n\u003Cli\u003EFaça as alterações necessárias no código ou em outros arquivos.\u003C\u002Fli\u003E\n\u003Cli\u003EAumente a versão do plug-in e do recurso.\n\u003Cul\u003E\n\u003Cli\u003EImportante: Tanto o plug-in como o recurso precisam de uma alteração de versão. Caso contrário, o mecanismo de atualização falha em detectar que foram realizadas alterações.\u003C\u002Fli\u003E\n\u003Cli\u003EO número da versão deve ser aumentado pelo menos no segmento do serviço. Por exemplo, a versão antiga é 0.0.1 e a nova versão é 0.0.2.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EAdicione a nova versão ao site de atualização e ao site de atualização de desenvolvimento.\u003C\u002Fli\u003E\n\u003Cli\u003EExecute esse comando:\n\u003Cpre\u003Eclp.cmd admin --update --dir='c:\\workspace\\TextVisualizationAndAnalysisUpdateSite'\u003C\u002Fpre\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EExecute o aplicativo normalmente\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Ch2\u003E\u003Ca name=\"N105A9\"\u003E\u003C\u002Fa\u003EConclusão\u003C\u002Fh2\u003E\n\u003Cp\u003EA visualização é uma ferramenta eficiente para colher novos insights de textos. Foram usadas ferramentas de software livre para desenvolver um aplicativo de visualização que compara e analisa quaisquer dois textos. O aplicativo TextVisualizationAndAnalysis está pronto para comparar quaisquer outros tipos de texto — por exemplo, estratégias corporativas, biografias de celebridades ou obras de ficção. Melhor ainda, é possível usar as técnicas e ferramentas sobre as quais aprendeu aqui para criar seus próprios aplicativos de visualização.\u003C\u002Fp\u003E\n\u003Cp\u003EDownloads\u003C\u002Fp\u003E\n\u003Ctable summary=\"Esta tabela contém downloads para este documento.\" width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n\u003Cth scope=\"col\"\u003EDescrição\u003C\u002Fth\u003E\n\u003Cth scope=\"col\"\u003ENome\u003C\u002Fth\u003E\n\u003Cth scope=\"col\"\u003ETamanho\u003C\u002Fth\u003E\n\u003Cth scope=\"col\"\u003EMétodo de download\u003C\u002Fth\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd scope=\"row\"\u003EPlug-in projects, ready to import into Eclipse\u003C\u002Ftd\u003E\n\u003Ctd nowrap=\"nowrap\"\u003ETextVisualizationAndAnalysis_projects.zip\u003C\u002Ftd\u003E\n\u003Ctd nowrap=\"nowrap\"\u003E1.3MB\u003C\u002Ftd\u003E\n\u003Ctd nowrap=\"nowrap\"\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fapps\u002Fdownload\u002Findex.jsp?contentid=936241&filename=TextVisualizationAndAnalysis_projects.zip&method=http&locale=pt_BR\"\u003EHTTP\u003C\u002Fa\u003E\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd scope=\"row\"\u003EUpdate site for deploying to Command Line Program\u003C\u002Ftd\u003E\n\u003Ctd nowrap=\"nowrap\"\u003ETextVisualizationAndAnalysisUpdateSite.zip\u003C\u002Ftd\u003E\n\u003Ctd nowrap=\"nowrap\"\u003E1.3MB\u003C\u002Ftd\u003E\n\u003Ctd nowrap=\"nowrap\"\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fapps\u002Fdownload\u002Findex.jsp?contentid=936241&filename=TextVisualizationAndAnalysisUpdateSite.zip&method=http&locale=pt_BR\"\u003EHTTP\u003C\u002Fa\u003E\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003C\u002Ftbody\u003E\n\u003C\u002Ftable\u003E\n\u003Cp\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Flibrary\u002Fwhichmethod.html\"\u003EInformações sobre métodos de download\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"resources\"\u003E\u003C\u002Fa\u003ERecursos\u003C\u002Fh2\u003E\n\u003Ch3\u003EAprender\u003C\u002Fh3\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fhelp.eclipse.org\u002Fjuno\u002Fnav\u002F4_1\"\u003EEclipse plug-in concepts\u003C\u002Fa\u003E: Leia sobre os recursos, sites de atualização e outros conceitos do plug-in do Eclipse no Plug-in Development Environment Guide.\u003C\u002Fli\u003E\n\u003Cli\u003E“\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fopensource\u002Flibrary\u002Fos-datavis\u002Findex.html\"\u003EData visualization with Processing, Part 1: An introduction to the language and environment\u003C\u002Fa\u003E” (M. Tim Jones, developerWorks, novembro de 2010): Apresentação ao ambiente e à linguagem do Processing na primeira parte de uma série de três artigos.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fopenprocessing.org\u002F\"\u003EOpenProcessing\u003C\u002Fa\u003E: Visite esse site para visualizar uma extensa galeria de rascunhos que foram criados como Processing.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.thecocacolacompany.com\u002Fourcompany\u002Fmission_vision_values.html\"\u003EMission, Vision & Values:\u003C\u002Fa\u003E O texto da Coca-Cola Company que é usado no exemplo no artigo é do segundo trimestre de 2012.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.pepsico.com\u002FCompany\u002FPepsiCo-Values-and-Philosophy.html\"\u003EPepsiCo Values & Philosophy\u003C\u002Fa\u003E O texto da PepsiCo que é usado no exemplo no artigo (sem incluir sua seção Guiding Principles) é do segundo trimestre de 2012.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww-958.ibm.com\u002Fsoftware\u002Fdata\u002Fcognos\u002Fmanyeyes\u002Fvisualizations\"\u003EIBM Many Eyes visualizations\u003C\u002Fa\u003E: Essas visualizações, geradas com o IBM Many Eyes, incluem a \u003Ca href=\"http:\u002F\u002Fwww-958.ibm.com\u002Fsoftware\u002Fdata\u002Fcognos\u002Fmanyeyes\u002Fvis\u002FFullScreen\u002Ffullscreenvisualization.html?id=files%2Fthumbnails%2F29d29180-6f31-11e1-ab37-000255111976.wm.png&visId=29fdf94c6f3111e1ab37000255111976\"\u003Enuvem de palavras\u003C\u002Fa\u003E em \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Flibrary\u002Fos-txtviz\u002Findex.html#figure1\"\u003Ea Figura 1\u003C\u002Fa\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fsami.salkosuo.net\u002F\"\u003EBlog do Sami Salkosuo\u003C\u002Fa\u003E: O blog do Sami inclui muitas visualizações de nuvem de palavras que foram geradas com as ferramentas nesse artigo.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbigdata\u002Fstreams\u002Findex.html\"\u003EIBM InfoSphere Streams\u003C\u002Fa\u003E: Obtenha uma plataforma de analítica escalável eficiente que pode manipular taxas de rendimento de dados inacreditavelmente altas que podem variar de milhões de eventos ou mensagens por segundo.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbigdata\u002Fbiginsights\u002Findex.html\"\u003EIBM InfoSphere BigInsights\u003C\u002Fa\u003E: Gerencie e analise grandes volumes de dados estruturados e não estruturados em repouso com o InfoSphere BigInsights, a distribuição desenvolvida do Hadoop para a analítica de Big Data da IBM. Ele amplia o Hadoop com recursos corporativos, incluindo analítica avançada, aceleradores de aplicativo, suporte a diversas distribuições, otimização de desempenho, integração corporativa entre outros.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fopensource\u002F\"\u003ETópico técnico do Open source no developerWorks\u003C\u002Fa\u003E: encontre informações práticas, ferramentas e atualizações de projeto amplas para ajudá-lo a desenvolver com tecnologias de software livre e utilizá-las com produtos IBM.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch3\u003EObter produtos e tecnologias\u003C\u002Fh3\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.eclipse.org\u002Fjuno\u002F\"\u003EEclipse\u003C\u002Fa\u003E: Faça o download do Eclipse para sua plataforma.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fsoftabar.com\u002Fhome\u002Fcommand-line-program-platform\u002F\"\u003ECommand Line Program\u003C\u002Fa\u003E: O Command Line Program da Softbar é uma plataforma de software livre para o desenvolvimento de aplicativos de linha de comando.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.randelshofer.ch\u002Fmonte\u002Findex.html\"\u003EMonte Media Library\u003C\u002Fa\u003E: A Monte Media Library é a biblioteca Java para o processamento de dados de mídia.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fprocessing.org\u002F\"\u003EO processamento de \u003C\u002Fa\u003E: Processing é um ambiente e uma linguagem de programação de software livre para criar imagens, animações e interações.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwordcram.org\u002F\"\u003EWordCram\u003C\u002Fa\u003E: WordCram é uma biblioteca do Processing para a geração de nuvens de palavras.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.videolan.org\u002Fvlc\u002Findex.html\"\u003EVLC\u003C\u002Fa\u003E: VLC é um reprodutor multimídia de software livre grátis.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"https:\u002F\u002Fwww14.software.ibm.com\u002Fwebapp\u002Fiwm\u002Fweb\u002FpreLogin.do?source=SWG-STREAMS_TRIAL&S_CMP=web_dw_rt_swd\"\u003EIBM InfoSphere Streams\u003C\u002Fa\u003E: Faça download do InfoSphere Streams e desenvolva aplicativos que rapidamente alimentam, analisam e correlacionam as informações conforme elas chegam de milhares de fontes em tempo real.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"https:\u002F\u002Fwww14.software.ibm.com\u002Fwebapp\u002Fiwm\u002Fweb\u002FpreLogin.do?source=swg-ibmibee&S_CMP=web_dw_rt_swd\"\u003EIBM InfoSphere BigInsights\u003C\u002Fa\u003E: Faça download do InfoSphere BigInsights e gerencie e analise grandes volumes de dados estruturados e não estruturados em repouso.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch3\u003EDiscutir\u003C\u002Fh3\u003E\n\u003Cul\u003E\n\u003Cli\u003EParticipe da \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fcommunity\u002F\"\u003Ecomunidade do developerWorks\u003C\u002Fa\u003E. Conecte-se com outros usuários do developerWorks enquanto explora as wikis, os grupos, os fóruns e blogs voltados aos desenvolvedores.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E***\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003ESobre o autor:\u003C\u002Fstrong\u003E Sami Salkosuo é Software Client Architect (também conhecido como Software IT Architect) do IBM Software Group na Finlândia, e trabalhou na IBM por aproximadamente 15 anos atualmente trabalha com os clientes no setor de manufatura. Ele também é autor do Command Line Email Client for Lotus Notes, um projeto de software livre disponível em \u003Ca href=\"http:\u002F\u002Fopenntf.org\u002F\"\u003EOpenNTF.org\u003C\u002Fa\u003E. Em seu tempo livre, ele gosta de escrever ficção científica como autor independente. É possível visitar o \u003Ca href=\"http:\u002F\u002Fsami.salkosuo.net\u002F\"\u003Eblog de Sami\u003C\u002Fa\u003E ou segui-lo no \u003Ca href=\"https:\u002F\u002Ftwitter.com\u002FSamiSalkosuo\"\u003ETwitter\u003C\u002Fa\u003E.\u003C\u002Fp\u003E\n\u003Cp\u003E***\u003C\u002Fp\u003E\n\u003Cp\u003EArtigo original disponível em: \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Flibrary\u002Fos-txtviz\u002Findex.html\"\u003Ehttp:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Flibrary\u002Fos-txtviz\u002Findex.html\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n","excerpt":"\u003Cp\u003EO artigo mostra como desenvolver um software de análise e visualização de texto com bibliotecas e ferramentas de software livre. \u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fdesenvolva-um-aplicativo-de-analitica-e-visualizacao-de-texto","date":"8 ago, 2013","thumbnail":"","externalMention":null,"author":{"id":421,"thumbnail":"https:\u002F\u002Fsecure.gravatar.com\u002Favatar\u002Fbe5bc6f39606ac453a07bd2eb7ab21af?s=96&d=mm&r=g","name":"developerWorks Brasil","description":"é o portal de tecnologia da IBM para profissionais de TI de todo o mundo. Colabore, aprenda a criar aplicativos inovadores e compreenda tecnologias avançadas. Acesse mais artigos e tutoriais em www.ibm.com\u002Fdeveloperworks\u002Fbr","slug":"developerworks_brasil","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdeveloperworks_brasil","registered":"2010-07-07 17:06:45","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002Fsoudw","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002F","mail":"dwbr@br.ibm.com"},"articles_count":217,"views_count":4709798,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"Desenvolvimento","slug":"desenvolvimento","id":7234,"link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento"},{"title":"Mobile","slug":"mobile","id":4255,"link":"https:\u002F\u002Fimasters.com.br\u002Fmobile"}],"tags":[{"title":"aplicativo","slug":"aplicativo","id":649,"link":"https:\u002F\u002Fimasters.com.br\u002Faplicativo"},{"title":"app","slug":"app","id":615,"link":"https:\u002F\u002Fimasters.com.br\u002Fapp"},{"title":"desenvolvimento","slug":"desenvolvimento-2","id":186,"link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento-2"},{"title":"mobile","slug":"mobile-2","id":220,"link":"https:\u002F\u002Fimasters.com.br\u002Fmobile-2"}],"seo":{"open_graph":{"title":"Desenvolva um aplicativo de análise e visualização de texto - iMasters - We are Developers","description":"O artigo mostra como desenvolver um software de análise e visualização de texto com bibliotecas e ferramentas de software livre.","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":false,"modified_time":"2013-08-06T17:24:47-03:00","published_time":"2013-08-08T14:00:31-03:00"},"twitter":{"title":"Desenvolva um aplicativo de análise e visualização de texto - iMasters - We are Developers","description":"O artigo mostra como desenvolver um software de análise e visualização de texto com bibliotecas e ferramentas de software livre.","type":"summary_large_image","image":false}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fdesenvolva-um-aplicativo-de-analitica-e-visualizacao-de-texto","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fdesenvolva-um-aplicativo-de-analitica-e-visualizacao-de-texto","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fdesenvolva-um-aplicativo-de-analitica-e-visualizacao-de-texto"},"type":"post"},{"id":45577,"title":"Agile DevOps: quebrando os silos","content":"\u003Cp\u003EAs pessoas em empresas que criam sistemas e produtos de software frequentemente me perguntam “Como mudamos nossa organização nem realmente mudá-la?”. Claro, elas não usam essas palavras de fato (pelo menos não \u003Cem\u003Etodas \u003C\u002Fem\u003Eas vezes), mas é essa a implicação. Elas desejam minimizar o esforço e o risco envolvido no release de software, mas percebem que isso exige mudanças (culturais e técnicas) em toda a organização e que nem sempre elas têm o poder ou influência para afetar.\u003C\u002Fp\u003E\n\u003Cp\u003EUm obstáculo cultural que elas normalmente encontram é que equipes de operações e desenvolvimento tradicionais tendem a trabalhar em silos, limitando a quantidade de comunicação entre as equipes até os momentos de release do software. (E tal comunicação frequentemente é confinada em uma série de chamados em um sistema de acompanhamento de problema.) As empresas de software em crescimento \u003Cem\u003Edevem\u003C\u002Fem\u003E se tornar mais colaborativas, caso contrário deixarão de existir. O segmento de mercado de software está mudando nessa direção—muito mais rapidamente do que algumas pessoas previram—como resultado da computação em nuvem, que fazem com que os recursos de computação sejam menos escassos e da demanda de negócios. As empresas que se desenvolverem tirarão as que não se desenvolverem dos negócios.\u003C\u002Fp\u003E\n\u003Cp\u003EComo enfatizado \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fjava\u002Flibrary\u002Fa-devops1\u002F\"\u003Eartigo introdutório\u003C\u002Fa\u003E dessa \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fviews\u002Fagile\u002Flibraryview.jsp?series_title_by=agile+devops\"\u003Esérie \u003C\u002Fa\u003E, a colaboração além dos limites organizacionais é uma das âncoras do agile DevOps. Esse artigo discute como o estabelecimento de equipes multidisciplinares e a ampliação dos conjuntos de qualificações dos membros da equipe de entrega são formas de aumentar a colaboração e transpor as barreiras tradicionais que impedem que os softwares sejam entregues continuamente.\u003C\u002Fp\u003E\n\u003Ch2\u003EO crescimento das equipes multidisciplinares\u003C\u002Fh2\u003E\n\u003Cp\u003EO \u003Cem\u003Eequipe multidisciplinar\u003C\u002Fem\u003E consiste em especialistas em todo o ciclo de fornecimento de software, como engenheiros de operações, administradores de banco de dado (DBAs), testadores e analistas. Todos em uma equipe multidisciplinar contribuem com código para um repositório de controle de versão. Por exemplo, o engenheiro de operações contribui com a configuração e infraestrutura como um código, o DBA contribui com Linguagem de Definição de Dados (DDL), Linguagem de Modelagem de Dados (DML) e conjuntos de dados como código, o desenvolvedor contribui com configuração e código de aplicativo e os testadores contribuem com códigos como código.\u003C\u002Fp\u003E\n\u003Cp\u003ETodos os membros de uma equipe multidisciplinar são responsáveis pelo processo de entrega. Qualquer pessoa na equipe pode modificar qualquer parte do sistema de software. O antipadrão correspondente são as equipes isoladas, que no desenvolvimento, teste e operações têm seus próprios scripts e processos e não fazem parte da mesma equipe.\u003C\u002Fp\u003E\n\u003Cp\u003EEntão, as equipes multidisciplinares consistem em indivíduos de todas as disciplinas responsáveis pelo desenvolvimento e entrega de sistemas de software. Em vez de tratar cada disciplina como uma organização de serviço centralizada separada, a equipe de entrega se torna o constructo organizacional chave. As equipes trabalham em conjunto de uma forma dedicada para entregar o software de forma consistente, sem os impedimentos de tempo inerentes de quando as equipes se comunicam através da organização. Considere a composição de cada equipe por (pelo menos) analistas de negócios, representantes de serviços, DBAs, desenvolvedores, gerentes de projeto e controle de qualidade (QA) e engenheiros de liberação. Com uma equipe multidisciplinar, a síndrome do “não é meu trabalho” e outras “paredes” que reprimem a comunicação entre as equipes dentro e através de locais físicos são reduzidas.\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cp\u003E\u003Cstrong\u003EA função dos especialistas\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EPara as novas equipes multidisciplinares compostas por pessoas acostumadas a trabalhar em organizações baseadas em serviços matriciadas, pode demorar um pouco para elas se familiarizarem com trabalhar em uma equipe multidisciplinar. Normalmente, os conjuntos de qualificações das pessoas na equipe são mais limitados e precisam ser expandidos. Nesse contexto, nos projetos piloto iniciais, os especialistas na organização (por exemplo, especialistas em segurança) devem ser trazidos para aconselhar os membros da equipe multidisciplinar. Os consultores não fazem parte da equipe multidisciplinar e eles não contribuem com testes ou códigos. Seu objetivo é expandir o conjunto de qualificações dos membros da equipe multidisciplinar. Conforme ele é expandido, a equipe irá recorrer menos aos consultores.\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\n\u003Ch3\u003ETodos fazendo tudo\u003C\u002Fh3\u003E\n\u003Cp\u003EApós um período, será possível perceber que os conjuntos de qualificação frequentemente mudam para engenheiros\u002Fanalistas mais completos que começam a realizar mais do que apenas uma parte do processo de entrega de software. Por exemplo, um programa pode criar scripts de DDL e DML. Ou os analistas de negócios definem seus requisitos em scripts de aceitação de teste (como Cucumber) para que todas as mudanças sejam feitas através de testes automatizados baseados nos requisitos do cliente. Cada membro da equipe sabe que precisa escrever testes, scripts, versões (consulte “\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fjava\u002Flibrary\u002Fa-devops6\u002F\"\u003EAgile DevOps: Version everything\u003C\u002Fa\u003E“), e fazer com que tudo o que é feito seja parte de um sistema contínuo (consulte “\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fjava\u002Flibrary\u002Fa-devops8\u002F\"\u003EAgile DevOps: Continuous delivery platform\u003C\u002Fa\u003E“). Esse é o caso para todos os artefatos de origem: código do aplicativo, configuração, infraestrutura e dados. Quando os membros da equipe se tornam multiqualificados e os silos são desmanchados, a comunicação é melhorada e os gargalos são removidos das organizações de software do passado.\u003C\u002Fp\u003E\n\u003Ch3\u003EO processo\u003C\u002Fh3\u003E\n\u003Cp\u003ETudo o que compõe o sistema de software completo é um script (isto é, um programa) ou um teste automatizado. Todos esses componentes do sistema de software são identificados com a versão e tudo é incorporado em um pipeline de entrega contínua. Dessa forma, quando qualquer material com que qualquer membro contribuir for verificado no repositório de controle de versão, é criado o sistema de software completo,—incluindo ambientes, banco(s) de dado(s) e o serviço\u002Faplicativo de software usando a configuração com versão. Todos os componentes do sistema são identificados com versão, sem exceção. Os membros da equipe multidisciplinar são 100% dedicados ao projeto e não são afiliados a nenhum outro projeto. Essa abordagem aumenta a comunicação e reduz quaisquer gargalos do processo.\u003C\u002Fp\u003E\n\u003Ch2\u003EComo funciona?\u003C\u002Fh2\u003E\n\u003Cp\u003ERealizar a mudança cultural em uma organização é o elemento mais essencial da implementação do DevOps. Nada significativo irá acontecer a menos que isso seja realizado. Essa seção discute uma abordagem de alto nível da execução da transição para —e funcionando efetivamente com—equipes multidisciplinares.\u003C\u002Fp\u003E\n\u003Ch3\u003EProjetos piloto\u003C\u002Fh3\u003E\n\u003Cp\u003EAs tentativas de mudar uma grande organização de uma só vez quase sempre tem a garantia de falharem. A abordagem preferencial é começar com um pequeno projeto piloto que forneça algo de valor de negócios para a produção em um período de tempo relativamente curto—de maneira ideal, não mais de 90 dias. O projeto piloto deve ser algo estratégico—não um aplicativo que raramente é atualizado e proporciona um valor de negócios mínimo. Essa nova equipe será uma equipe multidisciplinar e todos os membros estarão completamente dedicados ao projeto. (Eles não trabalharão em outros projetos.) Todas as funções necessárias para o desenvolvimento do sistema de software (operações desenvolvedores de aplicativos, bancos de dados, testadores, etc.) serão uma parte dessa equipe multidisciplinar.\u003C\u002Fp\u003E\n\u003Cp\u003EApós ter comprovado o sucesso com um projeto, é possível escalar para mais alguns. Esses outros projetos terão membros de equipe do primeiro projeto piloto que irão compartilhar seu conhecimento e cada um será um membro integral da nova equipe. Após esses projetos serem bem sucedidos, as equipes piloto subsequentes serão duplicadas ou triplicadas até todos os projetos estratégicos estarem operando no novo modelo.\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cp\u003E\u003Cstrong\u003EArquiteturas orientadas a serviços\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EPara trabalhar em pequenas equipes que se comunicam efetivamente, é necessário desmontar as arquiteturas monolíticas. Arquiteturas que têm muitos outros sistemas dependentes fortemente acoplados são sensíveis e fazem com que a mudança seja extremamente difícil. Isso não significa que não estão sendo desenvolvidos grandes sistemas, significa que esses sistemas são fracamente acoplados como serviços que se comunicam através de um protocolo simples.\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\n\u003Ch3\u003E\u003Cspan style=\"font-size: 1.17em\"\u003EResponsabilidades centralizadas\u003C\u002Fspan\u003E\u003C\u002Fh3\u003E\n\u003Cp\u003EEm virtude de todas as equipes de serviço serem pequenas (no máximo 10 pessoas) e independentes, pode-se imaginar quais funções organizacionais são centralizadas. Embora cada organização seja diferente, com equipes que utilizam o DevOps e os princípios de entrega contínua, as funções centralizadas são aquelas desenvolvem os serviços de plataforma usados pelo restante da equipe de entrega de software ou aquelas que realizam o monitoramento do sistema (aplicativo, rede, segurança, etc.). Pode haver coordenadores de release, governança e gerenciamento também, mas nenhuma dessas equipes centralizadas deve realizar atividades que somem ao tempo de espera das equipes multidisciplinares (em outras palavras, os serviços que as equipes centralizadas fornecem são completamente de autoatendimento). Frequentemente, nessas organizações, as equipes de entrega de serviço (de programadores, operações, banco de dados, testadores, etc.) estão de plantão (normalmente isso alterna entre os membros da equipe) e são responsáveis por corrigir problemas de produção.\u003C\u002Fp\u003E\n\u003Ch3\u003ESistemas de autoatendimento\u003C\u002Fh3\u003E\n\u003Cp\u003EUma das principais características do DevOps é que um membro da equipe \u003Cem\u003Enunca\u003C\u002Fem\u003E deve precisar de outro membro fora de sua equipe multidisciplinar para executar uma atividade como parte do processo de entrega. \u003Cem\u003ETudo \u003C\u002Fem\u003Edeve ser nos moles de autoatendimento. Qualquer membro da equipe deve poder entregar software para a produção (consulte a barra lateral “\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Flibrary\u002Fa-devops9\u002Findex.html#youbuild\"\u003EVocê desenvolve, você executa!\u003C\u002Fa\u003E “). Quando os membros da equipe estão projetando qualquer recurso em um sistema de entrega de software, eles precisam considerar como desenvolver isso de forma que possa ser usado sem os tempos de espera de pipeline de entrega envolvendo o envio de chamados, envio de email ou o uso de quaisquer outros mecanismos de comunicação. (Essas ferramentas frequentemente ainda são usadas com equipes que adotam o DevOps e a Entrega Contínua. Mas no contexto do pipeline de entrega, elas são automatizadas.)\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cp\u003E\u003Cstrong\u003EVocê desenvolve, você executa!\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EQuando os sistemas de entrega de software são desenvolvidos de forma que apenas as mudanças automatizadas executam a entrega do software, qualquer pessoa na equipe (de no máximo de 8 a 10 membros) pode implementar as mudanças na produção (ou em qualquer outro ambiente). Como um desenvolvedor (ou código de infraestrutura, código do aplicativo, scripts de analista ou qualquer outra coisa) o cliente final é o usuário real—não uma equipe de operações tradicional—o que encoraja loops de feedback muito rápidos.\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\n\u003Ch3\u003E\u003Cspan style=\"font-size: 1.17em\"\u003EPadrões\u003C\u002Fspan\u003E\u003C\u002Fh3\u003E\n\u003Cp\u003ECom o princípio universal sendo mover todos os serviços internos para os modelos de \u003Cem\u003Eautoatendimento\u003C\u002Fem\u003E , determinados padrões específicos que se aplicam são abordados de uma forma ou de outra nessa série até o momento. Os padrões mais essenciais entre eles são descritos na Tabela 1.\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003ETabela 1. Padrões principais que suportam o trabalho do DevOps \u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Ctable summary=\"Key patterns that support DevOps work\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n\u003Cth scope=\"col\"\u003EPadrão\u003C\u002Fth\u003E\n\u003Cth scope=\"col\"\u003EDescrição\u003C\u002Fth\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EGrandes painéis visíveis\u003C\u002Ftd\u003E\n\u003Ctd\u003EAs equipes em toda a organização obtêm informações em tempo real sobre o estado do sistema de software, incluindo status de desenvolvimento, métricas do cliente e disponibilidade.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EColocação\u003C\u002Ftd\u003E\n\u003Ctd\u003EAs equipes estão fisicamente próximas para aprimorar a comunicação.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EIntegração contínua\u003C\u002Ftd\u003E\n\u003Ctd\u003EO software é desenvolvido (ambientes, aplicativos, etc.) com cada mudança.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EEquipes multidisciplinares\u003C\u002Ftd\u003E\n\u003Ctd\u003EEquipes de entrega de software compostas por especialistas de várias disciplinas, incluindo programadores, testadores, analistas e operações.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EEspecialistas com várias qualificações\u003C\u002Ftd\u003E\n\u003Ctd\u003EReduz os silos de especialistas ao expandir os conjuntos de qualificações nas equipes multidisciplinares.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EImplementações com script\u003C\u002Ftd\u003E\n\u003Ctd\u003EA implementação do software nos ambientes é completamente definida por scripts para que possa ser executada com um único comando.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EAmbientes com script\u003C\u002Ftd\u003E\n\u003Ctd\u003EA criação de ambientes é completamente definida por scripts para que possa ser executada com um único comando.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EReleases de autoatendimento (“Você desenvolve, você executa.”)\u003C\u002Ftd\u003E\n\u003Ctd\u003EQualquer pessoa autorizada na equipe pode e executa implementações para a produção.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EParar a linha\u003C\u002Ftd\u003E\n\u003Ctd\u003ETodos podem e devem parar o sistema de integração contínua quando necessário.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003ETodos os itens orientados por teste\u003C\u002Ftd\u003E\n\u003Ctd\u003EEscreva testes automatizados para tudo: aplicativos, infraestrutura, tudo. Isso deve incluir escrita da unidade, a aceitação, o carregamento e os testes de desempenho.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003EIndicação de versão de todos os itens\u003C\u002Ftd\u003E\n\u003Ctd\u003EIndicação versão de todos os artefatos: infraestrutura, configuração, código do aplicativo e dados.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003C\u002Ftbody\u003E\n\u003C\u002Ftable\u003E\n\u003Cdiv\u003E\u003C\u002Fdiv\u003E\n\u003Cdiv\u003E\n\u003Ch2\u003EA morte do desenvolvimento de software do passado\u003C\u002Fh2\u003E\n\u003C\u002Fdiv\u003E\n\u003Cdiv\u003E\n\u003Cp\u003ENesse artigo, você aprendeu que um dos segredos para o DevOps ser efetivo é a quebra dos silos e a criação de equipes multidisciplinares que podem implementar seu software na produção. Organizações que têm longos ciclos de intermediação e entrega irão se desenvolver ou se retirar dos negócios. Em grandes organizações, o desenvolvimento pode ser demorado e requer uma mudança na cultura organizacional.\u003C\u002Fp\u003E\n\u003Cp\u003ENo artigo final dessa \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fviews\u002Fagile\u002Flibraryview.jsp?series_title_by=agile+devops\"\u003Esérie \u003C\u002Fa\u003E, você aprenderá como criar um painel do DevOps—uma visualização abrangente do estado do sistema de software para as equipes de desenvolvimento e operações monitorarem em tempo real.\u003C\u002Fp\u003E\n\u003Ch2\u003ERecursos\u003C\u002Fh2\u003E\n\u003C\u002Fdiv\u003E\n\u003Cp\u003E \u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EAprender\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E \u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E“\u003Ca href=\"http:\u002F\u002Fperfcap.blogspot.com\u002F2011\u002F12\u002Fhow-netflix-gets-out-of-way-of.html\"\u003EHow Netflix gets out of the way of innovation\u003C\u002Fa\u003E” (Adrian Cockcroft’s Blog, dezembro de 2011): Cockcroft discute como a cultura da Netflix afeta a inovação.\u003C\u002Fli\u003E\n\u003Cli\u003E“\u003Ca href=\"http:\u002F\u002Fcontinuousdelivery.com\u002F2012\u002F10\u002Ftheres-no-such-thing-as-a-devops-team\u002F\"\u003EThere’s No Such Thing as a ‘Devops Team’\u003C\u002Fa\u003E” (Jez Humble, continuousdelivery.com, outubro de 2012): Humble explica porque os silos funcionais e a segregação de funções são problemáticos.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAndon_%28manufacturing%29\"\u003EAndon\u003C\u002Fa\u003E: Saiba como um cabo andon é usado na manufatura lean. As equipes de software podem aplicar o mesmo conceito em “parar a linha”.\u003C\u002Fli\u003E\n\u003Cli\u003E“\u003Ca href=\"http:\u002F\u002Frefcardz.dzone.com\u002Frefcardz\u002Fcontinuous-delivery-patterns\"\u003EContinuous Delivery: Patterns and Antipatterns in the Software Lifecycle\u003C\u002Fa\u003E” (Paul Duvall, DZone, junho de 2011): Conheça mais de 40 padrões e antipadrões para a entrega contínua.\u003C\u002Fli\u003E\n\u003Cli\u003E“\u003Ca href=\"http:\u002F\u002Fthenextweb.com\u002Finsider\u002F2011\u002F10\u002F05\u002Famazons-cto-amazon-is-a-technology-company-we-just-happen-to-do-retail\u002F\"\u003EAmazon’s CTO: ‘Amazon is a technology company. We just happen to do retail’\u003C\u002Fa\u003E“: (Brad McCarty, The Next Web, outubro de 2011): Em um vídeo de apresentação integrado nesse artigo, o CTO da Amazon, Werner Vogels, discute a abordagem dos sistemas de software “Você desenvolve, você executa” de sua empresa.\u003C\u002Fli\u003E\n\u003Cli\u003EFique por dentro dos \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Foffers\u002Ftechbriefings\u002Fevents.html\"\u003EdeveloperWorks\u003C\u002Fa\u003E com ênfase em uma série de produtos IBM e tópicos do segmento de mercado de TI.\u003C\u002Fli\u003E\n\u003Cli\u003EParticipe de um \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Foffers\u002Ftechbriefings\u002F\"\u003Ebriefing ao vivo e gratuito do developerWorks Live!\u003C\u002Fa\u003E para se atualizar rapidamente sobre produtos e ferramentas IBM e tendências do segmento de mercado de TI.\u003C\u002Fli\u003E\n\u003Cli\u003ESiga o \u003Ca href=\"http:\u002F\u002Fwww.twitter.com\u002Fdeveloperworks\u002F\"\u003EO developerWorks no Twitter\u003C\u002Fa\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003EAcompanhe as \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Foffers\u002Flp\u002Fdemos\u002F\"\u003EDemos on demand do developerWorks\u003C\u002Fa\u003E que abrangem desde demos de instalação e configuração de produtos para iniciantes até funcionalidades avançadas para desenvolvedores experientes.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E \u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EObter produtos e tecnologias\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E \u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fdownloads\u002F\"\u003EAvalie os produtos IBM\u003C\u002Fa\u003E da maneira que for melhor para você: faça download da versão de teste de um produto, avalie um produto on-line, use-o em um ambiente de nuvem ou passe algumas horas na \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fdownloads\u002Fsoasandbox\u002Findex.html\"\u003ESandbox SOA\u003C\u002Fa\u003E aprendendo a implementar Arquitetura Orientada a Serviços de modo eficiente.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E \u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EDiscutir\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E \u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EParticipe da \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fcommunity\u002F\"\u003Ecomunidade do developerWorks\u003C\u002Fa\u003E. Entre em contato com outros usuários do developerWorks, enquanto explora os blogs, fóruns, grupos e wikis orientados ao desenvolvedor.\u003C\u002Fli\u003E\n\u003Cli\u003EA \u003Ca href=\"https:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fmydeveloperworks\u002Fgroups\u002Fservice\u002Fhtml\u002Fcommunityview?communityUuid=c914709e-8097-4537-92ef-8982fc416138\"\u003Ecomunidade Agile Transformation\u003C\u002Fa\u003E do developerWorks fornece notícias, discussões e treinamento para ajudar você e sua organização a desenvolverem uma base fundamentada em princípios de desenvolvimento agile.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Cem\u003E\u003Cstrong\u003ESobre o Autor\u003C\u002Fstrong\u003E\u003C\u002Fem\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cem\u003E\u003Ca href=\"http:\u002F\u002Ftwitter.com\u002Fpaulduvall\"\u003EPaul Duvall\u003C\u002Fa\u003E é CTO do \u003Ca href=\"http:\u002F\u002Fwww.stelligent.com\u002F\"\u003EStelligent\u003C\u002Fa\u003E. Palestrante presente em muitas das principais conferências de software, desempenhou praticamente todas as funções em projetos de software: desenvolvedor, gerente de projeto, arquiteto e testador. É o principal autor de \u003Ca href=\"http:\u002F\u002Famzn.to\u002Fcibook\"\u003EContinuous Integration: Improving Software Quality and Reducing Risk\u003C\u002Fa\u003E(Addison-Wesley, 2007) e \u003Ca href=\"http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FJolt_Awards#Technical_2\"\u003EVencedor do Jolt Award de 2008\u003C\u002Fa\u003E. Ele também é autor de \u003Ca href=\"http:\u002F\u002Famzn.to\u002Fstartupatcloud\"\u003EStartup@Cloud\u003C\u002Fa\u003E e \u003Ca href=\"http:\u002F\u002Fwww.informit.com\u002Fstore\u002Fproduct.aspx?isbn=0321793269\"\u003EDevOps in the Cloud LiveLessons\u003C\u002Fa\u003E (Pearson Education, junho de 2012). Ele contribuiu em diversos outros livros também. Paul é autor da série de 20 artigos \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fviews\u002Fjava\u002Flibraryview.jsp?search_by=automation+people:\"\u003EAutomation for the people\u003C\u002Fa\u003E no developerWorks. Sua paixão é oferecer software de alta qualidade para os usuários mais rápido e com maior frequência através da entrega contínua e de nuvem. Leia seu blog em \u003Ca href=\"http:\u002F\u002Fwww.stelligent.com\u002Fblog\u002F\"\u003EStelligent.com\u003C\u002Fa\u003E.\u003C\u002Fem\u003E\u003C\u002Fp\u003E\n","excerpt":"\u003Cp\u003ESaiba como equipes multidisciplinares são essenciais para DevOps bem-sucedidos\u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fagile-devops-quebrando-os-silos","date":"6 ago, 2013","thumbnail":"","externalMention":null,"author":{"id":421,"thumbnail":"https:\u002F\u002Fsecure.gravatar.com\u002Favatar\u002Fbe5bc6f39606ac453a07bd2eb7ab21af?s=96&d=mm&r=g","name":"developerWorks Brasil","description":"é o portal de tecnologia da IBM para profissionais de TI de todo o mundo. Colabore, aprenda a criar aplicativos inovadores e compreenda tecnologias avançadas. Acesse mais artigos e tutoriais em www.ibm.com\u002Fdeveloperworks\u002Fbr","slug":"developerworks_brasil","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdeveloperworks_brasil","registered":"2010-07-07 17:06:45","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002Fsoudw","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002F","mail":"dwbr@br.ibm.com"},"articles_count":217,"views_count":4709798,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"Desenvolvimento","slug":"desenvolvimento","id":7234,"link":"https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento"},{"title":"DevSecOps","slug":"devsecops","id":1,"link":"https:\u002F\u002Fimasters.com.br\u002Fdevsecops"}],"tags":[{"title":"agile","slug":"agile-2","id":358,"link":"https:\u002F\u002Fimasters.com.br\u002Fagile-2"},{"title":"agile devops","slug":"agile-devops","id":1977,"link":"https:\u002F\u002Fimasters.com.br\u002Fagile-devops"},{"title":"devops","slug":"devops","id":1925,"link":"https:\u002F\u002Fimasters.com.br\u002Fdevops"},{"title":"gerência de TI","slug":"gerencia-de-ti-2","id":221,"link":"https:\u002F\u002Fimasters.com.br\u002Fgerencia-de-ti-2"},{"title":"metodologia","slug":"metodologia","id":330,"link":"https:\u002F\u002Fimasters.com.br\u002Fmetodologia"},{"title":"metodologias","slug":"metodologias","id":1978,"link":"https:\u002F\u002Fimasters.com.br\u002Fmetodologias"}],"seo":{"open_graph":{"title":"Agile DevOps: quebrando os silos - iMasters - We are Developers","description":"Saiba como equipes multidisciplinares são essenciais para DevOps bem-sucedidos","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":false,"modified_time":"2018-05-24T01:52:47-03:00","published_time":"2013-08-06T10:00:50-03:00"},"twitter":{"title":"Agile DevOps: quebrando os silos - iMasters - We are Developers","description":"Saiba como equipes multidisciplinares são essenciais para DevOps bem-sucedidos","type":"summary_large_image","image":false}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fagile-devops-quebrando-os-silos","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fagile-devops-quebrando-os-silos","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fdesenvolvimento\u002Fagile-devops-quebrando-os-silos"},"type":"post"},{"id":45385,"title":"Mineração de dados em um mundo de documentos","content":"\u003Cp\u003EA análise preditiva, business intelligence e mineração de dados, em geral, exigem o armazenamento e processamento de estruturas de dados complexas e muitas vezes totalmente diferentes à medida que as informações são processadas, resolvidas e resumidas. É altamente provável, em especial para informações comerciais e financeiras, que uma quantidade significativa de dados venha de bancos de dados relacionais. Eles seguem uma estrutura rígida e exigem preparação significativa em termos de projeto antecipado do seu esquema e de modelos de dados. A nova geração de NoSQL e bancos de dados baseados em documento simplifica muito desse processamento porque é possível criar e fazer dump de informações em formato flexível. Além disso, você pode trabalhar em métodos para extrair os dados no formato fixo que precisar. Neste artigo, analisarei como usar bancos de dados baseados em documentos para processamento de dados e analítica como parte de sua solução geral de banco de dados.\u003C\u002Fp\u003E\n\u003Ch2\u003EArquitetura do banco de dados de documento\u003C\u002Fh2\u003E\n\u003Cp\u003EUm dos elementos-chave de todos os bancos de dados de documentos é que eles podem manipular e trabalhar com estruturas e conjuntos de dados muito maiores do que o normal. Em especial, devido à sua natureza distribuída e à maneira diferente em que armazenam dados fisicamente, eles são ideais quando houver uma grande quantidade de dados a serem processados, como frequentemente é o caso na mineração de dados.\u003C\u002Fp\u003E\n\u003Cp\u003EEsses benefícios são evidentes e documentados em outra parte. Este artigo concentra-se na estrutura e no formato das informações e nas técnicas utilizadas para processar e relatar as informações armazenadas.\u003C\u002Fp\u003E\n\u003Ch2\u003EEstrutura de dados flexível\u003C\u002Fh2\u003E\n\u003Cp\u003EBancos de dados de documentos têm uma estrutura (quase) infinitamente flexível que fornece diversas áreas-chave diferentes de funcionalidade:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Cstrong\u003ESem esquema\u003C\u002Fstrong\u003E: bancos de dados de documento não precisam predefinir a estrutura dos dados que devem ser armazenados neles. Em RDBM tradicional, especifique a estrutura das tabelas em que os dados são armazenados e tente prever o conteúdo, os valores possíveis e a estrutura das informações. Com um banco de dados de documentos, é possível armazenar informações nos documentos sem ter que se preocupar com a estrutura, se há vários campos e nem mesmo, na maioria dos casos, quais são os relacionamentos de um para muitos e de muitos para muitos. Em vez disso, é possível concentrar-se no próprio conteúdo das informações. Isso pode facilitar muito o armazenamento de matéria-prima e de informações, embora possam ser provenientes de fontes distintas. A maior flexibilidade também significa que é possível combinar e processar informações de diferentes tipos e estruturas. Por exemplo, o processamento de dados textuais é difícil de conseguir com um RDBMS tradicional, porque é preciso garantir que a estrutura (número de frases, parágrafos, etc.) seja flexível o suficiente para suportar as informações recebidas. De forma mais explícita, imagine cotejar os dados do Twitter, Facebook e outras fontes de mídia social e procurar padrões. As informações no Twitter têm um comprimento fixo, e são incluídas em uma única cadeia de caractere pequena. O Facebook não tem elementos separados para saída de informações (texto, localização e indivíduos). Seria necessária uma quantidade significativa de processamento dessas informações de forma a coletá-las, unificá-las e colocá-las em uma estrutura rígida.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Cstrong\u003EObjetos lógicos\u003C\u002Fstrong\u003E: a maioria das soluções de RDBMS é utilizada para modelar informações que normalmente estariam em um formato (relativamente) estruturado. Em seguida, SQL e junções são usados para moldar essas informações em um objeto que é usado internamente. Pode-se observar individualmente diferentes elementos da estrutura de dados global, mas com frequência as informações são combinadas e relatadas de acordo com o objeto que recolhe todos os dados.A partir de uma perspectiva mais complexa, muitas vezes fatiamos e fragmentamos os diferentes elementos de dados de maneiras diferentes, embora na realidade ainda estejamos apenas escolhendo elementos dessa estrutura geral. A estrutura do documento altera essa perspectiva. Em vez de observar pontos de dados distintos e individuais, os documentos observam os objetos como um todo. O rastreamento de informações sobre coletores de dados, por exemplo, pode exigir que todas as informações sobre esse objeto estejam no lugar, embora diferentes coletores de dados possam ter diferentes sensores, números diferentes de sensores e diferentes níveis de complexidade.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Cstrong\u003EEstrutura migratória\u003C\u002Fstrong\u003E: os dados mudam ao longo do tempo, às vezes lenta e às vezes rapidamente. Modificar a estrutura de dados é um processo complexo, que não afeta apenas o banco de dados que você usa, mas também exige mudanças nos aplicativos que acessam e usam essas informações. Com uma estrutura baseada em documento, visto que a estrutura dos dados é fixa, a adaptação dessa estrutura a novas versões e formatos diferentes dos dados originais é difícil e complexa. É preciso criar uma tabela ou modificar a tabela existente para lidar com a nova estrutura, o que significa a conversão de todos os registros criados anteriormente para corresponderem à nova estrutura. Com um banco de dados de documento, a estrutura dos documentos pode ser modificada. De fato, as estruturas dos documentos individuais podem ser diferentes de um para o outro. Visto que você está sempre lidando com documentos inteiros, é improvável que seu aplicativo precise lidar com mudanças até precisar processar os novos dados.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003EEm vista disso tudo, o que significa na prática coletar, extrair e processar essas informações?\u003C\u002Fp\u003E\n\u003Cp\u003EA primeira coisa a levar em conta é o formato dos próprios dados. Bancos de dados de documentos podem armazenar qualquer informação, mas o formato estrutural mais utilizado é JSON, um formato de notação de objeto da linguagem JavaScript. Ele permite armazenar cadeias de caractere, números, arrays e dados (hash) de registro, e as combinações desses tipos básicos.\u003C\u002Fp\u003E\n\u003Cp\u003EPara fins de compreensão das noções básicas de processamento de documentos, este artigo utiliza dados bastante simples. Listagem 1 é um documento que rastreia o nível de água e a temperatura de um tanque de água externo:\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 1. Documento que rastreia o nível de água e a temperatura de um tanque de água externo\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cpre\u003E{\r\n  "datestring": "Tue Nov 30 01:40:30 2010",\r\n  "hour": 1,\r\n  "min": 40,\r\n  "waterlevel": 96,\r\n  "day": 30,\r\n  "mon": 11,\r\n  "year": 2010,\r\n  "temperature": "28.64"\r\n}\u003C\u002Fpre\u003E\n\u003Cp\u003EOs componentes de data individuais foram armazenados para obter flexibilidade, embora sejam inteiramente opcionais. O nível de água e a temperatura são armazenados como valores brutos.\u003C\u002Fp\u003E\n\u003Cp\u003EUm criador de logs diferente rastreia a temperatura de um tanque de água em três pontos e representa seus dados como um hash dos diferentes valores (consulte a Listagem 2):\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 2. Documento que rastreia a temperatura do tanque em três pontos\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cpre\u003E{\r\n  "datestring": "Tue Nov 30 02:06:21 2010",\r\n  "temperature": {\r\n    "mid": 23.2148953489378,\r\n    "top": 23.6984348277329,\r\n    "bot": 23.0212211444848\r\n  }\r\n}\u003C\u002Fpre\u003E\n\u003Cp\u003E\u003Ciframe width=\"500\" height=\"375\" src=\"http:\u002F\u002Fwww.youtube.com\u002Fembed\u002FvzxWPtInfKk?feature=oembed\" frameborder=\"0\" allowfullscreen\u003E\u003C\u002Fiframe\u003E\u003C\u002Fp\u003E\n\u003Cp\u003ENa verdade, colocar os dados em um banco de dados de documentos, como Hadoop ou Couchbase Server, é provavelmente a parte mais fácil do processo. Em comparação, não há processamento nem construção de dados ou de estrutura para retê-los. Não precisamos analisar os dados para identificar uma estrutura; basta armazená-los em sua forma bruta.\u003C\u002Fp\u003E\n\u003Cp\u003EÉ o processamento durante a extração que torna eficiente a mineração de dados com base em documento.\u003C\u002Fp\u003E\n\u003Ch2\u003EIntercâmbio de dados\u003C\u002Fh2\u003E\n\u003Cp\u003ESe houver dados dentro de um RDBMS tradicional, como o IBM DB2, será possível usar um banco de dados de documentos para simplificar e unificar de forma mais normal diferentes dados em documentos que podem ser processados por um banco de dados de documentos para tirar proveito do formato unificador.\u003C\u002Fp\u003E\n\u003Cp\u003ETalvez você ache errado executar essa operação: se já estão em um banco de dados, por que movê-los? Mas as soluções RDBMS são usadas há anos para armazenar informações textuais e diferentes versões e revisões de dados tabulares. Um banco de dados de documentos pode ser uma forma eficaz de unificá-los em uma estrutura que pode ser usada para mapear\u002Freduzir e para outras técnicas.\u003C\u002Fp\u003E\n\u003Cp\u003EO processo mais simples é carregar seus objetos à medida que eles são formatados e estruturados dentro do banco de dados. Isso é fácil se você estiver usando um sistema ORM para modelar seus dados em um objeto. Fora disso, é possível executar o processo à mão. O script na Listagem 3 executa a operação tirando um registro de componente complexo carregado por meio de uma função que compila instruções SQL individuais para gerar um objeto interno, formatá-lo para JSON e depois gravá-lo em um banco de dados de documentos (nesse caso, o CouchDB):\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 3. Operação para carregar seus objetos\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E[perl]\u003C\u002Fp\u003E\n\u003Cp\u003Eforeach my $productid (keys %{$products})\u003Cbr \u002F\u003E\n{\u003Cbr \u002F\u003E\nmy $product = new Product($fw,$productid);\u003C\u002Fp\u003E\n\u003Cp\u003Emy $id = $product->{title};\u003Cbr \u002F\u003E\n$id =~ s\u002F[ ‘,\\(\\)]\u002F\u002Fg;\u003Cbr \u002F\u003E\nmy $record = {\u003Cbr \u002F\u003E\n_id => $id,\u003Cbr \u002F\u003E\ntitle => $product->{title},\u003Cbr \u002F\u003E\ncomponentcount => $product->{componentcount},\u003Cbr \u002F\u003E\nbuildtime => $product->{metadata_bytag}->{totalbuildtime},\u003Cbr \u002F\u003E\ntesttime => $product->{metadata_bytag}->{totaltesttime},\u003Cbr \u002F\u003E\ntotaltime => $product->{metadata_bytag}->{totaltime},\u003Cbr \u002F\u003E\nkeywords => [keys %{$product->{keywordbytext}} ],\u003Cbr \u002F\u003E\n};\u003C\u002Fp\u003E\n\u003Cp\u003Eforeach my $component (@{$product->{components}})\u003Cbr \u002F\u003E\n{\u003Cbr \u002F\u003E\npush(@{$record->{component}},\u003C\u002Fp\u003E\n\u003Cp\u003Ecomponentqty => $component->{‘qty’},\u003Cbr \u002F\u003E\ncomponent => $component->{‘componentdesc’},\u003Cbr \u002F\u003E\ncomponentcode => $component->{‘componentcode’},\u003Cbr \u002F\u003E\n}\u003Cbr \u002F\u003E\n);\u003Cbr \u002F\u003E\n}\u003C\u002Fp\u003E\n\u003Cp\u003Emy $req = HTTP::Request->new(‘POST’ => $base);\u003Cbr \u002F\u003E\n$req->header(‘Content-Type’ => ‘application\u002Fjson’);\u003Cbr \u002F\u003E\n$req->content(to_json($record));\u003C\u002Fp\u003E\n\u003Cp\u003Emy $res = $ua->request($req);\u003C\u002Fp\u003E\n\u003Cp\u003E}\u003C\u002Fp\u003E\n\u003Cp\u003E[\u002Fperl]\u003C\u002Fp\u003E\n\u003Cp\u003EPode-se usar processos similares com outras informações e bancos de dados de documentos. Em Hadoop, por exemplo, é possível criar um novo arquivo único para cada registro de produto.\u003C\u002Fp\u003E\n\u003Cp\u003EAo combinar informações de várias tabelas em um formato único para o processamento, embora não seja obrigatório usar os mesmos nomes de campo (que podem ser resolvidos no tempo de processamento), não há razão, pelo menos, para não padronizar alguns dos campos (datas, pontos de dados) se as informações forem praticamente as mesmas.\u003C\u002Fp\u003E\n\u003Cp\u003EDurante o processamento, como no código de exemplo, você talvez queira realizar também pré-processamento e formatação das informações. Por exemplo, você pode harmonizar os dados para usar os mesmos pontos de medição ou combinar os campos que foram usados de maneira diferente nos dados de origem.\u003C\u002Fp\u003E\n\u003Ch2\u003EProcessamento na extração\u003C\u002Fh2\u003E\n\u003Cp\u003ECom a estrutura do documento flexível em mente, o processamento e a identificação de padrões nessas informações são processos que acontecem ao extrair os dados, em vez de impor a extração e o processo de geração de relatórios no ponto onde os dados são colocados.\u003C\u002Fp\u003E\n\u003Cp\u003EEm um RDBMS típico, a estrutura é composta de tabelas e campos que dependem de como você deseja que as informações sejam extraídas posteriormente. Por exemplo, com as informações de criação de log, é possível associar uma tabela de ponto de criação de log (que contém a data) a uma tabela de ponto de dados que contém os dados de log específicos. Você sabe que, a partir do processo, é possível executar uma junção para conectar o ponto de criação de log com seus dados em tempo às informações de temperatura e nível de água para poder rastrear e monitorar os valores ao longo do tempo (consulte a Figura 1).\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EFigura 1. Executando uma junção\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002Fbanco-de-dados\u002Fmineracao-de-dados-em-um-mundo-de-documentos\u002Fattachment\u002Fbanco-de-dados-1\u002F\" rel=\"attachment wp-att-45426\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-45426\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F07\u002Fbanco-de-dados-1.gif\" alt=\"banco-de-dados-1\" width=\"580\" height=\"383\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EO processamento das informações é feito no ponto de entrada, separando as informações para poderem ser inseridas em tabelas e depois unificadas no ponto de saída por meio da recombinação das informações. O processo requer que você saiba como deseja que as informações sejam relatadas, juntadas e processadas na saída. É possível gravar uma instrução SQL apenas se for conhecida a estrutura da tabela.\u003C\u002Fp\u003E\n\u003Cp\u003ECom um banco de dados de documentos, é o processo dos dados brutos que cria a visualização harmonizada das informações que permite que os dados sejam processados, quer sejam dados com base de valor, quer dados temáticos e textuais. As informações são colocadas em vários documentos e o sistema de mapeamento\u002Fredução processa essas informações e gera uma tabela de estrutura a partir dos dados (consulte a Figura 2).\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EFigura 2. Gerando uma tabela estruturada a partir de dados\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002Fbanco-de-dados\u002Fmineracao-de-dados-em-um-mundo-de-documentos\u002Fattachment\u002Fbanco-de-dados-2\u002F\" rel=\"attachment wp-att-45427\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-45427\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F07\u002Fbanco-de-dados-2.gif\" alt=\"banco-de-dados-2\" width=\"580\" height=\"278\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003ECom o banco de dados de documentos, processe as informações depois de elas terem sido inseridas. Isso significa que é possível processar e até mesmo alterar a forma como os dados são extraídos enquanto ainda estiverem sendo usados e processados os dados brutos em seu formato original. Todo o tempo, você tem total flexibilidade sobre como as informações devem ser relatadas, sem perder nenhuma informação contextual.\u003C\u002Fp\u003E\n\u003Cp\u003ESeguir esse método, é claro, exige algumas diferenças para a maneira em que você processa os dados brutos.\u003C\u002Fp\u003E\n\u003Ch2\u003EUsando Mapear\u002FReduzir\u003C\u002Fh2\u003E\n\u003Cp\u003EExistem muitos sistemas diferentes para o processamento de Big Data, para produzir e pegar informações e processá-las para analítica de dados, especialmente com bancos de dados de documentos. As soluções variam em sua abordagem, de mecanismos de consulta simples, semelhantes aos disponíveis em um banco de dados SQL, a análise e entendimento mais complexos baseados em programa. A última solução é frequentemente usada em situações em que é precisa modelar e entender os dados subjacentes para que seu sistema de processamento possa desenvolver o entendimento das informações essenciais em um formato adequado para seu processamento e resumo.\u003C\u002Fp\u003E\n\u003Cp\u003ESem dúvida, a mais comum dessas técnicas é Mapear\u002FReduzir. Ela tem duas etapas: mapear para extrair as informações e a função de reduzir para simplificar e resumir os dados.\u003C\u002Fp\u003E\n\u003Cp\u003EO papel da função de mapear é levar as informações de entrada, os documentos armazenados, e simplificá-los em um formato que forneça uma saída harmonizada e adequada para análise. Por exemplo, utilizando os dados de log anteriores, pode-se obter os dados de temperatura individuais e os dados de temperatura de diversos pontos e enviar essas informações como um único ponto de dados, com base na informação da data e na temperatura, como mostrado na Listagem 4:\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 4. Saída de dados de temperatura individuais e dados de temperatura de diversos pontos como um único ponto de dados\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E[perl]\u003C\u002Fp\u003E\n\u003Cp\u003Efunction (doc, meta) {\u003Cbr \u002F\u003E\nif (doc.temperature && doc.temperature[“mid”]) {\u003Cbr \u002F\u003E\nemit(doc.datestring, parseFloat(doc.temperature[“mid”]));\u003Cbr \u002F\u003E\nemit(doc.datestring, parseFloat(doc.temperature[“top”]));\u003Cbr \u002F\u003E\nemit(doc.datestring, parseFloat(doc.temperature[“bot”]));\u003C\u002Fp\u003E\n\u003Cp\u003E} else\u003Cbr \u002F\u003E\n{\u003Cbr \u002F\u003E\nemit(doc.datestring, parseFloat(doc.temperature));\u003Cbr \u002F\u003E\n}\u003Cbr \u002F\u003E\n}\u003C\u002Fp\u003E\n\u003Cp\u003E[\u002Fperl]\u003C\u002Fp\u003E\n\u003Cp\u003EO mapa mostrado na Listagem 4 é escrito em JavaScript e projetado para uso dentro do Couchbase Server, embora funcione no CouchDB, mas os princípios básicos também funcionam no Hadoop. A chamada de emissão gera uma ‘linha’ de informações, nesse caso uma chave e um valor. É possível ver uma amostra da saída de dados brutos na Listagem 5):\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 5. Saída de dados brutos\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cpre\u003E{"total_rows":404,"rows":[\r\n{"id":"1334307543","key":"Fri Apr 13 09:59:03 2012","value":22.6132600653245},\r\n{"id":"1334307543","key":"Fri Apr 13 09:59:03 2012","value":25.903221768301},\r\n{"id":"1334307543","key":"Fri Apr 13 09:59:03 2012","value":29.0646016268462},\r\n{"id":"1322793686","key":"Fri Dec  2 02:41:26 2011","value":22.7931975564504},\r\n{"id":"1322793686","key":"Fri Dec  2 02:41:26 2011","value":23.8901498654126},\r\n{"id":"1322793686","key":"Fri Dec  2 02:41:26 2011","value":23.9022843956552},\r\n{"id":"1292554769","key":"Fri Dec 17 02:59:29 2010","value":26.55},\r\n{"id":"1324617141","key":"Fri Dec 23 05:12:21 2011","value":24.43},\r\n{"id":"1296843676","key":"Fri Feb  4 18:21:16 2011","value":23.75},\r\n{"id":"1297446912","key":"Fri Feb 11 17:55:12 2011","value":24.56}\r\n]\r\n}\u003C\u002Fpre\u003E\n\u003Cp\u003EO ID na saída mostrada na Listagem 5 é o documento que gera a linha (a partir da chamada emit()). Nesse caso, é possível ver que o primeiro e o segundo registros vêm de documentos com vários sensores de temperatura porque os IDs são idênticos.\u003C\u002Fp\u003E\n\u003Cp\u003EO ponto crítico em mineração de dados com o Mapear\u002FReduzir é garantir que sejam coletadas as informações e os campos de dados corretos para desenvolver as informações desejadas. Dentro de Mapear\u002FReduzir, o formato do mapa é crítico. Providencie a saída de uma chave e do valor associado. O valor é obtido durante a fase de redução e chegará à gravação efetiva dessas informações em alguns momentos. Mas escolher o valor correto é crítico. Ao processar texto, o valor pode ser a análise temática da cadeia de caractere ou sentença que está sendo examinada. Ao analisar dados complexos, é possível optar por combinar vários pontos de dados, por exemplo, informações de vendas de mineração, em que se pode escolher a combinação de usuário exclusivo, produto e localização.\u003C\u002Fp\u003E\n\u003Cp\u003EA chave é importante durante a mineração de dados porque fornece a base para o modo como as informações são comparadas. No exemplo mostrado na Listagem 5, escolhi a data como um todo, mas é possível criar estruturas mais complexas para permitir seleções mais complicadas. Por exemplo, se uma data for dividida em partes (ano, mês, dia, hora, minuto), é possível agrupar as informações de acordo com regras diferentes.\u003C\u002Fp\u003E\n\u003Cp\u003EA Listagem 6 mostra uma versão modificada do mapa que \u003Cem\u003Eexplode\u003C\u002Fem\u003E a data em partes individuais:\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 6. Mapa modificado que explode a data em partes individuais\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E[perl]\u003C\u002Fp\u003E\n\u003Cp\u003Efunction (doc, meta) {\u003Cbr \u002F\u003E\nif (doc.temperature && doc.temperature[“mid”]) {\u003Cbr \u002F\u003E\nemit(dateToArray(doc.datestring), parseFloat(doc.temperature[“mid”]));\u003Cbr \u002F\u003E\nemit(dateToArray(doc.datestring), parseFloat(doc.temperature[“top”]));\u003Cbr \u002F\u003E\nemit(dateToArray(doc.datestring), parseFloat(doc.temperature[“bot”]));\u003C\u002Fp\u003E\n\u003Cp\u003E} else\u003Cbr \u002F\u003E\n{\u003Cbr \u002F\u003E\nemit(dateToArray(doc.datestring), parseFloat(doc.temperature));\u003Cbr \u002F\u003E\n}\u003Cbr \u002F\u003E\n}\u003C\u002Fp\u003E\n\u003Cp\u003E[\u002Fperl]\u003C\u002Fp\u003E\n\u003Cp\u003EIsso gera saída de mapa ligeiramente modificada com a data como array (consulte a Listagem 7):\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 7. Saída de mapa modificada com dados como array\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cpre\u003E{"total_rows":404,"rows":[\r\n{"id":"1291323688","key":[2010,12,2,21,1,28],"value":23.17},\r\n{"id":"1292554769","key":[2010,12,17,2,59,29],"value":26.55},\r\n{"id":"1292896140","key":[2010,12,21,1,49,0],"value":25.79},\r\n{"id":"1293062859","key":[2010,12,23,0,7,39],"value":23.5796487295866},\r\n{"id":"1293062859","key":[2010,12,23,0,7,39],"value":26.7156670181177},\r\n{"id":"1293062859","key":[2010,12,23,0,7,39],"value":29.982973219635},\r\n{"id":"1293403599","key":[2010,12,26,22,46,39],"value":22.2949007587861},\r\n{"id":"1293403599","key":[2010,12,26,22,46,39],"value":24.1374973576972},\r\n{"id":"1293403599","key":[2010,12,26,22,46,39],"value":27.4711695088274},\r\n{"id":"1293417481","key":[2010,12,27,2,38,1],"value":25.8482292176647}\r\n]\r\n}\u003C\u002Fpre\u003E\n\u003Cp\u003EAgora é possível combinar isso com uma função de reduzir para fornecer dados de resumo em diferentes intervalos. A função de redução pega a saída da função \u003Cem\u003Emap ()\u003C\u002Fem\u003E e resume essas informações de acordo com a estrutura de chave selecionada, até um formato mais simples. Os exemplos comuns são somas, médias ou contagens. A Listagem 8 fornece um exemplo de função de reduzir que calcula a média:\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 8. Função de reduzir que calcula a média\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E[perl]\u003C\u002Fp\u003E\n\u003Cp\u003Efunction(keys, values, rereduce) {\u003Cbr \u002F\u003E\nif (!rereduce){\u003Cbr \u002F\u003E\nvar length = values.length\u003Cbr \u002F\u003E\nreturn [sum(values) \u002F length, length]\u003Cbr \u002F\u003E\n} else {\u003Cbr \u002F\u003E\nvar length = sum(values.map(function(v){return v[1]}))\u003Cbr \u002F\u003E\nvar avg = sum(values.map(function(v){\u003Cbr \u002F\u003E\nreturn v[0] * (v[1] \u002F length)\u003Cbr \u002F\u003E\n}))\u003Cbr \u002F\u003E\nreturn [avg, length]\u003Cbr \u002F\u003E\n}\u003Cbr \u002F\u003E\n}\u003C\u002Fp\u003E\n\u003Cp\u003E[\u002Fperl]\u003C\u002Fp\u003E\n\u003Cp\u003EDevido à natureza do sistema de redução, é preciso lidar com a média original (calculada a partir da saída da função \u003Cem\u003Emap ()\u003C\u002Fem\u003E) e uma nova redução (na qual a saída de redução do primeiro nível é combinada com outras para a redução final em determinado intervalo de entrada).\u003C\u002Fp\u003E\n\u003Cp\u003EA maior parte da função calcula a média dos dados de entrada (um array de valores da função \u003Cem\u003Emap ()\u003C\u002Fem\u003E) e depois calcula a média dividindo a soma total pela contagem.\u003C\u002Fp\u003E\n\u003Cp\u003EQuando acessado pela primeira vez, o conjunto de dados é agrupado e processado, resultando na média de todos os dados armazenados (consulte a Listagem 9):\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 9. O conjunto de dados é agrupado e processado, resultando na média de todos os dados armazenados\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cpre\u003E{"rows":[\r\n{"key":null,"value":[26.251700506838258,400100]}\r\n]\r\n}\u003C\u002Fpre\u003E\n\u003Cp\u003EDurante a saída das informações de data como array, é possível usar os componentes do array como critérios de seleção para os dados gerados. Por exemplo, se for especificado um nível de grupo de um, as informações serão agrupadas pelo primeiro elemento do array, ou seja, o ano (consulte a Listagem 10):\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 10. Agrupamento das informações pelo primeiro elemento do array \u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cpre\u003E{"rows":[\r\n{"key":[2010],"value":[26.225817751696518,17484]},\r\n{"key":[2011],"value":[26.252118781247404,199912]},\r\n{"key":[2012],"value":[26.253719707387862,182704]}\r\n]\r\n}\u003C\u002Fpre\u003E\n\u003Cp\u003ESe for especificado um nível de grupo de 3, será possível obter as informações resumidas nas combinações individuais de ano\u002Fmês\u002Fdia (consulte a Listagem 11):\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 11. Resumindo as informações em combinações individuais de ano\u002Fmês\u002Fdia\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cpre\u003E{"rows":[\r\n{"key":[2010,11,30],"value":[26.23524809151833,505]},\r\n{"key":[2010,12,1],"value":[26.37107941210551,548]},\r\n{"key":[2010,12,2],"value":[26.329862140504616,547]},\r\n{"key":[2010,12,3],"value":[26.31599258504074,548]},\r\n{"key":[2010,12,4],"value":[26.389849136337002,548]},\r\n{"key":[2010,12,5],"value":[26.175710823088224,548]},\r\n{"key":[2010,12,6],"value":[26.21352234443162,548]},\r\n{"key":[2010,12,7],"value":[26.10277260171637,548]},\r\n{"key":[2010,12,8],"value":[26.31207700104686,548]},\r\n{"key":[2010,12,9],"value":[26.207143469079593,548]}\r\n]\r\n}\u003C\u002Fpre\u003E\n\u003Cp\u003EÉ possível usar as funções de redução de resumir e identificar uma variedade de informações. Pode-se combinar uma função \u003Cem\u003Ereduce()\u003C\u002Fem\u003E mais complexa com uma representação de texto da temperatura entre diferentes níveis de valor (aviso, erro e fatal) e mesclá-las em uma única estrutura (consulte a Listagem 12):\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 12. Combinando uma função de redução mais complexa com uma representação de texto em uma única estrutura\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E[perl]\u003C\u002Fp\u003E\n\u003Cp\u003Efunction(key, values, rereduce)\u003Cbr \u002F\u003E\n{   var response = {“warning” : 0, “error”: 0, “fatal” : 0 };\u003Cbr \u002F\u003E\nfor(i=0; i<data.length; i++)\u003Cbr \u002F\u003E\n{\u003Cbr \u002F\u003E\nif (rereduce)\u003Cbr \u002F\u003E\n{\u003Cbr \u002F\u003E\nresponse.warning = response.warning + values[i].warning;\u003Cbr \u002F\u003E\nresponse.error = response.error + values[i].error;\u003Cbr \u002F\u003E\nresponse.fatal = response.fatal + values[i].fatal;\u003Cbr \u002F\u003E\n}\u003Cbr \u002F\u003E\nelse\u003Cbr \u002F\u003E\n{\u003Cbr \u002F\u003E\nif (values[i] == “warning”)\u003Cbr \u002F\u003E\n{\u003Cbr \u002F\u003E\nresponse.warning++;\u003Cbr \u002F\u003E\n}\u003Cbr \u002F\u003E\nif (values[i] == “error” )\u003Cbr \u002F\u003E\n{\u003Cbr \u002F\u003E\nresponse.error++;\u003Cbr \u002F\u003E\n}\u003Cbr \u002F\u003E\nif (values[i] == “fatal” )\u003Cbr \u002F\u003E\n{\u003Cbr \u002F\u003E\nresponse.fatal++;\u003Cbr \u002F\u003E\n}\u003Cbr \u002F\u003E\n}\u003Cbr \u002F\u003E\n}\u003Cbr \u002F\u003E\nreturn response;\u003Cbr \u002F\u003E\n}\u003C\u002Fp\u003E\n\u003Cp\u003E[\u002Fperl]\u003C\u002Fp\u003E\n\u003Cp\u003EAgora você pode relatar as contagens de instâncias individuais desses erros em qualquer combinação de intervalo de data\u002Fhora, por exemplo, por mês (consulte a Listagem 13):\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EListagem 13. Instâncias individuais de erros contadas por mês\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cpre\u003E{"rows":[\r\n{"key":[2010,7], "value":{"warning":4,"error":2,"fatal":0}},\r\n{"key":[2010,8], "value":{"warning":4,"error":3,"fatal":0}},\r\n{"key":[2010,9], "value":{"warning":4,"error":6,"fatal":0}},\r\n{"key":[2010,10],"value":{"warning":7,"error":6,"fatal":0}},\r\n{"key":[2010,11],"value":{"warning":5,"error":8,"fatal":0}},\r\n{"key":[2010,12],"value":{"warning":2,"error":2,"fatal":0}},\r\n{"key":[2011,1], "value":{"warning":5,"error":1,"fatal":0}},\r\n{"key":[2011,2], "value":{"warning":3,"error":5,"fatal":0}},\r\n{"key":[2011,3], "value":{"warning":4,"error":4,"fatal":0}},\r\n{"key":[2011,4], "value":{"warning":3,"error":6,"fatal":0}} \r\n]\r\n}\u003C\u002Fpre\u003E\n\u003Cp\u003EEsses são exemplos simplistas projetados para demonstrar o poder e a flexibilidade de mapear\u002Freduzir, mas é fácil ver como lidar com diferentes formatos de documentos e estruturas em suas informações de fonte e também a forma de resumir e extrair informações durante o processo.\u003C\u002Fp\u003E\n\u003Ch2\u003EEncadeamento de mapear\u002Freduzir\u003C\u002Fh2\u003E\n\u003Cp\u003EComo já vimos, Mapear\u002FReduzir é um método prático para análise e processamento de grandes quantidades de dados, quer suas informações e dados de fonte sejam armazenados para começar em um banco de dados adequado, quer não.\u003C\u002Fp\u003E\n\u003Cp\u003EDentro de Mapear\u002FReduzir, porém, existem limitações na quantidade de informações ligadas (implícita ou explicitamente) em diferentes documentos que podem ser combinados e relatados juntos. Da mesma forma, para informações muito complexas, um único processo de Mapear\u002FReduzir pode ser incapaz de manipular o processo na única análise da combinação de Mapear\u002FReduzir.\u003C\u002Fp\u003E\n\u003Cp\u003EEm especial quando comparado com RDBMS tradicional de todos os tipos, a incapacidade de utilizar uma junção para combinar as informações entre vários pontos (incluindo a mesma tabela) torna certas operações na estrutura de Mapear\u002FReduzir impossíveis de alcançar em uma única etapa.\u003C\u002Fp\u003E\n\u003Cp\u003EPor exemplo, ao processar informações textuais e realizar uma análise temática dos dados, você talvez passe por um processo antes de processar as informações e as sentenças a partir de matéria bruta e dividir os dados de origem brutos em blocos de documentos individuais. Isso pode ser conseguido por meio de um simples map() que processa as informações em novos documentos.\u003C\u002Fp\u003E\n\u003Cp\u003EUma etapa secundária poderia, então, processar as informações extraídas para fornecer uma análise mais detalhada dos fragmentos individuais e comparar e contar essas informações (consulte a Figura 3):\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EFigura 3. Processando as informações extraídas para fornecer uma análise mais detalhada\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002Fbanco-de-dados\u002Fmineracao-de-dados-em-um-mundo-de-documentos\u002Fattachment\u002Fbanco-de-dados-3\u002F\" rel=\"attachment wp-att-45428\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-45428\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F07\u002Fbanco-de-dados-3.gif\" alt=\"banco-de-dados-3\" width=\"580\" height=\"294\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EDe uma perspectiva prática, o encadeamento de Mapear\u002FReduzir envolve a execução de uma função de Mapear\u002FReduzir para uma análise de primeiro nível e usar a chave da saída (da sua função map()) como ID do documento para, em seguida, manter a estrutura de dados que saiu dessa linha reduzida.\u003C\u002Fp\u003E\n\u003Cp\u003ENo exemplo de criação de log anterior, você poderia ter usado estrutura combinada de aviso\u002Ferro\u002Ffatal, escrito essa estrutura como novos dados em um novo banco de dados (ou bucket, usado no Couchbase) e, em seguida, executado processamento adicional daquele bucket para identificar tendências ou outros dados (consulte a Figura 4):\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EFigure 4. Executando processamento adicional para identificar as tendências ou outros dados\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002Fbanco-de-dados\u002Fmineracao-de-dados-em-um-mundo-de-documentos\u002Fattachment\u002Fbanco-de-dados-4\u002F\" rel=\"attachment wp-att-45429\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-45429\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F07\u002Fbanco-de-dados-4.gif\" alt=\"banco-de-dados-4\" width=\"580\" height=\"437\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003ELembre-se de que Mapear\u002FReduzir direto é apenas um elemento dos dados. Se forem exportadas e combinadas informações de outras fontes durante o processamento, também será possível usar e combinar essas informações nesse estágio no fluxo de dados.\u003C\u002Fp\u003E\n\u003Cp\u003EPor exemplo, ao observar as informações de vendas, você pode ter informações sobre o cliente em um banco de dados, as vendas do cliente em outro e informações sobre o produto em outro. Ao executar Mapear\u002FReduzir nos dados de vendas, exportando-os para outro banco de dados, combinando-os com os dados do produto e, em seguida, reduzindo novamente antes de combinar com as informações do cliente, é possível gerar dados complexos em fontes aparentemente díspares.\u003C\u002Fp\u003E\n\u003Ch2\u003EConclusão\u003C\u002Fh2\u003E\n\u003Cp\u003EBancos de dados de documentos invertem completamente a estrutura normal de dados e as regras de processamento em sua cabeça. Já não é possível analisar, construir e formatar as informações em um formato tabular para facilitar o processamento. Em vez disso, os dados são armazenados em qualquer formato em que são recebidos e, em seguida, é feito o processamento que os analisa, manipulando os diferentes formatos e estruturas durante o processo. Esse processo pode simplificar grandes quantidades de dados até pedaços menores com muita facilidade. O processo de backend que permite bancos de dados muito grandes e distribuídos normalmente melhora, em vez de dificultar, o processo. É possível processar dados muito maiores e mais complexos usando a arquitetura de diversos nós. Como este artigo demonstrou, sua principal preocupação é construir um documento adequado e escrever a combinação correta e Mapear\u002FReduzir para processar os dados de forma eficaz.\u003C\u002Fp\u003E\n\u003Ch2\u003ERecursos\u003C\u002Fh2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAprender\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E“\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fopensource\u002Flibrary\u002Fba-ind-PMML1\u002Findex.html\"\u003EO que é PMML?\u003C\u002Fa\u003E” (Alex Guazzelli, developerWorks, setembro de 2010): leia este artigo sobre o padrão PMML usado por empresas de analítica para representar e mover soluções preditivas entre sistemas.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPredictive_analytics\"\u003EAnalítica Preditiva\u003C\u002Fa\u003E: Leia a página da Wikipédia sobre analítica preditiva para obter uma visão geral de aplicações e técnicas comuns usadas para fazer previsões sobre o futuro.\u003C\u002Fli\u003E\n\u003Cli\u003ELeia o livro \u003Ca href=\"http:\u002F\u002Fwww.amazon.com\u002Fgp\u002Fproduct\u002F1452858268\u002Fref=s9_simh_gw_p14_i1?pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-2&pf_rd_r=08SKWRZP2ZRDENEWRSX5&pf_rd_t=101&pf_rd_p=470938631&pf_rd_i=507846\"\u003E\u003Cem\u003EPMML in Action: Unleashing the Power of Open Standards for Data Mining and Predictive Analytics\u003C\u002Fem\u003E\u003C\u002Fa\u003E (maio de 2010).\u003C\u002Fli\u003E\n\u003Cli\u003EA opção \u003Ca href=\"http:\u002F\u002Fwww.dmg.org\u002F\"\u003EData Mining Group (DMG)\u003C\u002Fa\u003E é um consórcio independente liderado por fornecedores que desenvolve padrões de mineração de dados, como a Predictive Model Markup Language (PMML).\u003C\u002Fli\u003E\n\u003Cli\u003EVisite a seção \u003Ca href=\"http:\u002F\u002Fwww.zementis.com\u002Fpmml.htm\"\u003EPáginas de recursos de PMML da Zementis\u003C\u002Fa\u003E para explorar PMML completos.\u003C\u002Fli\u003E\n\u003Cli\u003EVisite a seção \u003Ca href=\"http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FData_Mining\"\u003Epágina de Mineração de Dados\u003C\u002Fa\u003E na Wikipédia.\u003C\u002Fli\u003E\n\u003Cli\u003EFaça parte das \u003Ca href=\"http:\u002F\u002Fwww.linkedin.com\u002FgroupRegistration?gid=2328634\"\u003Egrupo de discussão do PMML\u003C\u002Fa\u003E no LinkedIn.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fopensource\"\u003EZona de software livre do developerWorks\u003C\u002Fa\u003E: encontre informações práticas, ferramentas e atualizações de projeto amplas para ajudá-lo a desenvolver com tecnologias de software livre e utilizá-las com produtos IBM.\u003C\u002Fli\u003E\n\u003Cli\u003EPara ouvir entrevistas e discussões interessantes para desenvolvedores de software, confira os \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fpodcast\u002F?S_TACT=105AGY79&S_CMP=ART\"\u003EPodcasts do developerWorks\u003C\u002Fa\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Foffers\u002Ftechbriefings\u002F?S_TACT=105AGY79&S_CMP=art\"\u003EdeveloperWorks\u003C\u002Fa\u003E: Permaneça atualizado com os webcasts e eventos técnicos do developerWorks.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Cstrong\u003EObter produtos e tecnologias\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww-01.ibm.com\u002Fsoftware\u002Febusiness\u002Fjstart\u002Fhadoop\u002F\"\u003EHadoop\u003C\u002Fa\u003E suporta parte da estrutura NoSQL, como o formato sem esquema e a capacidade de usar Mapear\u002FReduzir para processar os dados armazenados.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww-01.ibm.com\u002Fsoftware\u002Fdata\u002Finfosphere\u002Fwarehouse\u002Fmining.html\"\u003EInfoSphere Warehouse\u003C\u002Fa\u003E é um conjunto de ferramentas completo para desenvolver e analisar dados que suporta muitas das técnicas de mineração de dados.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.cs.waikato.ac.nz\u002Fml\u002Fweka\u002F\"\u003EWEKA\u003C\u002Fa\u003E é um kit de ferramentas baseado em Java que suporta uma série de diferentes algoritmos de mineração de dados e estatística.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww-01.ibm.com\u002Fsoftware\u002Fanalytics\u002Fspss\u002F\"\u003ESPSS\u003C\u002Fa\u003E é um pacote estatístico que inclui recursos eficientes de análise preditiva.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.couchbase.com\"\u003ECouchbase Server\u003C\u002Fa\u003E é um banco de dados NoSQL de documentos com consulta e indexação baseadas em Mapear\u002FReduzir\u003C\u002Fli\u003E\n\u003Cli\u003EInove seu próximo projeto de desenvolvimento de software livre com \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fdownloads\u002F\"\u003Eo software de teste IBM\u003C\u002Fa\u003E, disponível para download ou em DVD.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Cstrong\u003EDiscutir\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EParticipe do \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fblogs\"\u003Eblogs do developerWorks\u003C\u002Fa\u003E e participe da comunidade do developerWorks.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E***\u003C\u002Fp\u003E\n\u003Cp\u003ESobre o autor: Martin ‘MC’ Brown é escritor profissional há mais de 15 anos e é autor e colaborador em mais de 26 livros abrangendo uma variedade de tópicos, incluindo o recém-publicado “Getting Started with CouchDB”. Seu conhecimento abrange inúmeras linguagens de desenvolvimento e as plataformas Perl, Python, Java, JavaScript, Basic, Pascal, Modula-2, C, C++, Rebol, Gawk, Shellscript, Windows, Solaris, Linux, BeOS, Microsoft® WP, Mac OS, e muito mais. Ele foi editor de LAMP Technologies para a revista LinuxWorld e contribui regularmente para ServerWatch.com, LinuxPlanet, ComputerWorld e IBM developerWorks. Ele baseia-se em uma formação rica e variada como membro fundador de um ISP líder no Reino Unido, gerente de sistemas e consultor de TI para uma agência de publicidade e grupo de soluções de Internet, especialista técnico para uma rede de ISP intercontinental, designer e programador de banco de dados e como consumidor compulsivo confesso de hardware e software de computação. MC atualmente é Vice-Presidente de Publicações e Educação Técnica da Couchbase e é responsável por toda documentação publicada, programas de treinamento e conteúdo, além da Couchbase Techzone.\u003C\u002Fp\u003E\n\u003Cp\u003E***\u003C\u002Fp\u003E\n\u003Cp\u003EArtigo original está disponível em: \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Flibrary\u002Fba-datamining\u002Findex.html\" target=\"_blank\"\u003Ehttp:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Flibrary\u002Fba-datamining\u002Findex.html\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n","excerpt":"\u003Cp\u003EVeja como usar bancos de dados baseados em documentos para processamento de dados e analítica como solução geral de banco de dados.\u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fbanco-de-dados\u002Fmineracao-de-dados-em-um-mundo-de-documentos","date":"1 ago, 2013","thumbnail":"","externalMention":null,"author":{"id":421,"thumbnail":"https:\u002F\u002Fsecure.gravatar.com\u002Favatar\u002Fbe5bc6f39606ac453a07bd2eb7ab21af?s=96&d=mm&r=g","name":"developerWorks Brasil","description":"é o portal de tecnologia da IBM para profissionais de TI de todo o mundo. Colabore, aprenda a criar aplicativos inovadores e compreenda tecnologias avançadas. Acesse mais artigos e tutoriais em www.ibm.com\u002Fdeveloperworks\u002Fbr","slug":"developerworks_brasil","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdeveloperworks_brasil","registered":"2010-07-07 17:06:45","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002Fsoudw","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002F","mail":"dwbr@br.ibm.com"},"articles_count":217,"views_count":4709798,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"Banco de Dados","slug":"banco-de-dados","id":7209,"link":"https:\u002F\u002Fimasters.com.br\u002Fbanco-de-dados"},{"title":"Data","slug":"data","id":16,"link":"https:\u002F\u002Fimasters.com.br\u002Fdata"}],"tags":[{"title":"Análise de Dados","slug":"analise-de-dados","id":7320,"link":"https:\u002F\u002Fimasters.com.br\u002Fanalise-de-dados"},{"title":"arquitetura","slug":"arquitetura","id":541,"link":"https:\u002F\u002Fimasters.com.br\u002Farquitetura"},{"title":"banco de dados","slug":"banco-de-dados-2","id":189,"link":"https:\u002F\u002Fimasters.com.br\u002Fbanco-de-dados-2"},{"title":"mapear","slug":"mapear","id":1959,"link":"https:\u002F\u002Fimasters.com.br\u002Fmapear"},{"title":"mineração de dados","slug":"mineracao-de-dados","id":958,"link":"https:\u002F\u002Fimasters.com.br\u002Fmineracao-de-dados"},{"title":"reduzir","slug":"reduzir","id":1960,"link":"https:\u002F\u002Fimasters.com.br\u002Freduzir"}],"seo":{"open_graph":{"title":"Mineração de dados em um mundo de documentos - iMasters - We are Developers","description":"Veja como usar bancos de dados baseados em documentos para processamento de dados e analítica como solução geral de banco de dados.","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":false,"modified_time":"2018-05-23T23:43:33-03:00","published_time":"2013-08-01T10:00:47-03:00"},"twitter":{"title":"Mineração de dados em um mundo de documentos - iMasters - We are Developers","description":"Veja como usar bancos de dados baseados em documentos para processamento de dados e analítica como solução geral de banco de dados.","type":"summary_large_image","image":false}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fbanco-de-dados\u002Fmineracao-de-dados-em-um-mundo-de-documentos","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fbanco-de-dados\u002Fmineracao-de-dados-em-um-mundo-de-documentos","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fbanco-de-dados\u002Fmineracao-de-dados-em-um-mundo-de-documentos"},"type":"post"},{"id":40806,"title":"Crie um complemento do Firefox para acessar servidores OSLC","content":"\u003Ch2\u003E\u003Ca name=\"1.Unnecessarily complicated user interfaces confuse users|outline\"\u003E\u003C\u002Fa\u003EInterfaces com o usuário desnecessariamente complicadas confundem os usuários\u003C\u002Fh2\u003E\n\u003Cp\u003EÉ importante manter uma interface com o usuário simples, para ter uma boa usabilidade. Esse fato diz respeito às ferramentas de gerenciamento de ciclo de vida do aplicativo (ALM). As ferramentas ALM precisam oferecer suporte para muitos casos de uso para muitas funções, como desenvolvedor, líder de equipe, gerente de projeto ou proprietário de produto. Por isso, as interfaces com o usuário dessas ferramentas são geralmente complicadas por dois problemas:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EPrimeiro, são incluídos muitos widgets (como botões, campos de texto, guias e links) para editar todas as propriedades de recursos a qualquer momento. No entanto, nem todos os widgets são usados, pois os usuários não editam propriedades de recursos com a mesma frequência. Se widgets de uso frequente e de uso ocasional forem exibidos ao mesmo tempo, os usuários podem se confundir facilmente. O ideal é exibir apenas os widgets que os usuários precisem para editar propriedades;\u003C\u002Fli\u003E\n\u003Cli\u003ESegundo, widgets para editar propriedades de recursos ou para criar recursos são sempre incluídos em páginas da web e visualizações (parte de páginas da web) em particular. Os usuários precisam chegar a destinos como páginas da web e visualizações, clicando em links e guias várias vezes, e então editar as propriedades dos recursos ou criar recursos. No entanto, chegar a um destino não é uma ação essencial. O ideal é que os usuários editem as propriedades de recursos ou criem recursos sem etapas não essenciais para chegar a destinos.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40807\" rel=\"attachment wp-att-40807\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40807\" alt=\"image001\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage001.gif\" width=\"578\" height=\"261\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EEste artigo soluciona esses dois problemas de ferramentas ALM com suporte para Open Services for Lifecycle Collaboration (OSLC).\u003C\u002Fp\u003E\n\u003Cp\u003EOSLC padroniza a maneira como ferramentas de ciclo de vida podem compartilhar dados (solicitações de mudança e casos de teste, por exemplo). OSLC usa Representational State Transfer (REST) para associar dados nessas ferramentas para integração, o que é um dos grandes aspectos do OSLC.\u003C\u002Fp\u003E\n\u003Cp\u003EO exemplo neste artigo usa a maneira padrão para melhorar a usabilidade, não para integração. Em servidores com suporte a OSLC, os recursos podem ser criados, lidos, atualizados e excluídos por serviços RESTful. Isso significa que é possível criar interfaces com o usuário com boa usabilidade ao chamar esses serviços da maneira que você escolher, em vez de continuar usando UIs empacotadas com o servidor.\u003C\u002Fp\u003E\n\u003Cp\u003ENa abordagem que este artigo propõe, são preparados widgets para editar propriedades de recursos e criar recursos diretamente. Em seguida, são compostas interfaces com o usuário por combinações de widgets, que podem ser customizados pelos usuários (veja a Figura 2). Essa abordagem soluciona os dois problemas desta maneira:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EOs usuários podem customizar combinações em UIs de acordo com seus propósitos, para reduzir widgets desnecessários.\u003C\u002Fli\u003E\n\u003Cli\u003EOs usuários podem editar propriedades de recursos e criar recursos diretamente, usando os widgets em combinação sem etapas não essenciais, como chegar a um destino.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40808\" rel=\"attachment wp-att-40808\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40808\" alt=\"image002\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage002.gif\" width=\"578\" height=\"261\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EUm aplicativo cliente de amostra, criado como um complemento do Firefox, soluciona esses dois problemas. As quatro seções deste artigo explicam como criar e implementar esse complemento, que o autor chamou de FireOSLC:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Frational\u002Flibrary\u002Ffirefox-add-on-oslc-servers\u002Findex.html#prerequisite\"\u003EPré-requisitos de tecnologias e software\u003C\u002Fa\u003E explica o que é necessário para implementar e testar FireOSLC;\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Frational\u002Flibrary\u002Ffirefox-add-on-oslc-servers\u002Findex.html#architecture\"\u003EVisão geral da arquitetura\u003C\u002Fa\u003E explica a arquitetura geral do complemento FireOSLC do Firefox;\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Frational\u002Flibrary\u002Ffirefox-add-on-oslc-servers\u002Findex.html#designs\"\u003EDesigns em detalhes\u003C\u002Fa\u003E explica o que FireOSLC usa para implementação;\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Frational\u002Flibrary\u002Ffirefox-add-on-oslc-servers\u002Findex.html#usecases\"\u003ECasos de uso\u003C\u002Fa\u003E explica como criar, ler e atualizar recursos OSLC de CM (Gerenciamento de Mudanças), QM (Gerenciamento de Qualidade) e RM (Gerenciamento de Requisitos) usando FireOSLC.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch2\u003E\u003Ca name=\"prerequisite\"\u003E\u003C\u002Fa\u003EPré-requisitos de tecnologias e software\u003C\u002Fh2\u003E\n\u003Cp\u003EA seção Downloads deste artigo oferece uma amostra do complemento FireOSLC Firefox. Antes de ler os detalhes, faça o download de fireoslc.xpi e execute-o para entender este artigo rapidamente.\u003C\u002Fp\u003E\n\u003Cp\u003EFireOSLC é executado como um complemento do Firefox, portanto, o único software necessário é o Firefox. FireOSLC chama um XPCOM (cross-platform component object model) pré-instalado para usar arquivos locais e o about:config do Firefox, portanto, é necessário versões do Firefox que ofereçam suporte a XPCOM. Este exemplo usa Firefox Versão 15.\u003C\u002Fp\u003E\n\u003Cp\u003EVocê usará estas tecnologias para implementar FireOSLC:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EXUL (XML User Interface language)\u003C\u002Fli\u003E\n\u003Cli\u003EJavaScript\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003ETambém é possível usar Cygwin e Perl para criar um pacote XPI (cross-platform installation) do FireOSLC.\u003C\u002Fp\u003E\n\u003Cp\u003EPara testar a execução do FireOSLC, este exemplo usa a solução Rational para Collaborative Lifecycle Management (CLM), que inclui ferramentas de ALM com suporte a OSLC. Este artigo explica o caso de uso FireOSLC para criar, ler e atualizar recursos de OSLC nestes aplicativos: recursos de CM (Gerenciamento de Mudanças) no IBM® Rational Team Concert™, recursos de QM (Gerenciamento de Qualidade) no Rational® Quality Manager, e recursos de RM (Gerenciamento de Requisitos) no Rational Requirements Composer. Você usará dados dessas soluções para testar o FireOSLC:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003ECollaborative Lifecycle Management Versão 3.0.1\n\u003Cul\u003E\n\u003Cli\u003EServidor: testhost.testdomain\u003C\u002Fli\u003E\n\u003Cli\u003EPorta: 9443\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EConta\n\u003Cul\u003E\n\u003Cli\u003ENome de usuário: tester\u003C\u002Fli\u003E\n\u003Cli\u003ESenha: testerx\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EProjeto de ciclo de vida\n\u003Cul\u003E\n\u003Cli\u003ERational Team Concert\n\u003Cul\u003E\n\u003Cli\u003ENome do projeto: TestProjectCM\u003C\u002Fli\u003E\n\u003Cli\u003EProcesso: Scrum\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003ERational Quality Manager\n\u003Cul\u003E\n\u003Cli\u003ENome do projeto: TestProjectQM\u003C\u002Fli\u003E\n\u003Cli\u003EProcesso: Processo V3 padrão de Gerenciamento de Qualidade\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003ERational Requirements Composer\n\u003Cul\u003E\n\u003Cli\u003ENome do projeto: TestProjectRM\u003C\u002Fli\u003E\n\u003Cli\u003EProcesso: Modelo do Rational Requirements Server\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch2\u003E\u003Ca name=\"architecture\"\u003E\u003C\u002Fa\u003EVisão geral da arquitetura\u003C\u002Fh2\u003E\n\u003Cp\u003EA Figura 3 mostra uma visão geral da arquitetura do FireOSLC. O quadrado maior, com o rótulo FireOSLC, é o FireOSLC geral. Os quadrados dentro do maior são pacotes de JavaScript que compõem o FireOSLC. Cada pacote JavaScript possui um prefixo com.fireoslc. Por exemplo, oslc_cm é uma abreviação de com.fireoslc.oslc_cm. Os quadrados com o canto inferior direito dobrado são entidades de dados que os usuários precisam editar. As setas mostram como os pacotes e entidades de dados interagem. As frases a seguir neste capítulo explicam a arquitetura em detalhes.\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40809\" rel=\"attachment wp-att-40809\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40809\" alt=\"image003\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage003.gif\" width=\"579\" height=\"388\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"designs\"\u003E\u003C\u002Fa\u003EDesigns em detalhes\u003C\u002Fh2\u003E\n\u003Cp\u003ESiga estas instruções para implementar o FireOSLC (explicações a seguir):\u003C\u002Fp\u003E\n\u003Col start=\"1\" type=\"1\"\u003E\n\u003Cli\u003EProcessar serviços de OSLC;\u003C\u002Fli\u003E\n\u003Cli\u003ELer, atualizar e criar recursos;\u003C\u002Fli\u003E\n\u003Cli\u003EProjetar a interface com o usuário;\u003C\u002Fli\u003E\n\u003Cli\u003EAcessar propriedades que não estão definidas em OSLC;\u003C\u002Fli\u003E\n\u003Cli\u003EDefinir preferências no Firefox.\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Ch3\u003E\u003Ca name=\"N101A6\"\u003E\u003C\u002Fa\u003EProcessar serviços de OSLC\u003C\u002Fh3\u003E\n\u003Cp\u003EPara poder obter informações do servidor OSLC, os usuários precisam ser autenticados por ele. O pacote \u003Cstrong\u003Eauth\u003C\u002Fstrong\u003E envia informações de contas dos usuários para solicitar autenticação de formulário.\u003C\u002Fp\u003E\n\u003Cp\u003EA seguir, é necessário ler os recursos existentes ou criar novos recursos. É necessário obter recursos de consulta ou factories de criação.\u003C\u002Fp\u003E\n\u003Cp\u003EPara processar os serviços OSLC, siga estas instruções:\u003C\u002Fp\u003E\n\u003Col start=\"1\" type=\"1\"\u003E\n\u003Cli\u003EUse o serviço de raiz para solicitar informações e extraia a URL do catálogo do provedor de serviços;\u003C\u002Fli\u003E\n\u003Cli\u003EUse o catálogo do provedor de serviços para solicitar informações e extraia a URL do provedor de serviços;\u003C\u002Fli\u003E\n\u003Cli\u003EUse o provedor de serviços para solicitar informações:\n\u003Col type=\"a\"\u003E\n\u003Cli\u003EExtraia a URL do recurso de consulta para que os recursos existentes sejam lidos.\u003C\u002Fli\u003E\n\u003Cli\u003EExtraia a URL de factories de criação para que novos recursos sejam criados.\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cp\u003EO pacote sprovider solicita informações através de serviços de OSLC, como o serviço raiz, catálogo de provedor de serviços e provedor de serviços (nessa ordem), e obtém recurso de consulta e factories de criação. Com XPath, a URL do serviço OSLC pode ser extraída das informações retornadas pelo serviço OSLC anterior. O pacote oslc_cm oferece XPaths para obter serviços OSLC para OSLC CM. É o mesmo que o pacote oslc_qm (OSLC QM) e o pacote oslc_rm (OSLC RM).\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N101DF\"\u003E\u003C\u002Fa\u003ELer, atualizar e criar recursos\u003C\u002Fh3\u003E\n\u003Cp\u003EServiços de OSLC usam HTTP para ações de criação, recuperação, atualização e exclusão de recursos. FireOSLC oferece suporte para as operações de leitura, atualização e criação de recursos, mas não para exclusão. Isso porque a operação de exclusão não tem geralmente suporte em servidores OSLC tanto quanto as demais operações.\u003C\u002Fp\u003E\n\u003Cp\u003EPara selecionar um recurso existente em servidores OSLC, é possível usar a Consulta OSLC. Para a operação de leitura, FireOSLC recupera um recurso por vez com o método HTTP \u003Cem\u003Eget\u003C\u002Fem\u003E com o parâmetro de consulta oslc.where. Para a operação de atualização, FireOSLC atualiza o recurso recuperado durante a operação de leitura através do método HTTP \u003Cem\u003Eput\u003C\u002Fem\u003E com a entrada do usuário. Para a operação de criação, FireOSLC cria um novo recurso através do método HTTP \u003Cem\u003Epost\u003C\u002Fem\u003E com a entrada do usuário. O pacote \u003Cstrong\u003Econsts\u003C\u002Fstrong\u003E contém propriedades definidas em OSLC. Essas propriedades de recursos podem ser acessadas durante operações de leitura, atualização e criação pelo FireOSLC.\u003C\u002Fp\u003E\n\u003Cp\u003EO pacote oslc_cm realiza as operações para o recurso de CM do OSLC, Solicitação de Mudança. Da mesma forma, o pacoteoslc_qm realiza as operações para os recursos de QM do OSLC QM: Plano de Teste, Caso de Teste, Script de Teste, Registro de Execução de Teste, Resultado de Teste. O pacote oslc_rm realiza as operações para os recursos de RM do OSLC: Requisito e Coleção de Requisito.\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N10203\"\u003E\u003C\u002Fa\u003EProjetar a interface com o usuário\u003C\u002Fh3\u003E\n\u003Cp\u003EA interface com o usuário do FireOSLC é criada pelo pacote \u003Cstrong\u003Eui\u003C\u002Fstrong\u003E com XUL. Inclui seis áreas de janela. Este artigo usa a expressão “área de janela” para indicar uma área lógica na interface com o usuário do FireOSLC.\u003C\u002Fp\u003E\n\u003Col start=\"1\" type=\"1\"\u003E\n\u003Cli\u003ELogin;\u003C\u002Fli\u003E\n\u003Cli\u003EOSLC settings;\u003C\u002Fli\u003E\n\u003Cli\u003EProperties list;\u003C\u002Fli\u003E\n\u003Cli\u003ECreate, Retrieve, Update;\u003C\u002Fli\u003E\n\u003Cli\u003EProperties;\u003C\u002Fli\u003E\n\u003Cli\u003EResults.\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cp\u003EA Figura 4 ajudará a entender as explicações a seguir.\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003ELogin: \u003C\u002Fstrong\u003EInsira o nome do servidor com a porta, nome de usuário e senha para efetuar login no servidor OSLC. Em caso de sucesso, o status mostra conectado.\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Cstrong\u003EOSLC settings: \u003C\u002Fstrong\u003ESelecione um tipo de aplicativo OSLC, um provedor de serviços e um tipo de recurso.\u003C\u002Fp\u003E\n\u003Cdl\u003E\n\u003Cdt\u003E\u003Cstrong\u003EProperties list: \u003C\u002Fstrong\u003EEssa área de janela corresponde à lista de propriedades na Figura 3. O formato é um texto de propriedades separadas por vírgula. Na lista de propriedades, é necessário escrever propriedades com namespaces que você deseja acessar durante operações de leitura, atualização ou criação de recursos.\u003Cstrong\u003ENota\u003C\u002Fstrong\u003E\u003Cstrong\u003E: \u003C\u002Fstrong\u003EPropriedades que não tenham sido incluídas na lista não podem ser acessadas durante as operações.\u003C\u002Fdt\u003E\n\u003Cdt\u003E\u003Cstrong\u003ECreate, Retrieve, Update and Properties:\u003C\u002Fstrong\u003E Selecione o botão de opções de R|U (Leitura ou Atualização) ou C (Criação).\u003Cstrong\u003ENota:\u003C\u002Fstrong\u003E No FireOSLC, a operação de atualização não pode ser feita sem a operação de leitura.\u003C\u002Fdt\u003E\n\u003Cdd\u003E\n\u003Cul\u003E\n\u003Cli\u003EAo escolher o botão de opções R|U, selecione uma opção para o parâmetro de consulta oslc.where e escreva um valor para esse parâmetro. FireOSLC oferece suporte para estes três parâmetros: dcterms:identifier, dcterms:title, dcterms:description\u003C\u002Fli\u003E\n\u003Cli\u003EAo clicar no botão de opções R, um recurso correspondente à consulta oslc.where é buscado no servidor OSLC e as suas propriedades são exibidas na área de janela Properties. Se houver mais de um recurso correspondente à consulta oslc.where, um deles é retornado aleatoriamente.\u003C\u002Fli\u003E\n\u003Cli\u003EPara alterar as propriedades mostradas na área de janela Properties após clicar no botão de opções R, escreva os novos valores em campos de texto ou selecione itens das listas de menu. Ao clicar no botão de opções U, os valores alterados são enviados ao servidor OSLC para atualizar as propriedades do recurso.\u003C\u002Fli\u003E\n\u003Cli\u003EAo selecionar o botão de opções C, escreva valores das propriedades na área de janela Properties. Ao clicar no botão C, as propriedades são enviadas ao servidor OSLC para criar um novo recurso.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fdd\u003E\n\u003Cdt\u003E\u003Cstrong\u003EResults\u003C\u002Fstrong\u003E\u003C\u002Fdt\u003E\n\u003Cdd\u003E\n\u003Cul\u003E\n\u003Cli\u003EUm código retornado e a hora são mostrados quando operações de leitura, atualização e criação são executadas.\u003C\u002Fli\u003E\n\u003Cli\u003EUm corpo retornado é mostrado na janela de diálogo ao clicar no botão body.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fdd\u003E\n\u003C\u002Fdl\u003E\n\u003Cp\u003EA Figura 4 mostra uma captura de tela da interface com o usuário do FireOSLC. A Figura 5 mostra uma captura de tela do Rational Team Concert, na qual aparece o mesmo item de trabalho mostrado na Figura 4.\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40811\" rel=\"attachment wp-att-40811\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40811\" alt=\"image004 (1)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage004-1.jpg\" width=\"580\" height=\"660\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage004-1.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage004-1-263x300.jpg 263w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E \u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40813\" rel=\"attachment wp-att-40813\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40813\" alt=\"image005 (1)\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage005-1.jpg\" width=\"580\" height=\"336\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage005-1.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage005-1-300x173.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N102B0\"\u003E\u003C\u002Fa\u003EAcessar propriedades que não estão definidas em OSLC\u003C\u002Fh3\u003E\n\u003Cp\u003ECom as três etapas acima, é possível acessar propriedades definidas na especificação de OSLC durante operações de leitura, atualização e criação de recursos em servidores OSLC. No entanto, ainda há dois desafios:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EComo acessar propriedades que não são definidas na especificação do OSLC\u003C\u002Fli\u003E\n\u003Cli\u003EComo acessar propriedades com representação de referência e com propriedades sem referência\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003EAs ferramentas de ALM frequentemente definem propriedades que não são definidas na especificação de OSLC. Algumas dessas propriedades são essenciais para operações em recursos. Por exemplo, sem a propriedade rtc_cm:filedAgainst, o recurso Solicitação de Mudança não pode ser criado no Rational Team Concert com as configurações padrão. FireOSLC oferece uma extensão de propriedade que é um arquivo externo, no qual é possível incluir as propriedades necessárias das ferramentas de ALM que devem ser acessadas durante operações de leitura, criação e atualização de recursos. O pacote oslc_ext lê dados do arquivo externo da extensão de propriedade para tornar as propriedades adicionais disponíveis durante operações em recursos.\u003C\u002Fp\u003E\n\u003Cp\u003EQuando o tipo de valor de propriedades (dcterms:contributor, por exemplo) for referenciado, é necessário solicitar as informações necessárias da referência para ver quais valores foram definidos para as propriedades. As informações solicitadas devem ser processadas para extrair valores e, em seguida, os valores são mostrados nos widgets apropriados. As maneiras de processar as informações solicitadas diferem de acordo com as propriedades e com as ferramentas de ALM. Para processar essas propriedades do Rational Team Concert, o pacote oslc_ext oferece duas abordagens:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003EA primeira é solicitar informações da URL especificada para mostrar todos os valores selecionáveis em um menu suspenso. Por exemplo,\n\u003Cul\u003E\n\u003Cli\u003Ertc_cm:filedAgainst\u003C\u002Fli\u003E\n\u003Cli\u003Ertc_cm:type\u003C\u002Fli\u003E\n\u003Cli\u003Eoslc_cmx:priority\u003C\u002Fli\u003E\n\u003Cli\u003Eoslc_cmx:severity\u003C\u002Fli\u003E\n\u003Cli\u003Edcterms:contributor\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EA segunda abordagem é solicitar informações da URL especificada de uma propriedade, como oslc:discussion, para mostrar o seu valor mais recente em uma caixa de texto.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003EFireOSLC lê dados da extensão de propriedades, fireoslc_prop_ext.xml (um arquivo externo), no qual é possível escrever tags XML para definir informações ou propriedades acessadas durante as operações. Também é possível usar estas tags no arquivo de extensão de propriedades:\u003C\u002Fp\u003E\n\u003Cul\u003E\n\u003Cli\u003Eoslc_ext_all\n\u003Cul\u003E\n\u003Cli\u003EA tag oslc_ext_all é a tag de raiz, com tags oslc_ext como filhas.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003Eoslc_ext\n\u003Cul\u003E\n\u003Cli\u003EA tag oslc_ext possui xpath_ns e tags de propriedade como filhas para cada tipo de OSLC.\u003C\u002Fli\u003E\n\u003Cli\u003EAtributo oslc_type: 0 é CM, 1 é QM, 2 é RM.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003Expath_ns\n\u003Cul\u003E\n\u003Cli\u003EA tag xpath_ns registra namespaces. Os namespaces registrados são usados em dois casos:\n\u003Cul\u003E\n\u003Cli\u003EPara incluir propriedades em XML enviado ao servidor OSLC durante a operação de criação, namespaces são incluídos em um cabeçalho de XML.\u003C\u002Fli\u003E\n\u003Cli\u003EPara acessar um nó (que corresponde a uma propriedade) em documento com base XML usando a função document.evaluate durante a operação de atualização, um namespace do nó é incluído no resolvedor de namespace (consulte o link em Recursos para “Introduction to using XPath in JavaScript”).\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EAtributo key: um prefixo de namespace.\u003C\u002Fli\u003E\n\u003Cli\u003EAtributo url: a URL do namespace.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003Eproperty\n\u003Cul\u003E\n\u003Cli\u003EA tag property inclui informações sobre uma nova propriedade. Os atributos id e type são necessários.\n\u003Cul\u003E\n\u003Cli\u003EAtributo id: o nome de uma propriedade\u003C\u002Fli\u003E\n\u003Cli\u003EAtributo type: Read-only, text, list, rtc_ext\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EUma propriedade cujo valor de type seja read-only é mostrada como um rótulo na interface com o usuário.\u003C\u002Fli\u003E\n\u003Cli\u003EUma propriedade cujo valor de type seja text é mostrada como uma caixa de texto na interface com o usuário.\u003C\u002Fli\u003E\n\u003Cli\u003EUma propriedade cujo valor de type seja list é mostrada como um menu suspenso na interface com o usuário. O atributo precisa de tags de item como filhas.\u003C\u002Fli\u003E\n\u003Cli\u003EUma propriedade cujo valor de type seja rtc_ext é mostrada como um menu suspenso ou uma caixa de texto (apenas oslc:discussion). id com valor de type rtc_ext seria rtc_cm:filedAgainst, rtc_cm:type, oslc_cmx:priority, oslc_cmx:severity, dcterms:contributor, oslc:discussion. O atributo precisa de quatro atributos adicionais: def_url, tgt_xpath, tgt_ns e tgt_name.\n\u003Cul\u003E\n\u003Cli\u003EAtributo def_url: uma URL especificada que retorna informações de todos os valores e rótulos selecionáveis. Esse atributo pode ser vazio para oslc:discussion.\u003C\u002Fli\u003E\n\u003Cli\u003EAtributo tgt_xpath: um XPath que enumera valores e rótulos selecionáveis.\u003C\u002Fli\u003E\n\u003Cli\u003EAtributo tgt_ns: a URL do namespace da tag que inclui o rótulo\u003C\u002Fli\u003E\n\u003Cli\u003EAtributo tgt_name: o nome da tag que inclui o rótulo. É necessário um prefixo de namespace para oslc:discussion (por exemplo, dc:description).\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003ETag item\n\u003Cul\u003E\n\u003Cli\u003EA tag item inclui rótulos selecionáveis e valores de uma propriedade.\n\u003Cul\u003E\n\u003Cli\u003EAtributo label: rótulo mostrado no item de menu.\u003C\u002Fli\u003E\n\u003Cli\u003EAtributo value: valor enviado ao servidor OSLC se o rótulo for selecionado.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003EPor exemplo, você incluiria a tag property para acessar uma nova propriedade e a tag xpath_ns quando a nova propriedade tiver um prefixo que não seja definido na especificação OSLC. A Listagem 1 mostra um exemplo do arquivo de extensão de propriedades.\u003C\u002Fp\u003E\n\u003Cpre class=\"brush: xml; gutter: true\"\u003E<oslc_ext_all>\r\n<!-- Extensions for OSLC CM -->\r\n<oslc_ext oslc_type="0">\r\n<!-- Here are examples of properties in RTC.-->\r\n<xpath_ns key="foaf" url="http:\u002F\u002Fxmlns.com\u002Ffoaf\u002F0.1\u002F"\u002F>\r\n<xpath_ns key="rtc_cm" url="http:\u002F\u002Fjazz.net\u002Fxmlns\u002Fprod\u002Fjazz\u002Frtc\u002Fcm\u002F1.0\u002F"\u002F>\r\n<xpath_ns key="oslc_cmx" url="http:\u002F\u002Fopen-services.net\u002Fns\u002Fcm-x#"\u002F>\r\n<xpath_ns key="rdf" url="http:\u002F\u002Fwww.w3.org\u002F1999\u002F02\u002F22-rdf-syntax-ns#"\u002F>\r\n<xpath_ns key="dcterms" url="http:\u002F\u002Fpurl.org\u002Fdc\u002Fterms\u002F"\u002F>\r\n\r\n<!-- xmlns:foaf="http:\u002F\u002Fxmlns.com\u002Ffoaf\u002F0.1\u002F" -->\r\n<property id="dcterms:contributor" type="rtc_ext"\r\n def_url="https:\u002F\u002Ftesthost.testdomain:9443\u002Fccm\u002Foslc\u002Fusers\u002F?oslc.select=foaf:name"\r\n tgt_xpath="\u002F\u002Ffoaf:Person"\r\n tgt_ns="http:\u002F\u002Fxmlns.com\u002Ffoaf\u002F0.1\u002F"\r\n tgt_name="name"\u002F>\r\n\r\n<!-- xmlns:dcterms="http:\u002F\u002Fpurl.org\u002Fdc\u002Fterms\u002F" -->\r\n<property id="rtc_cm:type" type="rtc_ext"\r\n def_url="https:\u002F\u002Ftesthost.testdomain:9443\u002Fccm\u002Foslc\u002Ftypes\u002F_yJNt8vNgEeCl8oCPwVoRZA\u002F"\r\n tgt_xpath="\u002F\u002Frtc_cm:Type"\r\n tgt_ns="http:\u002F\u002Fpurl.org\u002Fdc\u002Fterms\u002F" \r\n tgt_name="title"\u002F>\r\n\r\n<property id="rtc_cm:filedAgainst" type="rtc_ext"\r\n def_url="https:\u002F\u002Ftesthost.testdomain:9443\u002Fccm\u002Foslc\u002Fcategories.xml\r\n?oslc.select=dcterms:title"\r\n tgt_xpath="\u002F\u002Frtc_cm:Category"\r\n tgt_ns="http:\u002F\u002Fpurl.org\u002Fdc\u002Fterms\u002F"\r\n tgt_name="title"\u002F>\r\n\r\n<property id="oslc_cmx:priority" type="rtc_ext"\r\n def_url="https:\u002F\u002Ftesthost.testdomain:9443\u002Fccm\u002Foslc\u002Fenumerations\u002F\r\n_yJNt8vNgEeCl8oCPwVoRZA\u002Fpriority"\r\n tgt_xpath="\u002F\u002Frtc_cm:Literal"\r\n tgt_ns="http:\u002F\u002Fpurl.org\u002Fdc\u002Fterms\u002F"\r\n tgt_name="title"\u002F>\r\n\r\n<property id="oslc_cmx:severity" type="rtc_ext"\r\n def_url="https:\u002F\u002Ftesthost.testdomain:9443\u002Fccm\u002Foslc\u002Fenumerations\u002F\r\n_yJNt8vNgEeCl8oCPwVoRZA\u002Fseverity"\r\n tgt_xpath="\u002F\u002Frtc_cm:Literal"\r\n tgt_ns="http:\u002F\u002Fpurl.org\u002Fdc\u002Fterms\u002F"\r\n tgt_name="title"\u002F>\r\n\r\n<property id="oslc:discussion" type="rtc_ext"\r\n def_url="this_field_of_oslc_discussion_is_not_used"\r\n tgt_xpath="\u002F\u002Frdf:Description[rdf:type[@rdf:resource='\r\nhttp:\u002F\u002Fopen-services.net\u002Fns\u002Fcore#Comment']]"\r\n tgt_ns="http:\u002F\u002Fpurl.org\u002Fdc\u002Fterms\u002F"\r\n tgt_name="dc:description"\u002F>\r\n\r\n<!-- Here are examples of properties specific for user's ALM tools. -->\r\n<xpath_ns key="t1" url="http:\u002F\u002Ftesthost.testdomain\u002F"\u002F>\r\n<property id="t1:list1" type="list">\r\n <item label="label1" value="value1"\u002F>\r\n <item label="label2" value="value2"\u002F>\r\n <item label="label3" value="value3"\u002F>\r\n<\u002Fproperty>\r\n<property id="t1:readonly1" type="readonly"\u002F>\r\n<property id="t1:text1" type="text"\u002F>\r\n<\u002Foslc_ext>\r\n<!-- Extensions for OSLC QM -->\r\n<oslc_ext oslc_type="1"\u002F>\r\n<!-- Extensions for OSLC RM -->\r\n<oslc_ext oslc_type="2">\r\n<xpath_ns key="dc" url="http:\u002F\u002Fpurl.org\u002Fdc\u002Fterms\u002F"\u002F>\r\n<property id="dc:identifier" type="readonly"\u002F>\r\n<property id="dc:modified" type="readonly"\u002F>\r\n<property id="dc:created" type="readonly"\u002F>\r\n<property id="dc:title" type="text"\u002F>\r\n<property id="dc:creator" type="readonly"\u002F>\r\n<property id="dc:contributor" type="text"\u002F>\r\n<property id="dc:description" type="text"\u002F>\r\n<\u002Foslc_ext>\r\n<\u002Foslc_ext_all>\u003C\u002Fpre\u003E\n\u003Ch3\u003EDefinir preferências no Firefox\u003C\u002Fh3\u003E\n\u003Cp\u003EFireOSLC usa as preferências do Firefox. Todas as preferências têm um prefixo, por exemplo, extensions.fireoslc.servername para nome de servidor. A Tabela 1 mostra todas as preferências. Para configurar essas preferências, escreva about:config na barra de endereços do Firefox.\u003C\u002Fp\u003E\n\u003Ctable summary=\"\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n\u003Cth\u003ENome da preferência\u003C\u002Fth\u003E\n\u003Cth\u003ETipo\u003C\u002Fth\u003E\n\u003Cth\u003EExplicação\u003C\u002Fth\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Eservername\u003C\u002Ftd\u003E\n\u003Ctd\u003Ecadeia de caractere\u003C\u002Ftd\u003E\n\u003Ctd\u003EArmazena o nome do servidor com o número da porta.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Eusername\u003C\u002Ftd\u003E\n\u003Ctd\u003Ecadeia de caractere\u003C\u002Ftd\u003E\n\u003Ctd\u003EArmazena o nome de usuário.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Eplist\u003C\u002Ftd\u003E\n\u003Ctd\u003Ecadeia de caractere\u003C\u002Ftd\u003E\n\u003Ctd\u003EArmazena a lista de propriedades.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Elog\u003C\u002Ftd\u003E\n\u003Ctd\u003Evariáveis booleanas\u003C\u002Ftd\u003E\n\u003Ctd\u003EEspecifica se o conteúdo do log é gravado em um arquivo local. O valor padrão é falso.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Eroot_serv.cm\u003Cbr \u002F\u003E\nroot_serv.qm\u003Cbr \u002F\u003E\nroot_serv.rm\u003C\u002Ftd\u003E\n\u003Ctd\u003Ecadeia de caractere\u003C\u002Ftd\u003E\n\u003Ctd\u003EUm caminho dos serviços de raiz que retorna catálogos do provedor de serviços. É um caminho relativo para o nome do servidor. Os valores padrão são ccm\u002Frootservices, qm\u002Frootservices e rm\u002Frootservices, nessa ordem.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003Eworkdir\u003C\u002Ftd\u003E\n\u003Ctd\u003Ecadeia de caractere\u003C\u002Ftd\u003E\n\u003Ctd\u003EÉ um caminho para um diretório no qual o arquivo de extensão de propriedades (fireoslc_prop_ext.xml) e o arquivo de log estão armazenados. O valor padrão é c:\\tmp.\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003C\u002Ftbody\u003E\n\u003C\u002Ftable\u003E\n\u003Ch2\u003E\u003Ca name=\"usecases\"\u003E\u003C\u002Fa\u003ECasos de uso\u003C\u002Fh2\u003E\n\u003Cp\u003EEsta seção explica como usar FireOSLC para criar, ler e atualizar recursos de CM, QM e RM do OSLC.\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N103E4\"\u003E\u003C\u002Fa\u003EGerenciamento de mudanças (CM)\u003C\u002Fh3\u003E\n\u003Cp\u003ECrie um recurso de Solicitação de Mudança no Rational Team Concert.\u003C\u002Fp\u003E\n\u003Col start=\"1\" type=\"1\"\u003E\n\u003Cli\u003ESelecione \u003Cstrong\u003ETools\u003C\u002Fstrong\u003E > \u003Cstrong\u003EFireOSLC\u003C\u002Fstrong\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003EInsira o nome do servidor, nome de usuário e senha e clique em \u003Cstrong\u003Elogin\u003C\u002Fstrong\u003E.\n\u003Cul\u003E\n\u003Cli\u003E\u003Cstrong\u003EServidor:\u003C\u002Fstrong\u003E \u003Ccode\u003Etesthost.testdomain:9443\u002Fjts\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Cstrong\u003EUsuário\u003C\u002Fstrong\u003E: \u003Ccode\u003Etester\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Cstrong\u003ESenha:\u003C\u002Fstrong\u003E \u003Ccode\u003Etesterx\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003ESe o login falhar na etapa anterior, certifique-se de que os cookies estão ativados.\n\u003Col start=\"1\" type=\"a\"\u003E\n\u003Cli\u003EAbra \u003Cstrong\u003ETools\u003C\u002Fstrong\u003E > \u003Cstrong\u003EOptions\u003C\u002Fstrong\u003E > \u003Cstrong\u003EPrivacy\u003C\u002Fstrong\u003E e acesse a seção History.\u003C\u002Fli\u003E\n\u003Cli\u003EEm Firefox will, clique em \u003Cstrong\u003EUse custom settings for history\u003C\u002Fstrong\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003EClique em \u003Cstrong\u003EAccept cookies from sites\u003C\u002Fstrong\u003E e \u003Cstrong\u003EAccept third-party cookies\u003C\u002Fstrong\u003E. Alternativa: em vez de clicar em \u003Cstrong\u003EAccept third-party cookies\u003C\u002Fstrong\u003E, clique em \u003Cstrong\u003EExceptions\u003C\u002Fstrong\u003E, escreva o nome do seu servidor (por exemplo, \u003Ccode\u003Etesthost.testdomain\u003C\u002Fcode\u003E), clique em \u003Cstrong\u003EAllow\u003C\u002Fstrong\u003E, \u003Cstrong\u003EClose\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003Cli\u003EClique em \u003Cstrong\u003EOK\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EClique em um tipo de OSLC, selecione um provedor de serviços e um tipo de recursos na área de janela de configurações de OSLC. Por exemplo,\n\u003Cul\u003E\n\u003Cli\u003EClique em \u003Cstrong\u003ECM\u003C\u002Fstrong\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003EEm Service Provider, selecione \u003Cstrong\u003ETestProjectCM\u003C\u002Fstrong\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003EEm Resource type, selecione \u003Cstrong\u003EChangeRequest\u003C\u002Fstrong\u003E.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EEscreva properties na área de janela Properties list. Para Rational Team Concert,\u003Cstrong\u003E dcterms:title\u003C\u002Fstrong\u003E e \u003Cstrong\u003Ertc_cm:filedAgainst \u003C\u002Fstrong\u003Edeve ser incluída. Por exemplo,\n\u003Cpre class=\"brush: xml; gutter: true\"\u003Edcterms:title,dcterms:description,dcterms:contributor,rtc_cm:type,rtc_cm:filedAgainst\u003C\u002Fpre\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione o botão de opções \u003Cstrong\u003EC\u003C\u002Fstrong\u003E na área de janela Create, Retrieve, Update.\u003C\u002Fli\u003E\n\u003Cli\u003EEscreva valores nas caixas de texto ou selecione valores nos menus suspensos ao lado dos rótulos de propriedade na área de janela de propriedade. Por exemplo,\n\u003Col start=\"1\" type=\"a\"\u003E\n\u003Cli\u003E\u003Cstrong\u003Edcterms:title:\u003C\u002Fstrong\u003E escreva \u003Ccode\u003EFunction A returns an invalid value.\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Cstrong\u003Ertc_cm:filedAgainst:\u003C\u002Fstrong\u003E selecione \u003Cstrong\u003ETestProjectCM\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Cstrong\u003Edcterms:description:\u003C\u002Fstrong\u003E escreva \u003Ccode\u003EInvestigate a case of input value B.\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Cstrong\u003Edcterms:contributor: \u003C\u002Fstrong\u003Eselecione \u003Cstrong\u003Etester\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Cstrong\u003Ertc_cm:type:\u003C\u002Fstrong\u003E selecione \u003Cstrong\u003EDefect\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EClique no botão \u003Cstrong\u003EC\u003C\u002Fstrong\u003E na área de janela Create, Retrieve, Update (Figura 6) e verifique se o código de sucesso (201) é exibido na área de janela Results. Um código de erro significa que o FireOSLC não criou um recurso de Solicitação de Mudança.\u003C\u002Fli\u003E\n\u003Cli\u003EClique no botão \u003Cstrong\u003Ebody\u003C\u002Fstrong\u003E na área de janela Results e você verá a propriedade \u003Cstrong\u003Edcterms:identifier\u003C\u002Fstrong\u003E do recém-criado recurso de Solicitação de Mudança (Figura 7). Também é possível usar o cliente da web do Rational Team Concert para verificar se o recurso de Solicitação de Mudança foi criado.\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40815\" rel=\"attachment wp-att-40815\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40815\" alt=\"image006\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage006.jpg\" width=\"580\" height=\"660\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage006.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage006-263x300.jpg 263w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40816\" rel=\"attachment wp-att-40816\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40816\" alt=\"image007\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage007.jpg\" width=\"467\" height=\"538\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage007.jpg 467w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage007-260x300.jpg 260w\" sizes=\"(max-width: 467px) 100vw, 467px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003EEm seguida, leia o recurso recém-criado e atualize-o.\u003C\u002Fp\u003E\n\u003Col start=\"10\" type=\"1\"\u003E\n\u003Cli\u003EEscreva properties na área de janela Properties list. Por exemplo,\n\u003Cpre class=\"brush: xml; gutter: true\"\u003Edcterms:identifier,oslc_cmx:priority,oslc_cmx:severity,oslc:discussion\u003C\u002Fpre\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione um tipo de operação e um parâmetro de consulta \u003Cstrong\u003Eoslc.where\u003C\u002Fstrong\u003E e escreva um valor na área de janela Create, Retrieve, Update.\n\u003Cul\u003E\n\u003Cli\u003ESelecione o botão de opções \u003Cstrong\u003ER|U\u003C\u002Fstrong\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione \u003Cstrong\u003Edcterms:identifier\u003C\u002Fstrong\u003E em oslc.where no menu suspenso.\u003C\u002Fli\u003E\n\u003Cli\u003EEscreva um valor que você viu na etapa de criação de recurso acima.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EClique no botão \u003Cstrong\u003ER\u003C\u002Fstrong\u003E na área de janela Create, Retrieve, Update e verifique se o código de sucesso (200, por exemplo) é exibido na área de janela Results. Então você verá as propriedades do recurso na área de janela Properties (Figura 8). Um código de erro significa que o FireOSLC não leu o recurso de Solicitação de Mudança.\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione e escreva valores. Por exemplo,\n\u003Cul\u003E\n\u003Cli\u003E\u003Cstrong\u003Eoslc_cmx:priority:\u003C\u002Fstrong\u003E selecione \u003Cstrong\u003EHigh\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Cstrong\u003Eoslc_cmx:severity:\u003C\u002Fstrong\u003E selecione \u003Cstrong\u003ECritical\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Cstrong\u003Eoslc:discussion:\u003C\u002Fstrong\u003E \u003Ccode\u003EWe need to fix it ASAP!\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EClique no botão \u003Cstrong\u003EU\u003C\u002Fstrong\u003E na área de janela Create, Retrieve, Update e verifique se o código de sucesso (200, por exemplo) é exibido na área de janela Results (Figura 9). Um código de erro significa que o FireOSLC não atualizou o recurso de Solicitação de Mudança.\u003Cstrong\u003ENota: \u003C\u002Fstrong\u003EInternamente, oslc:discussion estendido por Rational Team Concert é executado separadamente por meio de post HTTP, portanto, dois códigos de sucesso serão mostrados se oslc:discussion for acessado com outras propriedades, como acima.\u003C\u002Fli\u003E\n\u003Cli\u003EClique no botão \u003Cstrong\u003Ebody\u003C\u002Fstrong\u003E na área de janela Results para ver as propriedades atualizadas nas informações de recurso retornadas. Também é possível ver as propriedades atualizadas do recurso com o cliente de navegador da web do Rational Team Concert (Figura 10).\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40818\" rel=\"attachment wp-att-40818\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40818\" alt=\"image008\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage008.jpg\" width=\"580\" height=\"660\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage008.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage008-263x300.jpg 263w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40819\" rel=\"attachment wp-att-40819\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40819\" alt=\"image009\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage009.jpg\" width=\"580\" height=\"660\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage009.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage009-263x300.jpg 263w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Cp\u003E \u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40820\" rel=\"attachment wp-att-40820\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40820\" alt=\"image010\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage010.jpg\" width=\"580\" height=\"445\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage010.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage010-300x230.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N10569\"\u003E\u003C\u002Fa\u003EGerenciamento de Qualidade (QM)\u003C\u002Fh3\u003E\n\u003Cp\u003ECrie um recurso de TestCase no Rational Quality Manager.\u003C\u002Fp\u003E\n\u003Col start=\"1\" type=\"1\"\u003E\n\u003Cli\u003EClique em um tipo de OSLC, selecione um provedor de serviço e um tipo de recurso na área de janela de configurações de OSLC.\n\u003Cul\u003E\n\u003Cli\u003EClique em \u003Cstrong\u003EQM.\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione \u003Cstrong\u003ETestProjectQM\u003C\u002Fstrong\u003E em Service Provider.\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione \u003Cstrong\u003ETestCase\u003C\u002Fstrong\u003E em Resource type.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EEscreva propriedades na lista de propriedades. Por exemplo, \u003Ccode\u003Edcterms:title\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione o botão de opções \u003Cstrong\u003EC\u003C\u002Fstrong\u003E na área de janela Create, Retrieve, Update.\u003C\u002Fli\u003E\n\u003Cli\u003EEscreva um valor na caixa de texto na área de janela Properties. Por exemplo, para dcterms:title:\u003Ccode\u003ETC0905\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003EClique no botão \u003Cstrong\u003EC\u003C\u002Fstrong\u003E para criar um recurso TestCase e verifique se o código de sucesso (201, por exemplo) é exibido na área de janela Results.\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cp\u003EEm seguida, leia o recurso TestCase recém-criado e atualize-o.\u003C\u002Fp\u003E\n\u003Col start=\"6\" type=\"1\"\u003E\n\u003Cli\u003EEscreva propriedades na lista de propriedades. Por exemplo, \u003Ccode\u003Edcterms:title,dcterms:description\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione um tipo de operação e um parâmetro de consulta oslc.where e escreva um valor na área de janela Create, Retrieve, Update.\n\u003Cul\u003E\n\u003Cli\u003ESelecione o botão de opções \u003Cstrong\u003ER|U\u003C\u002Fstrong\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione \u003Cstrong\u003Edcterms:title\u003C\u002Fstrong\u003E em oslc.where no menu suspenso.\u003C\u002Fli\u003E\n\u003Cli\u003EEscreva o mesmo valor da etapa 4. Por exemplo, \u003Ccode\u003ETC0905\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EClique no botão \u003Cstrong\u003ER\u003C\u002Fstrong\u003E e verifique se o código de sucesso (200, por exemplo) é exibido na área de janela Results, e então você verá as propriedades na área de janela Properties.\u003C\u002Fli\u003E\n\u003Cli\u003EEscreva um valor. Por exemplo, dcterms:description: \u003Ccode\u003Ethis is test description\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003EClique no botão \u003Cstrong\u003EU\u003C\u002Fstrong\u003E e verifique se o código de sucesso (200, por exemplo) é exibido na área de janela Results.\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cp\u003EA Figura 11 mostra uma captura de tela do recurso TestCase recém-criado no web client do Rational Quality Manager.\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40821\" rel=\"attachment wp-att-40821\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40821\" alt=\"image011\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage011.jpg\" width=\"580\" height=\"439\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage011.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage011-300x227.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch3\u003E\u003Ca name=\"N105F2\"\u003E\u003C\u002Fa\u003EGerenciamento de Requisitos (RM)\u003C\u002Fh3\u003E\n\u003Cp\u003ECrie um recurso de Requisito no Rational Requirements Composer.\u003C\u002Fp\u003E\n\u003Col type=\"1\"\u003E\n\u003Cli\u003EClique em um tipo de OSLC e selecione o provedor de serviço e o tipo de recurso na área de janela de configurações de OSLC:\n\u003Col start=\"1\" type=\"a\"\u003E\n\u003Cli\u003EClique em \u003Cstrong\u003ERM.\u003C\u002Fstrong\u003E\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione \u003Cstrong\u003ETestProjectRM\u003C\u002Fstrong\u003E como provedor de serviços.\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione \u003Cstrong\u003ERequirement\u003C\u002Fstrong\u003E como tipo de recurso.\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EEscreva as propriedades na lista Properties. Por exemplo, \u003Ccode\u003Edc:title\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione o botão de opções \u003Cstrong\u003EC\u003C\u002Fstrong\u003E na área de janela Create, Retrieve, Update.\u003C\u002Fli\u003E\n\u003Cli\u003EEscreva valores na caixa de texto da área de janela properties. Por exemplo, \u003Ccode\u003EReq0905\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003EClique no botão C para criar um recurso de Requisito e verifique se o código de sucesso (201, por exemplo) é mostrado na área de janela Results.\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cp\u003E\u003Cstrong\u003ENota: \u003C\u002Fstrong\u003EGeralmente é possível confirmar o ID do recurso clicando no botão body na área de janela Results. No entanto, o Rational Requirements Composer 3.0.1 pode retornar um corpo vazio com o código de sucesso. Nesse caso, confirme o ID usando o web cliente do Rational Requirements Composer.\u003C\u002Fp\u003E\n\u003Cp\u003EEm seguida, leia o recurso de Requisito recém-criado e atualize-o.\u003C\u002Fp\u003E\n\u003Col start=\"6\" type=\"1\"\u003E\n\u003Cli\u003EEscreva estas propriedades, por exemplo, na lista de propriedades:\n\u003Cpre class=\"brush: xml; gutter: true\"\u003Edc:identifier,dc:title,dc:description\u003C\u002Fpre\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione um tipo de operação e um parâmetro de consulta \u003Cstrong\u003Eoslc.where\u003C\u002Fstrong\u003E e escreva um valor na área de janela Create, Retrieve, Update. Por exemplo,\n\u003Col start=\"1\" type=\"a\"\u003E\n\u003Cli\u003ESelecione o botão de opções \u003Cstrong\u003ER|U\u003C\u002Fstrong\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003ESelecione \u003Cstrong\u003Edcterms:identifier\u003C\u002Fstrong\u003E em oslc.where no menu suspenso\u003C\u002Fli\u003E\n\u003Cli\u003EEscreva um valor que você verificou na etapa 5. Por exemplo, \u003Ccode\u003E71\u003C\u002Fcode\u003E.\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EClique no botão \u003Cstrong\u003ER\u003C\u002Fstrong\u003E e verifique se o código de sucesso (200, por exemplo) é exibido na área de janela Results. Então você verá as propriedades na área de janela Properties.\u003C\u002Fli\u003E\n\u003Cli\u003EEscreva um valor na área de janela Properties. Por exemplo, dc:description: \u003Ccode\u003Ethis is test description\u003C\u002Fcode\u003E\u003C\u002Fli\u003E\n\u003Cli\u003EClique no botão \u003Cstrong\u003EU\u003C\u002Fstrong\u003E e verifique se o código de sucesso (200, por exemplo) é exibido na área de janela Results.\u003C\u002Fli\u003E\n\u003C\u002Fol\u003E\n\u003Cp\u003EA Figura 12 mostra uma captura de tela do recurso de Requisito recém-criado no web client do Rational Requirements Composer.\u003C\u002Fp\u003E\n\u003Cp\u003E\u003Ca href=\"https:\u002F\u002Fimasters.com.br\u002F?attachment_id=40822\" rel=\"attachment wp-att-40822\"\u003E\u003Cimg class=\"aligncenter size-full wp-image-40822\" alt=\"image012\" src=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage012.jpg\" width=\"580\" height=\"320\" srcset=\"https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage012.jpg 580w, https:\u002F\u002Fstatic.imasters.com.br\u002Fwp-content\u002Fuploads\u002F2013\u002F04\u002Fimage012-300x165.jpg 300w\" sizes=\"(max-width: 580px) 100vw, 580px\" \u002F\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n\u003Ch2\u003E\u003Ca name=\"6.Acknowledgement|outline\"\u003E\u003C\u002Fa\u003EAgradecimentos\u003C\u002Fh2\u003E\n\u003Cp\u003EO autor agradece a Masaki Wakao e Takehiko Amano pelo auxílio técnico.\u003C\u002Fp\u003E\n\u003Ch2\u003EDownload\u003C\u002Fh2\u003E\n\u003Ctable summary=\"Esta tabela contém downloads para este documento.\" width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n\u003Cth scope=\"col\"\u003EDescrição\u003C\u002Fth\u003E\n\u003Cth scope=\"col\"\u003ENome\u003C\u002Fth\u003E\n\u003Cth scope=\"col\"\u003ETamanho\u003C\u002Fth\u003E\n\u003Cth scope=\"col\"\u003EMétodo de download\u003C\u002Fth\u003E\n\u003C\u002Ftr\u003E\n\u003Ctr\u003E\n\u003Ctd scope=\"row\"\u003ESample file for this article\u003C\u002Ftd\u003E\n\u003Ctd nowrap=\"nowrap\"\u003Efireoslc_all.zip\u003C\u002Ftd\u003E\n\u003Ctd nowrap=\"nowrap\"\u003E35KB\u003C\u002Ftd\u003E\n\u003Ctd nowrap=\"nowrap\"\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fapps\u002Fdownload\u002Findex.jsp?contentid=852830&filename=fireoslc_all.zip&method=http&locale=pt_BR\"\u003EHTTP\u003C\u002Fa\u003E\u003C\u002Ftd\u003E\n\u003C\u002Ftr\u003E\n\u003C\u002Ftbody\u003E\n\u003C\u002Ftable\u003E\n\u003Ch2\u003E\u003Ca name=\"resources\"\u003E\u003C\u002Fa\u003ERecursos\u003C\u002Fh2\u003E\n\u003Ch3\u003EAprender\u003C\u002Fh3\u003E\n\u003Cul\u003E\n\u003Cli\u003ESaiba mais sobre o que é possível fazer com \u003Ca href=\"https:\u002F\u002Fjazz.net\u002Fprojects\u002Fclm\u002F\"\u003Ea solução Rational para Collaborative Lifecycle Management (CLM)\u003C\u002Fa\u003E,\n\u003Cul\u003E\n\u003Cli\u003EConsulte o website de \u003Ca href=\"http:\u002F\u002Fopen-services.net\u002F\"\u003EOSLC\u003C\u002Fa\u003E e estas páginas em especial: \u003Ca href=\"http:\u002F\u002Fopen-services.net\u002Fbin\u002Fview\u002FMain\u002FOslcCoreSpecification\"\u003EVersão 2 da Especificação Principal\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fopen-services.net\u002Fbin\u002Fview\u002FMain\u002FOSLCCoreSpecQuery\"\u003EConsulta OSLC\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003Cli\u003EWiki do \u003Ca href=\"http:\u002F\u002Fopen-services.net\u002Fwiki\u002Fchange-management\u002F\"\u003Egrupo de trabalho de Gerenciamento de Mudanças\u003C\u002Fa\u003E do OSLC\u003C\u002Fli\u003E\n\u003Cli\u003EWiki do \u003Ca href=\"http:\u002F\u002Fopen-services.net\u002Fwiki\u002Fquality-management\u002F\"\u003Egrupo de trabalho de Gerenciamento de Qualidade\u003C\u002Fa\u003E do OSLC\u003C\u002Fli\u003E\n\u003Cli\u003EWiki do \u003Ca href=\"http:\u002F\u002Fopen-services.net\u002Fwiki\u002Frequirements-management\u002F\"\u003Egrupo de trabalho de Gerenciamento de Requisitos\u003C\u002Fa\u003E do OSLC\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EPara mais informações, consulte estas páginas na Mozilla Developer Network\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FXPInstall\"\u003EXPInstall\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen\u002FXPCOM\"\u003EXPCOM\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FIntroduction_to_using_XPath_in_JavaScript\"\u003EIntrodução ao uso de XPath em JavaScript\u003C\u002Fa\u003E\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003C\u002Fli\u003E\n\u003Cli\u003EExplore a \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Frational\"\u003Eárea do software Rational no developerWorks \u003C\u002Fa\u003Epara recursos técnicos, melhores práticas e informações sobre as soluções Rational colaborativas e integradas para entrega de software e sistemas.\u003C\u002Fli\u003E\n\u003Cli\u003EFique por dentro dos \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Foffers\u002Ftechbriefings\u002Fevents.html\"\u003Eeventos técnicos e webcasts do developerWorks\u003C\u002Fa\u003E com ênfase em uma variedade de produtos IBM e assuntos do segmento de mercado de TI.\u003C\u002Fli\u003E\n\u003Cli\u003EParticipe de um \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Foffers\u002Ftechbriefings\u002F\"\u003Ebriefing ao vivo e gratuito do developerWorks Live!\u003C\u002Fa\u003E para se atualizar rapidamente sobre produtos e ferramentas IBM e tendências do segmento de mercado de TI.\u003C\u002Fli\u003E\n\u003Cli\u003EAcompanhe as \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Foffers\u002Flp\u002Fdemos\u002F\"\u003Edemos sob demanda do developerWorks\u003C\u002Fa\u003E, que abrangem desde a instalação e a configuração dos produtos para iniciantes até as funcionalidades avançadas para desenvolvedores experientes.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch3\u003EObter produtos e tecnologias\u003C\u002Fh3\u003E\n\u003Cul\u003E\n\u003Cli\u003EFaça o download da \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Frational\u002Fdownloads\u002F\"\u003Eversão gratuita de avaliação\u003C\u002Fa\u003E do software Rational.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fdownloads\u002F\"\u003EAvalie outros softwares IBM\u003C\u002Fa\u003E da forma que melhor lhe convier: faça o download da versão de avaliação, experimente-a on-line, use-a em um ambiente de nuvem ou passe algumas horas no \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fdownloads\u002Fsoasandbox\u002Findex.html\"\u003ESandbox da SOA\u003C\u002Fa\u003E para saber como implementar arquitetura orientada a serviço de maneira eficiente.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Ch3\u003EDiscutir\u003C\u002Fh3\u003E\n\u003Cul\u003E\n\u003Cli\u003EFaça parte dos \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fforums\u002Fdw_rforums.jspa\"\u003Efóruns do software Rational\u003C\u002Fa\u003E para tirar dúvidas e participar das discussões.\u003C\u002Fli\u003E\n\u003Cli\u003EFaça e responda a perguntas, e aumente seus conhecimentos participando dos \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fforums\u002Fdw_rforums.jspa\"\u003Efóruns\u003C\u002Fa\u003E, \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Frational\u002Fcommunity\u002Fcafe\"\u003Ecafés\u003C\u002Fa\u003Ee \u003Ca href=\"https:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fmydeveloperworks\u002Fwikis\u002Fhome?lang=en_US#\u002Fwiki\u002FRational%20Wiki%20Central\u002Fpage\u002FRational%20Wiki\"\u003Ewikis Rational\u003C\u002Fa\u003E.\u003C\u002Fli\u003E\n\u003Cli\u003EFaça parte da \u003Ca href=\"http:\u002F\u002Fibm.co\u002Frationalcommunity\"\u003Ecomunidade Rational\u003C\u002Fa\u003E para compartilhar seu conhecimento no software Rational e ficar conectado aos seus colegas.\u003C\u002Fli\u003E\n\u003Cli\u003E\u003Ca href=\"http:\u002F\u002Fwww-01.ibm.com\u002Fsoftware\u002Frational\u002Freview\u002F\"\u003EClassifique ou avalie o software\u003C\u002Fa\u003E Rational. É rápido e fácil.\u003C\u002Fli\u003E\n\u003C\u002Ful\u003E\n\u003Cp\u003E***\u003C\u002Fp\u003E\n\u003Cp\u003ESobre o autor: Ken Kumagai (theken) é staff software engineer na IBM no Japão. Ele é desenvolvedor na equipe do IBM Rational ClearCase. Um de seus interesses atuais é melhorar a usabilidade das ferramentas de desenvolvimento de software. Em seu tempo livre, ele gosta de ler livros no Starbucks mais próximo.\u003C\u002Fp\u003E\n\u003Cp\u003E***\u003C\u002Fp\u003E\n\u003Cp\u003EArtigo original está disponível em: \u003Ca href=\"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Frational\u002Flibrary\u002Ffirefox-add-on-oslc-servers\u002Findex.html\"\u003Ehttp:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002Frational\u002Flibrary\u002Ffirefox-add-on-oslc-servers\u002Findex.html\u003C\u002Fa\u003E\u003C\u002Fp\u003E\n","excerpt":"\u003Cp\u003EVeja os desafios de criar um aplicativo cliente para acessar servidores OSLC e explica como superá-los com criação de complemento do Firefox\u003C\u002Fp\u003E\n","link":"https:\u002F\u002Fimasters.com.br\u002Fdevsecops\u002Fcrie-um-complemento-do-firefox-para-acessar-servidores-oslc","date":"18 abr, 2013","thumbnail":"","externalMention":null,"author":{"id":421,"thumbnail":"https:\u002F\u002Fsecure.gravatar.com\u002Favatar\u002Fbe5bc6f39606ac453a07bd2eb7ab21af?s=96&d=mm&r=g","name":"developerWorks Brasil","description":"é o portal de tecnologia da IBM para profissionais de TI de todo o mundo. Colabore, aprenda a criar aplicativos inovadores e compreenda tecnologias avançadas. Acesse mais artigos e tutoriais em www.ibm.com\u002Fdeveloperworks\u002Fbr","slug":"developerworks_brasil","url":"https:\u002F\u002Fimasters.com.br\u002Fperfil\u002Fdeveloperworks_brasil","registered":"2010-07-07 17:06:45","social":{"linkedin":null,"youtube":null,"facebook":"","twitter":"https:\u002F\u002Ftwitter.com\u002Fsoudw","instagram":null,"github":null,"url":"http:\u002F\u002Fwww.ibm.com\u002Fdeveloperworks\u002Fbr\u002F","mail":"dwbr@br.ibm.com"},"articles_count":217,"views_count":4709798,"certifications":null,"conquests":null,"office":null},"categories":[{"title":"DevSecOps","slug":"devsecops","id":1,"link":"https:\u002F\u002Fimasters.com.br\u002Fdevsecops"},{"title":"Redes e Servidores","slug":"redes-e-servidores","id":7270,"link":"https:\u002F\u002Fimasters.com.br\u002Fredes-e-servidores"},{"title":"Software Livre","slug":"software-livre","id":7241,"link":"https:\u002F\u002Fimasters.com.br\u002Fsoftware-livre"}],"tags":[{"title":"firefox","slug":"firefox","id":1524,"link":"https:\u002F\u002Fimasters.com.br\u002Ffirefox"},{"title":"oslc","slug":"oslc","id":1523,"link":"https:\u002F\u002Fimasters.com.br\u002Foslc"},{"title":"redes","slug":"redes","id":207,"link":"https:\u002F\u002Fimasters.com.br\u002Fredes"},{"title":"servidor","slug":"servidor","id":943,"link":"https:\u002F\u002Fimasters.com.br\u002Fservidor"},{"title":"xml","slug":"xml-2","id":863,"link":"https:\u002F\u002Fimasters.com.br\u002Fxml-2"}],"seo":{"open_graph":{"title":"Crie um Complemento do Firefox para Acessar Servidores OSLC - iMasters","description":"Veja os desafios de criar um aplicativo cliente para acessar servidores OSLC e explica como superá-los com criação de complemento do Firefox","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":false,"modified_time":"2018-05-24T13:02:55-03:00","published_time":"2013-04-18T09:00:39-03:00"},"twitter":{"title":"Crie um Complemento do Firefox para Acessar Servidores OSLC - iMasters","description":"Veja os desafios de criar um aplicativo cliente para acessar servidores OSLC e explica como superá-los com criação de complemento do Firefox","type":"summary_large_image","image":false}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fdevsecops\u002Fcrie-um-complemento-do-firefox-para-acessar-servidores-oslc","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fdevsecops\u002Fcrie-um-complemento-do-firefox-para-acessar-servidores-oslc","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fdevsecops\u002Fcrie-um-complemento-do-firefox-para-acessar-servidores-oslc"},"type":"post"}]},"categories":[{"title":"Back-End","slug":"back-end","id":7158,"link":"https:\u002F\u002Fimasters.com.br\u002Fback-end"},{"title":"Banco de Dados","slug":"banco-de-dados","id":7209,"link":"https:\u002F\u002Fimasters.com.br\u002Fbanco-de-dados"},{"title":"Data","slug":"data","id":16,"link":"https:\u002F\u002Fimasters.com.br\u002Fdata"},{"title":"MongoDB","slug":"mongodb","id":7217,"link":"https:\u002F\u002Fimasters.com.br\u002Fmongodb"}],"tags":[{"title":"Django","slug":"django","id":7294,"link":"https:\u002F\u002Fimasters.com.br\u002Fdjango"}],"seo":{"open_graph":{"title":"Veja como usar o MongoDB com Django - iMasters - We are Developers","description":"","type":"article","locale":"pt_BR","site_name":"iMasters - We are Developers","image":false,"modified_time":"2018-05-23T23:25:44-03:00","published_time":"2012-03-19T09:45:00-03:00"},"twitter":{"title":"Veja como usar o MongoDB com Django - iMasters - We are Developers","description":"","type":"summary_large_image","image":false}},"articleSocial":{"facebook":"https:\u002F\u002Fwww.facebook.com\u002Fsharer?u=https:\u002F\u002Fimasters.com.br\u002Fback-end\u002Fveja-como-usar-o-mongodb-com-django","twitter":"https:\u002F\u002Ftwitter.com\u002Fshare?url=https:\u002F\u002Fimasters.com.br\u002Fback-end\u002Fveja-como-usar-o-mongodb-com-django","linkedin":"https:\u002F\u002Fwww.linkedin.com\u002FshareArticle?url=https:\u002F\u002Fimasters.com.br\u002Fback-end\u002Fveja-como-usar-o-mongodb-com-django"},"type":"post","articleViews":100}},"author":{"success":false,"isFetchingPagination":false,"maxPages":0,"page":1,"data":{}},"category":{"success":false,"data":{}},"categoryArticles":{"success":false,"isFetchingPagination":false,"maxPages":0,"page":1,"data":{}},"categoryMostRead":{"success":false,"data":{}},"home":{"success":false,"featured":[],"options":{"homeProducts":[]},"allCategories":{},"featuredArticles":{},"magazines":{"data":[]},"tv":{},"forums":[],"authorsRanking":{},"events":{},"certificatedUsers":[],"news":[]},"page":{"success":false,"data":{}},"magazine":{"success":false,"magazines":[]},"schedule":{"success":false,"data":{}},"searchResult":{"success":false,"totalPosts":0,"totalPage":0,"currentPage":1,"posts":[],"term":"","orderBy":"recents","currentFilter":"articles","isLoading":true,"isLoadingPagination":false},"singleNews":{"success":false,"data":{}},"listNews":{"success":false,"isFetchingPagination":false,"maxPages":0,"page":1,"data":[]},"sponsors":{"success":true,"data":[]},"header":{"success":true,"menus":{"main":[{"ID":138755,"order":1,"parent":0,"title":"Back-End","url":"https:\u002F\u002Fimasters.com.br\u002Fback-end","attr":"package","target":"","classes":"package","xfn":"","description":"Tecnologias utilizadas no backend da aplicação","object_id":7158,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":138756,"order":2,"parent":0,"title":"Mobile","url":"https:\u002F\u002Fimasters.com.br\u002Fmobile","attr":"package","target":"","classes":"package","xfn":"","description":"Conteúdos sobre Desenvolvimento Mobile nas plataformas iOS (iPhone e iPad) e Android.","object_id":4255,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":139476,"order":3,"parent":0,"title":"Front End","url":"https:\u002F\u002Fimasters.com.br\u002Ffront-end","attr":"package","target":"","classes":"package","xfn":"","description":"Conteúdos sobre HTML5, CSS3, Javascript, JQuery, Web Standards e SEO.","object_id":7304,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":138764,"order":4,"parent":0,"title":"DevSecOps","url":"https:\u002F\u002Fimasters.com.br\u002Fdevsecops","attr":"package","target":"","classes":"package","xfn":"","description":"","object_id":1,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":139204,"order":5,"parent":0,"title":"Design & UX","url":"https:\u002F\u002Fimasters.com.br\u002Fdesign-ux","attr":"package","target":"","classes":"package","xfn":"","description":"Conteúdos sobre User Experience, Arquitetura de Informação, Usabilidade, Acessibilidade, Design Responsivo, Teoria do Design e Photoshop.","object_id":7252,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":138759,"order":6,"parent":0,"title":"Data","url":"https:\u002F\u002Fimasters.com.br\u002Fdata","attr":"package","target":"","classes":"package","xfn":"","description":"Conteúdos sobre Banco de Dados Oracle, MySQL, SQL Server, MongoDB, DB2 e Postgre SQL, sobre BI e análise de dados.","object_id":16,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]},{"ID":138758,"order":7,"parent":0,"title":"APIs e Microsserviços","url":"https:\u002F\u002Fimasters.com.br\u002Fapis-microsservicos","attr":"package","target":"","classes":"package","xfn":"","description":"Dicas e tutoriais sobre APIs públicas como Facebook, Twitter, PayPal, Buscapé, Google, etc e arquitetura de microsserviços, com códigos de exemplo, vídeos, cursos.","object_id":4257,"object":"category","type":"taxonomy","type_label":"Categoria","children":[]}],"secondary":[{"ID":138752,"order":1,"parent":0,"title":"Fórum iMasters","url":"https:\u002F\u002Fforum.imasters.com.br\u002F","attr":"","target":"_blank","classes":"","xfn":"","description":"","object_id":138752,"object":"custom","type":"custom","type_label":"Link personalizado","children":[]},{"ID":139067,"order":2,"parent":0,"title":"Portal E-Commerce Brasil","url":"http:\u002F\u002Fwww.ecommercebrasil.com.br","attr":"","target":"","classes":"","xfn":"","description":"","object_id":139067,"object":"custom","type":"custom","type_label":"Link personalizado","children":[]},{"ID":156289,"order":3,"parent":0,"title":"iMasters Business","url":"http:\u002F\u002Fbusiness.imasters.com.br","attr":"","target":"","classes":"","xfn":"","description":"","object_id":156289,"object":"custom","type":"custom","type_label":"Link personalizado","children":[]}]}},"webinar":{"success":false,"data":{}},"webinars":{"success":false,"isFetchingPagination":false,"maxPages":0,"page":1,"data":{"next":[],"prev":[]}},"tv":{"sectionNameLeft":{"small":"Vídeos","large":"iMasters TV"},"itemsLeft":[{"text":"Em Destaque","slug":"recents"},{"text":"Mais Vistos","slug":"most-viewed"}],"sectionNameRight":{"small":"","large":""},"itemsRight":[{"text":"Mais Recentes","slug":"recents"},{"text":"7Masters","slug":"7-masters"},{"text":"PHP Experience","slug":"php-experience"},{"text":"Android DevConference","slug":"android-devconference"},{"text":"Busca","slug":"search"}],"currentVideo":"recents","currentListVideo":"recents"}} window.__SERVER_VARS__ = {"applicationRestUrl":"https:\u002F\u002Fadmin.imasters.com.br\u002Fwp-json","applicationBaseUrl":"https:\u002F\u002Fadmin.imasters.com.br"} , 'blog.blogapp.views.index'),
url(r'^update/', 'blog.blogapp.views.update'),
url(r'^delete/', 'blog.blogapp.views.delete'),
)

Lista 16. Mapeamentos de URL para índice, atualização e exclusão.

Observe que não é necessário executar o comando syncdb do Django. Para integrar o MongoDB ao seu aplicativo, é necessário o MongoEngine. No arquivo models.py do diretório blogapp, inclua o código mostrado na Listagem 17.

from mongoengine import *
from blog.settings import DBNAME

connect(DBNAME)

class Post(Document):
title = StringField(max_length=120, required=True)
content = StringField(max_length=500, required=True)
last_update = DateTimeField(required=True)

Lista 17. Incluindo MongoEngine na camada de dados.

O nome do banco de dados é obtido a partir do arquivo de definições para separar os interesses. Cada postagem do Blog contém três campos obrigatórios: title, content e o last_update. Se você comparar e contrastar esta listagem com o que você faria normalmente no Django, a diferença não será enorme. Em vez de ter uma classe que herda do django.db.models.Model, esta listagem usa a classe mongoengine.Document em seu lugar. A diferença entre os tipos de dados não será detalhada aqui, mas sinta-se a vontade para verificar os documentos do MongoEngine (consulte “Recursos”).

Tabela 2 lista os tipos de campo MongoEngine e mostra o tipo de campo Django ORM equivalente, se houver.

Tipo de campo MongoEngine Django ORM equivalente
StringField CharField
URLField URLField
EmailField EmailField
IntField IntegerField
FloatField FloatField
DecimalField DecimalField
BooleanField BooleanField
DateTimeField DateTimeField
EmbeddedDocumentField Nenhum
DictField Nenhum
ListField Nenhum
SortedListField Nenhum
BinaryField Nenhum
ObjectIdField Nenhum
FileField FileField

Tablela 2. Tipos de campo MongoEngine e Django ORM equivalentes.

Finalmente, é possível configurar as suas visualizações. Seguem três métodos de visualização: index, update e o delete. Para executar a ação desejada, deve ser feita uma solicitação de postagem para a URL específica. Por exemplo, para atualizar um documento deve ser feita uma postagem para localhost:8000/update. Executar uma solicitação http ‘GET’ não salvará, atualizará e assim por diante. As novas postagens do blog são inseridas a partir da visualização de índice. Listagem 18 mostra as implementações para as visualizações de índice, atualização e exclusão.

    if request.method == 'POST':
# save new post
title = request.POST['title']
content = request.POST['content']

post = Post(title=title)
post.last_update = datetime.datetime.now()
post.content = content
post.save()

# Get all posts from DB
posts = Post.objects
return render_to_response('index.html', {'Posts': posts},
context_instance=RequestContext(request))


def update(request):
id = eval("request." + request.method + "['id']")
post = Post.objects(id=id)[0]

if request.method == 'POST':
# update field values and save to mongo
post.title = request.POST['title']
post.last_update = datetime.datetime.now()
post.content = request.POST['content']
post.save()
template = 'index.html'
params = {'Posts': Post.objects}

elif request.method == 'GET':
template = 'update.html'
params = {'post':post}

return render_to_response(template, params, context_instance=RequestContext(request))


def delete(request):
id = eval("request." + request.method + "['id']")

if request.method == 'POST':
post = Post.objects(id=id)[0]
post.delete()
template = 'index.html'
params = {'Posts': Post.objects}
elif request.method == 'GET':
template = 'delete.html'
params = { 'id': id }

return render_to_response(template, params, context_instance=RequestContext(request))

Lista 18. As visualizações do Django.

Você deve ter notado as instruções eval usadas para recuperar os IDs do documento. Isso é usado para evitar a necessidade de gravar a instrução if mostrada na Listagem 19.

    if request.method == 'POST':
id = request.POST['id']
elif request.method == 'GET':
id = request.GET['id']

Lista 19. Forma alternativa de recuperar o ID do documento.

Também é possível escrever dessa maneira. Isso é tudo o que preciso para ter um blog simples ativo e funcionando. Obviamente, faltam muitos componentes para um produto final, tais como usuários, um login, tags e assim por diante.

Conclusão

Como você pode ver, não há realmente muito para chamar o MongoDB a partir do Django. Neste artigo, apresentei rapidamente o MongoDB e expliquei como acessá-lo e manipular suas coleções e documentos a partir do Python por meio do wrapper PyMongo e o mapeador de objeto para documento MongoEngine. Finalmente, ofereci uma rápida demonstração de como criar um formulário CRUD básico usando o Django. Embora esta seja apenas a primeira etapa, espero que você entenda agora como aplicar esta configuração em seus próprios projetos.

Download

Descrição Nome Tamanho Método de download
Sample Django application with MongoEngine blongo.zip 12KB HTTP

Recursos

Aprender

Obter produtos e tecnologias

Discutir

***

Sobre o autor: Cesar Otero é consultor Java e Python freelance. Ele é formado em engenharia elétrica com especialização em matemática.

De 0 a 10, o quanto você recomendaria este artigo para um amigo?

developerWorks Brasil

edit217 Artigo(s)

é o portal de tecnologia da IBM para profissionais de TI de todo o mundo. Colabore, aprenda a criar aplicativos inovadores e compreenda tecnologias avançadas. Acesse mais artigos e tutoriais em www.ibm.com/developerworks/br