Arquivo do mês: junho 2012

Proofreading Writing in WordPress

Links relacionados:

Anúncios

Adaptive Programming – Part 8


Início
Continuação da parte 7.

Adaptive Programming

CRUD Generation

Antes de entrarmos no tópico bypassing queremos gerar os códigos CRUD necessários para manter as listas internas a cada objeto. O código abaixo gera CRUD para as classes num determinado pacote. Para isso execute código similar ao seguinte:

A execução do script acima gera o CRUD. Abaixo mostramos o CRUD gerado na classe Departamento:

Departamento>>#addDivisao: anElement
		"Generated code"
		|toAdd|
		toAdd := self getDivisaoByNome: (anElement perform: anElement class idSelector).
		toAdd ifNotNil: [:found|self error: found asString, 'already exists'].
		^ divisoes := divisoes add: anElement

Departamento>>#getDivisaoByNome: anId
		"Generated code"
		|selecteds|
		selecteds := divisoes select: [:each| (each perform: #nome) = anId].
		selecteds ifEmpty: [^ nil].
			^ selecteds first

Departamento>>#deleteDivisaoByNome: anId
		"Generated code"
		|toDelete|
		toDelete := self getDivisaoByNome: anId.
		^ divisoes := divisoes remove: toDelete

Departamento>>#addEmpregado: anElement
		"Generated code"
		|toAdd|
		toAdd := self getEmpregadoByMatricula: (anElement perform: anElement class idSelector).
		toAdd ifNotNil: [:found|self error: found asString, 'already exists'].
		^ empregados := empregados add: anElement

Departamento>>#getEmpregadoByMatricula: anId
		"Generated code"
		|selecteds|
		selecteds := empregados select: [:each| (each perform: #matricula) = anId].
		selecteds ifEmpty: [^ nil].
			^ selecteds first

Departamento>>#deleteEmpregadoByMatricula: anId
		"Generated code"
		|toDelete|
		toDelete := self getEmpregadoByMatricula: anId.
		^ empregados := empregados remove: toDelete

Bypassing

Vamos agora introduzir o atributo #gerente nas classes Departamento e Divisao. Vários métodos que coletam empregados ou seus atributos vão acusar contagem duplicada. A razão disso é que o empregado que é gerente é alcançado por dois caminhos: através do atributo #gerente da classe Departamento e via lista de empregados do departamento. A operação #todosEmpregados2 corrige o problema usando um Set. Veja abaixo:

Uma outra forma de evitar o caminho até o gerente do departamento é o bypassing. Essa forma é ilustrada no código abaixo e representa uma nova funcionalidade na classe Operation.

O método #visit foi modificado para incluir bypassing:

Os file-outs até agora seguem abaixo:

Object subclass: #AdaptiveBase
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!AdaptiveBase methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:32'!
accept: aVisitor
	aVisitor visit: self! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

AdaptiveBase class
	instanceVariableNames: ''!

Object subclass: #Visitor
	instanceVariableNames: 'result'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Visitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 08:19'!
result
	^ result! !

!Visitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 08:19'!
result: anObject
	result := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Visitor class
	instanceVariableNames: ''!

!Visitor class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 18:48'!
result: anObject
	^ self new result: anObject.! !

Object subclass: #Operation
	instanceVariableNames: 'result sourceClass targetClass wrappers visitor signatureSymbol prefix sufix bypassing'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:38'!
addWrapperTo: aClass withPrefix: aBlockClosure
	wrappers at: aClass name asSymbol put: (Wrapper prefix: aBlockClosure) ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 21:11'!
addWrapperTo: aClass withSufix: aBlockClosure
	wrappers at: aClass name asSymbol put: (Wrapper sufix: aBlockClosure) ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 21:35'!
bypassing
	^ bypassing! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 21:28'!
bypassing: aByteSymbol
	bypassing:=aByteSymbol! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 06:11'!
compile
	self compileEntryPoint! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 06:11'!
compileEntryPoint
	sourceClass compile: self createEntryPointSource! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:03'!
createEntryPointSource
	| sourceCode |
	sourceCode := '
	"Generated code"
	| visitor |
	visitor := (Operation atSignature: #) visitor.
	visitor arguments: thisContext arguments.
	visitor visit: self.
	^ visitor result value'.
	^ sourceCode expandMacrosWith: (self signatureWithArgumentsFrom: signatureSymbol) with: signatureSymbol

! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:47'!
hasWrapperInClass: aClass
	^ wrappers isEmpty not and: [wrappers includesKey: aClass] ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:02'!
initialize
	wrappers := Dictionary new.
	visitor := OperationVisitor forOperation: self! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 11:43'!
prefix
	^ prefix! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 11:39'!
prefix: aBlockClosure
	prefix := aBlockClosure! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:35'!
prefixAt: aClassName
	^ (wrappers at: aClassName) prefix! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 12:44'!
result
	^ result! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 06:51'!
result: anObject
	result := anObject ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 20:52'!
signature: aByteSymbol
	signatureSymbol := aByteSymbol ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 21:51'!
signatureWithArgumentsFrom: aByteSymbol
	| stream count keywords |
	stream := WriteStream on: ''.
	count := 1.
	keywords := aByteSymbol keywords.

	(keywords size = 1 and: [(keywords first includes: $:) not] )ifTrue: [^ keywords first].

	self flag: #fix. "String concatenation instead os streams"
	keywords do: [:keyword|
		stream nextPutAll: keyword, ' anObject', count asString.
		count := count + 1
		].
	^ stream contents! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 06:52'!
sourceClass: aClass
	sourceClass := aClass! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:34'!
sufix
	^ sufix! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:03'!
sufix: aBlockClosure
	sufix := aBlockClosure! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:36'!
sufixAt: aClassName
	^ (wrappers at: aClassName) sufix! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 06:53'!
targetClass: aClass
	targetClass := aClass! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:03'!
visitor
	^visitor ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 18:42'!
wrapperFor: aWrappedClassName
	^ wrappers at: aWrappedClassName ifAbsent: [^ nil]! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 07:18'!
wrapperTo: aClass with: aWraperBlock
	| wrapper |
	wrapper := wrappers at: aClass name ifAbsent: [
		wrappers at: aClass name put: Wrapper new.
	]..
	aWraperBlock value: wrapper ! !

!Operation methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/25/2012 20:52'!
signature
	^ signatureSymbol! !

!Operation methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/27/2012 20:20'!
targetClass
	^ targetClass! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Operation class
	instanceVariableNames: 'operations'!

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:45'!
atSignature: aSignature
	^ operations at: aSignature! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:54'!
initialize
	"
	self initialize
	"
	operations := Dictionary new! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:58'!
registerOperation: anOperation
	operations at: anOperation signature put: anOperation! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 21:20'!
signature: aByteSymbol result: anOrderedCollection from: anEmpresaClass bypassing: aByteSymbol4 to: anEmpregadoClass
	^ self signature: aByteSymbol result: anOrderedCollection from: anEmpresaClass bypassing: aByteSymbol4 to: anEmpregadoClass  prefix: nil sufix: nil ! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 21:22'!
signature: aByteSymbol result: anObject from: aSourceClass bypassing: aByteSymbol4 to: aTargetClass  prefix: prefixBlock sufix: sufixBlock
	| operation |
	operation := self new
		signature: aByteSymbol ;
		result: anObject ;
		sourceClass: aSourceClass ;
		bypassing: aByteSymbol4;
		targetClass: aTargetClass ;
		prefix: prefixBlock;
		sufix: sufixBlock .

	self registerOperation: operation.
	^ operation! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 11:37'!
signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass
	^ self signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass prefix: nil sufix: nil! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 11:38'!
signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass prefix: aBlockClosure
	^ self signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass prefix: aBlockClosure sufix: nil! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 21:39'!
signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass prefix: prefixBlock sufix: sufixBlock
	^ self signature: aByteSymbol result: anObject from: aSourceClass bypassing: nil to: aTargetClass  prefix: prefixBlock sufix: sufixBlock ! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 19:00'!
signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass sufix: aBlockClosure
	^ self signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass prefix: nil sufix: aBlockClosure! !

Visitor subclass: #OperationVisitor
	instanceVariableNames: 'operation arguments'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 23:12'!
arguments
	^ arguments! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 21:35'!
bypassing
	^ operation bypassing! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:40'!
hasWrapperIn: aClass
	^ operation hasWrapperInClass: aClass! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:12'!
operation: anOperation
	operation := anOperation ! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 11:43'!
prefix
	^ operation prefix! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 12:43'!
result
	^ operation result! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 17:23'!
result: anObject
	operation result: anObject! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:33'!
sufix
	^ operation sufix! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 20:19'!
targetClass
	^ operation targetClass! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 21:34'!
visit: visitedObject
	"Prefix processing"
	| wrapper |
	self prefix
		ifNotNil: [:block | block cull: self cull: visitedObject].
	(wrapper := self wrapperFor: visitedObject class name)
		ifNotNil: [wrapper prefix
				ifNotNil: [:prefix | prefix cull: self cull: visitedObject]].

	"Traversal"
	visitedObject class = self targetClass
		ifFalse: [
			visitedObject class allInstVarNames
				do: [:varName |
					varName = #elementClass
						ifFalse: [
							(visitedObject respondsTo: varName asSymbol)
								ifTrue: [
									varName = self bypassing ifFalse: [
									(visitedObject perform: varName asSymbol)
										ifNotNil: [:varValue |
											self visit: varValue]
	]]]]].

	"Sufix processing"
	wrapper
		ifNotNil: [wrapper sufix
				ifNotNil: [:sufix | sufix cull: self cull: visitedObject]].
	self sufix
		ifNotNil: [:block | block cull: self cull: visitedObject]! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 18:38'!
wrapperFor: aWrappedClassName
	^ operation wrapperFor: aWrappedClassName
! !

!OperationVisitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/26/2012 06:01'!
arguments: anObject
	arguments := anObject! !

!OperationVisitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/25/2012 12:40'!
operation
	^ operation! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

OperationVisitor class
	instanceVariableNames: 'operation'!

!OperationVisitor class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:11'!
forOperation: anOperation
	^ self new operation: anOperation ! !

Object subclass: #Wrapper
	instanceVariableNames: 'prefix sufix'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Wrapper methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:39'!
prefix
	^ prefix! !

!Wrapper methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:39'!
prefix: aBlockClosure
	prefix := aBlockClosure ! !

!Wrapper methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:40'!
sufix
	^ sufix! !

!Wrapper methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/28/2012 07:50'!
sufix: anObject
	sufix := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Wrapper class
	instanceVariableNames: 'sufix'!

!Wrapper class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:39'!
prefix: aBlockClosure
	^self new
		prefix: aBlockClosure ! !

!Wrapper class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/28/2012 07:42'!
sufix: aBlockClosure
	sufix := aBlockClosure ! !

AdaptiveBase subclass: #List
	instanceVariableNames: 'elementClass'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!List methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 17:47'!
add: anElement
	(anElement isKindOf: elementClass) ifFalse: [self error: 'Element must be of class ', elementClass name].
	^ NonEmptyList head: anElement tail: self! !

!List methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 22:02'!
elementClass
	^ elementClass! !

!List methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 07:32'!
elementClass: aClass
	elementClass := aClass! !

!List methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 18:38'!
ifEmpty: aBlock
	^ self isEmpty
		ifTrue: [ ^aBlock value ]
		ifFalse: [ self ]! !

Object subclass: #Accumulator
	instanceVariableNames: 'value'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Accumulator methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 22:15'!
value
	^ value! !

!Accumulator methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 22:04'!
value: anObject
	value := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Accumulator class
	instanceVariableNames: ''!

!Accumulator class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:06'!
value: aSmallInteger
	^self new value: aSmallInteger ! !

Object subclass: #CRUDGenerator
	instanceVariableNames: 'packageName'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!CRUDGenerator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 07:16'!
generate
	| sample |
	(SystemNavigation default allClassesInPackageNamed: packageName)
		do: [:class|
			sample := class new.
			self generateCRUDInSample: sample
		]! !

!CRUDGenerator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 18:34'!
generateAddSourceWithList: aList collectionVaName: aCollectionVarName idSelector: anIdSelector
	^ 'add: anElement
	"Generated code"
	|toAdd|
	toAdd := self getBy: (anElement perform: anElement class idSelector).
	toAdd ifNotNil: [:found|self error: found asString, ''already exists''].
	^  :=  add: anElement'
	expandMacrosWith: aList elementClass name with: aCollectionVarName  with: anIdSelector capitalized ! !

!CRUDGenerator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 18:35'!
generateCRUDInClass: aClass withCollection: aList collectionVarName: aCollectionVarName idSelector: anIdSelector
	aClass compile: (self generateAddSourceWithList: aList collectionVaName: aCollectionVarName idSelector: anIdSelector).
	aClass compile: (self generateGetSourceWithList: aList collectionVarName: aCollectionVarName idSelector: anIdSelector).
	aClass
		compile: (self generateDeleteSourceWithList: aList collectionVarName: aCollectionVarName idSelector: anIdSelector)! !

!CRUDGenerator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:01'!
generateCRUDInSample: aSampleObject
	aSampleObject class allInstVarNames
				do: [:var |
				(aSampleObject respondsTo: var asSymbol)
					ifTrue: [(aSampleObject perform: var asSymbol)
						ifNotNil: [:varValue |
							(varValue isKindOf: List) ifTrue: [
								self generateCRUDInClass: aSampleObject class withCollection: varValue collectionVarName: var idSelector: varValue elementClass idSelector
								]
						]
				]
		].! !

!CRUDGenerator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 06:44'!
generateDeleteSourceWithList: aList collectionVarName: aCollectionVarName idSelector: anIdSelector
	^ 'deleteBy: anId
	"Generated code"
	|toDelete|
	toDelete := self getBy: anId.
	^  :=  remove: toDelete'
	expandMacrosWith: aList elementClass name with: aCollectionVarName with: anIdSelector capitalized ! !

!CRUDGenerator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 06:55'!
generateGetSourceWithList: aList collectionVarName: aCollectionVarName idSelector: anIdSelector
	^ 'getBy: anId
	"Generated code"
	|selecteds|
	selecteds :=  select: [:each| (each perform: #) = anId].
	selecteds ifEmpty: [^ nil].
		^ selecteds first'
	expandMacrosWith: aList elementClass name with: aCollectionVarName with: anIdSelector with: anIdSelector capitalized ! !

!CRUDGenerator methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 07:14'!
packageName: aByteString
	packageName := aByteString
		! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

CRUDGenerator class
	instanceVariableNames: ''!

!CRUDGenerator class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 07:13'!
packageName: aByteString
	^ self new
		packageName: aByteString ! !

List subclass: #EmptyList
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 22:18'!
append: anElement
	^ NonEmptyList head: anElement tail: self! !

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 19:39'!
do: aBlockClosure ! !

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 18:39'!
isEmpty
	^ true! !

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:31'!
select: aBlockClosure ! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

EmptyList class
	instanceVariableNames: ''!

!EmptyList class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 22:22'!
newWithElementClass: anElementClass
	^ self new
		elementClass: anElementClass! !

List subclass: #NonEmptyList
	instanceVariableNames: 'head tail'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 22:18'!
append: anElement
	^ NonEmptyList head: head tail: (tail append: anElement)! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:13'!
do: aBlockClosure
	aBlockClosure value: head.
	tail do: aBlockClosure ! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 16:13'!
first
	^ head! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:13'!
head
	^ head! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:14'!
head: anElement
	head := anElement! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 18:39'!
isEmpty
	^ false! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 16:24'!
remove: anObject
	head = anObject ifTrue: [^ tail].
	^ NonEmpty head: head tail: (tail remove: anObject)! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 06:52'!
select: aBlockClosure
	| newCollection |
	newCollection := EmptyList newWithElementClass: elementClass. .
	self do: [:each | (aBlockClosure value: each) ifTrue: [newCollection := newCollection add: each]].
	^newCollection! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:19'!
tail: anEmptyList
	tail := anEmptyList! !

!NonEmptyList methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/25/2012 16:58'!
tail
	^ tail! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

NonEmptyList class
	instanceVariableNames: ''!

!NonEmptyList class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 22:27'!
head: anElement tail: aList
	^ self new
		head: anElement;
		tail: aList;
		elementClass: aList elementClass! !
Operation initialize!

 

AdaptiveBase subclass: #Empregado
	instanceVariableNames: 'matricula nome salario'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples-Model'!

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:31'!
matricula
	^ matricula! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:31'!
matricula: anObject
	matricula := anObject! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
nome
	^ nome! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
nome: anObject
	nome := anObject! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
salario
	^ salario! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
salario: anObject
	salario := anObject! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:10'!
acceptVisitor: aVisitor
	aVisitor visitEmpregado: self! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:29'!
nomesEmpregados
	| result |
	result := OrderedCollection new.
	result add: self nome.
	^ result! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 07:06'!
numeroEmpregados
	| result |
	result := 1.
	^ result! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 10:00'!
printOn: aStream
	super printOn: aStream.
	aStream nextPutAll: ': ', nome! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:49'!
todosEmpregados
	| result |
	result := OrderedCollection new.
	result add: self.
	^ result! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Empregado class
	instanceVariableNames: 'proximaMatricula'!

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 15:56'!
idSelector
	^ #matricula! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:56'!
initialize
	"
	self initialize
	"
	self reinicieMatriculas! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:32'!
matricula: anInteger nome: aString salario: aFloat
	^ self new
	      matricula: anInteger;
		nome: aString;
		salario: aFloat ! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:28'!
nome: aString salario: aFloat
	^ self new
		nome: aString;
		salario: aFloat ! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:37'!
proximaMatricula
	proximaMatricula := proximaMatricula + 1.
	^ proximaMatricula! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:55'!
reinicieMatriculas
	proximaMatricula := 0..! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 21:26'!
ultimaMatricula
	^ proximaMatricula! !

AdaptiveBase subclass: #Divisao
	instanceVariableNames: 'nome empregados gerente'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples-Model'!

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 16:41'!
a CRUDGenerator! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:10'!
acceptVisitor: aVisitor
	aVisitor visitDivisao: self! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
addEmpregado: anElement
		"Generated code"
		|toAdd|
		toAdd := self getEmpregadoByMatricula: (anElement perform: anElement class idSelector).
		toAdd ifNotNil: [:found|self error: found asString, 'already exists'].
		^ empregados := empregados add: anElement! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
deleteEmpregadoByMatricula: anId
		"Generated code"
		|toDelete|
		toDelete := self getEmpregadoByMatricula: anId.
		^ empregados := empregados remove: toDelete! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
getEmpregadoByMatricula: anId
		"Generated code"
		|selecteds|
		selecteds := empregados select: [:each| (each perform: #matricula) = anId].
		selecteds ifEmpty: [^ nil].
			^ selecteds first! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 17:39'!
initialize
	empregados := EmptyList  newWithElementClass: Empregado
! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
listarEmpregados
	self empregados
		do: [ :empregado |
			Transcript
				cr;
				tab;
				show: empregado matricula;
				space;
				show: empregado nome;
				space;
				show: empregado salario ]! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:30'!
nomesEmpregados
	| result |
	result := OrderedCollection new.
	empregados do: [:each| result addAll: each nomesEmpregados].
	^ result! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 07:04'!
numeroEmpregados
	| result |
	result := 0.
	empregados do: [:each| result := result + each numeroEmpregados].
	^ result! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 09:59'!
printOn: aStream
	super printOn: aStream.
	aStream nextPutAll: ': ', nome! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:48'!
todosEmpregados
	| result |
	result := OrderedCollection new.
	empregados do: [:each| result addAll: each todosEmpregados].
	^ result! !

!Divisao methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
empregados
	^ empregados! !

!Divisao methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/29/2012 11:23'!
gerente
	^ gerente! !

!Divisao methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/29/2012 11:23'!
gerente: anObject
	gerente := anObject! !

!Divisao methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
nome
	^ nome! !

!Divisao methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
nome: anObject
	nome := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Divisao class
	instanceVariableNames: ''!

!Divisao class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 16:37'!
idSelector
	^#nome! !

!Divisao class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
nome: aString
	^ self new nome: aString! !

AdaptiveBase subclass: #Empresa
	instanceVariableNames: 'nome departamentos'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples-Model'!

!Empresa methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 10:59'!
departamentos
	^ departamentos! !

!Empresa methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 10:59'!
nome
	^ nome! !

!Empresa methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 10:59'!
nome: anObject
	nome := anObject! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:09'!
acceptVisitor: aVisitor
	aVisitor visitEmpresa: self! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
addDepartamento: anElement
		"Generated code"
		|toAdd|
		toAdd := self getDepartamentoByNome: (anElement perform: anElement class idSelector).
		toAdd ifNotNil: [:found|self error: found asString, 'already exists'].
		^ departamentos := departamentos add: anElement! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
deleteDepartamentoByNome: anId
		"Generated code"
		|toDelete|
		toDelete := self getDepartamentoByNome: anId.
		^ departamentos := departamentos remove: toDelete! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
empregadoComMaiorSalario
		"Generated code"
		| visitor |
		visitor := (Operation atSignature: #empregadoComMaiorSalario) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
empregadosPorDepartamento
		"Generated code"
		| visitor |
		visitor := (Operation atSignature: #empregadosPorDepartamento) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
empregadosSalarioMaiorQue: anObject1
		"Generated code"
		| visitor |
		visitor := (Operation atSignature: #empregadosSalarioMaiorQue:) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
getDepartamentoByNome: anId
		"Generated code"
		|selecteds|
		selecteds := departamentos select: [:each| (each perform: #nome) = anId].
		selecteds ifEmpty: [^ nil].
			^ selecteds first! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 20:36'!
initialize
	departamentos := EmptyList newWithElementClass: Departamento..

	self
		addDepartamento: (Departamento nome: 'A');
		addDepartamento: (Departamento nome: 'B');
		addDepartamento: (Departamento nome: 'C').

	Empregado reinicieMatriculas.

	(self getDepartamentoByNome: 'A') gerente: (Empregado matricula: Empregado proximaMatricula nome: 'João' salario: 5000).
	(self getDepartamentoByNome: 'A')
		addEmpregado: (self getDepartamentoByNome: 'A') gerente;
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Maria' salario: 6000);
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Paulo' salario: 3000).

	(self getDepartamentoByNome: 'B') gerente: (Empregado matricula: Empregado proximaMatricula nome: 'Carla' salario: 7000).
	(self getDepartamentoByNome: 'B')
		addEmpregado: (self getDepartamentoByNome: 'B') gerente;
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Pedro' salario: 2000).

	(self getDepartamentoByNome: 'C') gerente: (Empregado matricula: Empregado proximaMatricula nome: 'Mateus' salario: 5000).
	(self getDepartamentoByNome: 'C')
		addEmpregado: (self getDepartamentoByNome: 'C') gerente.

	(self getDepartamentoByNome: 'A')
		addDivisao: (Divisao nome: 'D').
	(self getDepartamentoByNome: 'B')
		addDivisao: (Divisao nome: 'E');
		addDivisao: (Divisao nome: 'F').
	(self getDepartamentoByNome: 'C')
		addDivisao: (Divisao nome: 'G');
		addDivisao: (Divisao nome: 'H');
		addDivisao: (Divisao nome: 'I').

	((self getDepartamentoByNome: 'A') getDivisaoByNome: 'D') gerente: (Empregado matricula: Empregado proximaMatricula nome: 'Paulo' salario: 5200).
	((self getDepartamentoByNome: 'A') getDivisaoByNome: 'D')
		addEmpregado: ((self getDepartamentoByNome: 'A') getDivisaoByNome: 'D') gerente;
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Tatiana' salario: 6100);
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Joana' salario: 3500).

	((self getDepartamentoByNome: 'B') getDivisaoByNome: 'E')
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Diego' salario: 2200);
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Natacha' salario: 8100).
	((self getDepartamentoByNome: 'B') getDivisaoByNome: 'F')
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Carolina' salario: 7100).
	((self getDepartamentoByNome: 'B') getDivisaoByNome: 'E') gerente: ((self getDepartamentoByNome: 'B') getDivisaoByNome: 'E') empregados head.

	((self getDepartamentoByNome: 'C') getDivisaoByNome: 'G')
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Rodrigo' salario: 4100).
	((self getDepartamentoByNome: 'C') getDivisaoByNome: 'G') gerente: ((self getDepartamentoByNome: 'C') getDivisaoByNome: 'G') empregados head.

	((self getDepartamentoByNome: 'C') getDivisaoByNome: 'H')
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Pedro' salario: 2200);
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Raissa' salario: 8100).
	((self getDepartamentoByNome: 'C') getDivisaoByNome: 'H') gerente: ((self getDepartamentoByNome: 'C') getDivisaoByNome: 'H') empregados head.

	((self getDepartamentoByNome: 'C') getDivisaoByNome: 'I')
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Francisco' salario: 5200);
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Melissa' salario: 6100);
		addEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Betània' salario: 3500).
	((self getDepartamentoByNome: 'C') getDivisaoByNome: 'I') gerente: ((self getDepartamentoByNome: 'C') getDivisaoByNome: 'I') empregados head.

		! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/16/2012 12:16'!
listarDepartamentos
	self departamentos
		do: [:departamento|
			Transcript
				space;
				show: departamento nome
				] ! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:54'!
listarEmpregados
	| empregados |
	Transcript cr; show: 'Empregados:'.
	empregados := self todosEmpregados.
	empregados do: [:empregado|
		Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
	]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 10:23'!
listarEmpregadosComSalariosAltos
	| empregados |
	Transcript cr; show: 'Empregados com salarios altos:'.
	empregados := self empregadosSalarioMaiorQue: 7000.
	empregados do: [:empregado|
		Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
	]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/16/2012 11:40'!
listarEmpregadosPorDepartamento
	self departamentos do: [:departamento|
		Transcript cr; show: departamento nome.
		departamento listarEmpregados
	]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:32'!
listarNomesEmpregados
	| nomes |
	Transcript cr; show: 'Nomes de empregados:'.
	nomes := self nomesEmpregados.
	nomes do: [:each|
		Transcript space; show: each
	]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 09:47'!
listarNumeroEmpregados
	Transcript cr; show: 'Número de empregados: ', self numeroEmpregados asString.
! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
nomesDepartamentos
		"Generated code"
		| visitor |
		visitor := (Operation atSignature: #nomesDepartamentos) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
nomesEmpregados
		"Generated code"
		| visitor |
		visitor := (Operation atSignature: #nomesEmpregados) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
numeroEmpregados
		"Generated code"
		| visitor |
		visitor := (Operation atSignature: #numeroEmpregados) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 07:49'!
printOn: aStream
	super printOn: aStream.
	aStream nextPutAll: ': ', nome! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
somaSalariosEmpregados
		"Generated code"
		| visitor |
		visitor := (Operation atSignature: #somaSalariosEmpregados) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
todosEmpregados
		"Generated code"
		| visitor |
		visitor := (Operation atSignature: #todosEmpregados) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
todosEmpregados2
		"Generated code"
		| visitor |
		visitor := (Operation atSignature: #todosEmpregados2) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Empresa class
	instanceVariableNames: ''!

!Empresa class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 07:47'!
nome: aByteString
	^ self new
		nome: aByteString ! !

AdaptiveBase subclass: #Departamento
	instanceVariableNames: 'nome empregados divisoes gerente'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples-Model'!

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:10'!
acceptVisitor: aVisitor
	aVisitor visitDepartamento: self! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
addDivisao: anElement
		"Generated code"
		|toAdd|
		toAdd := self getDivisaoByNome: (anElement perform: anElement class idSelector).
		toAdd ifNotNil: [:found|self error: found asString, 'already exists'].
		^ divisoes := divisoes add: anElement! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
addEmpregado: anElement
		"Generated code"
		|toAdd|
		toAdd := self getEmpregadoByMatricula: (anElement perform: anElement class idSelector).
		toAdd ifNotNil: [:found|self error: found asString, 'already exists'].
		^ empregados := empregados add: anElement! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
deleteDivisaoByNome: anId
		"Generated code"
		|toDelete|
		toDelete := self getDivisaoByNome: anId.
		^ divisoes := divisoes remove: toDelete! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
deleteEmpregadoByMatricula: anId
		"Generated code"
		|toDelete|
		toDelete := self getEmpregadoByMatricula: anId.
		^ empregados := empregados remove: toDelete! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
getDivisaoByNome: anId
		"Generated code"
		|selecteds|
		selecteds := divisoes select: [:each| (each perform: #nome) = anId].
		selecteds ifEmpty: [^ nil].
			^ selecteds first! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 22:06'!
getEmpregadoByMatricula: anId
		"Generated code"
		|selecteds|
		selecteds := empregados select: [:each| (each perform: #matricula) = anId].
		selecteds ifEmpty: [^ nil].
			^ selecteds first! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 17:40'!
initialize
	empregados := EmptyList  newWithElementClass: Empregado.
	divisoes := EmptyList  newWithElementClass: Divisao..
! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 07:40'!
listarEmpregados
	self empregados
		do: [:empregado | Transcript cr; tab;
			show: empregado matricula; space;
			show: empregado nome; space;
			show: empregado salario].
	self divisoes do: [:divisao|
		Transcript cr; show: 'Divisão: '; show: divisao nome.
		divisao listarEmpregados]! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:28'!
nomesEmpregados
	| result |
	result := OrderedCollection new.
	empregados do: [:each| result addAll: each nomesEmpregados].
	divisoes do: [:each| result addAll: each nomesEmpregados].
	^ result! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 07:03'!
numeroEmpregados
	| result |
	result := 0.
	empregados do: [:each| result := result + each numeroEmpregados].
	divisoes do: [:each| result := result + each numeroEmpregados].
	^ result! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 09:58'!
printOn: aStream
	super printOn: aStream.
	aStream nextPutAll: ': ', nome! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:47'!
todosEmpregados
	| result |
	result := OrderedCollection new.
	empregados do: [:each| result addAll: each todosEmpregados].
	divisoes do: [:each| result addAll: each todosEmpregados].
	^ result! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:33'!
divisoes
	^ divisoes! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:24'!
empregados
	^ empregados! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/29/2012 11:23'!
gerente
	^ gerente! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/29/2012 11:23'!
gerente: anObject
	gerente := anObject! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 09:23'!
nome
	^ nome! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 09:23'!
nome: anObject
	nome := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Departamento class
	instanceVariableNames: ''!

!Departamento class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/30/2012 16:36'!
idSelector
	^ #nome! !

!Departamento class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/16/2012 09:26'!
nome: aString
	^ self new nome: aString! !

Empregado initialize!

 

Object subclass: #Aplicacao
	instanceVariableNames: 'empresa'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples-UI'!

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 21:45'!
initialize
	empresa := Empresa nome: 'ABC Ltda.'.

	((Operation
		signature: #todosEmpregados
		result: OrderedCollection new
		from: Empresa
		bypassing: #gerente
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result add: visited
			]
		]
		) compile.

	((Operation
		signature: #todosEmpregados2
		result: Set new
		from: Empresa
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result add: visited
			]
		]
		) compile.

	((Operation
		signature: #nomesEmpregados
		result: OrderedCollection new
		from: Empresa
		bypassing: #gerente
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result add: visited nome
			]]
		) compile.

	((Operation
		signature: #numeroEmpregados
		result: (Accumulator value: 0)
		from: Empresa
		bypassing: #gerente
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result value: visitor result value + 1
			]]
		) compile.

	((Operation
		signature: #empregadosSalarioMaiorQue:
		result: (OrderedCollection new)
		from: Empresa
		bypassing: #gerente
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visited salario > visitor arguments first ifTrue: [visitor result add: visited]
			]]
		) compile.

		((Operation
		signature: #somaSalariosEmpregados
		result: (Accumulator value: 0)
		from: Empresa
		bypassing: #gerente
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result value: visitor result value + visited salario
			]]
		) compile.

	((Operation
		signature: #empregadoComMaiorSalario
		result: (Accumulator value: nil)
		from: Empresa
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				(visitor result value isNil or: [visited salario > visitor result value salario]) ifTrue: [visitor result: visited]
			]]
		) compile.

	((Operation
		signature: #nomesDepartamentos
		result: OrderedCollection new
		from: Empresa
		to: Departamento)
		wrapperTo: Departamento  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result add: visited nome
			]	]
		) compile.

	((Operation
		signature: #empregadosPorDepartamento
		result: Dictionary new
		from: Empresa
		bypassing: #gerente
		to: Empregado)
		wrapperTo: Departamento  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result at: visited put: nil.
				visitor result at: #empregados put: OrderedCollection new
			].
			wrapper sufix: [:visitor :visited|
				visitor result at: visited put: (visitor result at: #empregados)
			]
		];
		wrapperTo: Empregado with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				(visitor result at: #empregados) add: visited
			]
		]
		) compile.

! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 14:39'!
listarEmpregadoComMaiorSalario
	| empregado |
	Transcript cr; show: 'Empregado com maior salário:'.
	empregado := empresa empregadoComMaiorSalario.
	Transcript tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 20:32'!
listarEmpregados
	| empregados |
	Transcript cr; show: 'Empregados:'.
	empregados := empresa todosEmpregados2.
	(empregados sorted: [:emp1 :emp2| emp1 matricula < emp2 matricula]) do: [:empregado|
		Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
	]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 20:40'!
listarEmpregadosComSalariosAltos
	| empregados salario |
	salario := 7000.
	Transcript cr; show: 'Empregados com salarios maiores que ', salario asString.
	empregados := empresa empregadosSalarioMaiorQue: salario.
	empregados do: [:empregado|
		Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
	]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 7/1/2012 20:22'!
listarEmpregadosPorDepartamento
	| departamentos |
	Transcript cr; show: 'Empregados por departamento:'.
	departamentos := empresa empregadosPorDepartamento.
	departamentos keysAndValuesDo: [:key :value| |departamento empregados|
		key = #empregados ifFalse: [
			departamento := key.
			empregados := value.
			Transcript cr; show: 'Departamento: ', departamento nome, ', gerente: ', departamento gerente nome.
			empregados do: [:empregado|
			Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario].
		]
	]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 20:33'!
listarNomesDepartamentos
	| nomes |
	Transcript cr; show: 'Nomes dos departamentos: '.
	nomes := empresa nomesDepartamentos.
	nomes do: [:each|
		Transcript space; show: each
	]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 20:34'!
listarNomesEmpregados
	| nomes |
	Transcript cr; show: 'Nomes de empregados:'.
	nomes := empresa nomesEmpregados.
	nomes do: [:each|
		Transcript space; show: each
	]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 20:35'!
listarNumeroEmpregados
	Transcript cr; show: 'Número de empregados: ', empresa numeroEmpregados asString.
! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 09:36'!
listarSomaSalariosEmpregados
	Transcript cr; show: 'Soma dos salários dos empregados: ', empresa somaSalariosEmpregados asString.! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 13:00'!
run
	Transcript clear.
	self listarEmpregados.
	self listarNomesEmpregados.
	self listarNumeroEmpregados.
	self listarEmpregadosComSalariosAltos.
	self listarSomaSalariosEmpregados.
	self listarEmpregadoComMaiorSalario.
	self listarNomesDepartamentos.
	self listarEmpregadosPorDepartamento! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Aplicacao class
	instanceVariableNames: ''!

Na parte 9 vamos desenvolver uma aplicação para ilustrar a capacidade do framework.

Adaptive Programming – Part 7


Início
Continuação da parte 6.

Adaptive Programming

Hooks

Vamos introduzir o bloco de sufixo para o wrapper e também bloco de prefixo e sufixo para todos os nós visitados:

Agora temos dois blocos de prefixo e sufixo que são executados antes e depois do traversal das variáveis de instância. Dois deles são executados para todos os objetos visitados e os outros dois apenas para os objetos de determinadas classes. Esta nova flexiblidade permite funcionalidades mais sofisticadas.

Vamos criar um trace que mostre quais os objetos visitados para a operação #todosEmpregados:

Observamos no resultado que as variáveis de instância dos objetos da classe Empregado são traversed sem necessidade. Isto acontece porque não usamos a informação de que o trajeto em busca dos dados deve terminar nos objetos da classe Empregado. Corrigimos isto no código abaixo:

Os nomes dos departamentos são obtidos com a operação seguinte:

Vamos fazer algo um pouco mais complexo. Queremos listar os empregados agrupados por departamento. A operação abaixo dá conta do recado:

O métodos para exibir o relatório é o seguinte:

O file-out até agora pode ser obtido abaixo:

Object subclass: #Visitor
	instanceVariableNames: 'result'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Visitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 08:19'!
result
	^ result! !

!Visitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 08:19'!
result: anObject
	result := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Visitor class
	instanceVariableNames: ''!

!Visitor class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 18:48'!
result: anObject
	^ self new result: anObject.! !

Visitor subclass: #NomesEmpregadosVisitor
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!NomesEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:26'!
visitDepartamento: umDepartamento
	umDepartamento empregados do: [:each| each acceptVisitor: self].
	umDepartamento divisoes do: [:each| each acceptVisitor: self]	! !

!NomesEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/22/2012 07:52'!
visitDivisao: umaDivisao
	umaDivisao empregados do: [:each| each acceptVisitor: self]! !

!NomesEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:26'!
visitEmpregado: umEmpregado
	result add: umEmpregado nome! !

!NomesEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:26'!
visitEmpresa: umaEmpresa
	umaEmpresa departamentos do: [:each| each acceptVisitor: self]! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

NomesEmpregadosVisitor class
	instanceVariableNames: ''!

Visitor subclass: #NumeroEmpregadosVisitor
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!NumeroEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 21:59'!
visitDepartamento: umDepartamento
	umDepartamento empregados do: [:each| each acceptVisitor: self].
	umDepartamento divisoes do: [:each| each acceptVisitor: self]	! !

!NumeroEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/22/2012 07:52'!
visitDivisao: umaDivisao
	umaDivisao empregados do: [:each| each acceptVisitor: self]! !

!NumeroEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:00'!
visitEmpregado: umEmpregado
	result value: result value + 1! !

!NumeroEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 21:59'!
visitEmpresa: umaEmpresa
	umaEmpresa departamentos do: [:each| each acceptVisitor: self]! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

NumeroEmpregadosVisitor class
	instanceVariableNames: ''!

Object subclass: #Aplicacao
	instanceVariableNames: 'empresa'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 11:01'!
initialize
	empresa := Empresa nome: 'ABC Ltda.'..

	((Operation
		signature: #todosEmpregados
		result: OrderedCollection new
		from: Empresa
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result add: visited
			]
		]
		) compile.

	((Operation
		signature: #nomesEmpregados
		result: OrderedCollection new
		from: Empresa
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result add: visited nome
			]]
		) compile.

	((Operation
		signature: #numeroEmpregados
		result: (Accumulator value: 0)
		from: Empresa
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result value: visitor result value + 1
			]]
		) compile.

	((Operation
		signature: #empregadosSalarioMaiorQue:
		result: (OrderedCollection new)
		from: Empresa
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visited salario > visitor arguments first ifTrue: [visitor result add: visited]
			]]
		) compile.

		((Operation
		signature: #somaSalariosEmpregados
		result: (Accumulator value: 0)
		from: Empresa
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result value: visitor result value + visited salario
			]]
		) compile.

	((Operation
		signature: #empregadoComMaiorSalario
		result: (Accumulator value: nil)
		from: Empresa
		to: Empregado)
		wrapperTo: Empregado  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				(visitor result value = nil or: [visited salario > visitor result value salario]) ifTrue: [visitor result: visited]
			]]
		) compile.

	((Operation
		signature: #nomesDepartamentos
		result: OrderedCollection new
		from: Empresa
		to: Departamento)
		wrapperTo: Departamento  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result add: visited nome
			]	]
		) compile.

	((Operation
		signature: #empregadosPorDepartamento
		result: Dictionary new
		from: Empresa
		to: Empregado)
		wrapperTo: Departamento  with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				visitor result at: visited nome put: nil.
				visitor result at: #empregados put: OrderedCollection new
			]..
			wrapper sufix: [:visitor :visited|
				visitor result at: visited nome put: (visitor result at: #empregados)
			]
		];
		wrapperTo: Empregado with: [:wrapper|
			wrapper prefix: [:visitor :visited|
				(visitor result at: #empregados) add: visited
			]
		]
		) compile.

! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 14:39'!
listarEmpregadoComMaiorSalario
	| empregado |
	Transcript cr; show: 'Empregado com maior salário:'.
	empregado := empresa empregadoComMaiorSalario.
	Transcript tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 20:33'!
listarEmpregados
	| empregados |
	Transcript cr; show: 'Empregados:'.
	empregados := empresa todosEmpregados.
	empregados do: [:empregado|
		Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
	]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 07:48'!
listarEmpregadosComSalariosAltos
	| empregados |
	Transcript cr; show: 'Empregados com salarios altos:'.
	empregados := empresa empregadosSalarioMaiorQue: 7000.
	empregados do: [:empregado|
		Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
	]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 07:49'!
listarEmpregadosPorDepartamento
	| departamentos |
	Transcript cr; show: 'Empregados por departamento:'.
	departamentos := empresa empregadosPorDepartamento.
	departamentos keysAndValuesDo: [:key :value| |nomeDepartamento empregados|
		nomeDepartamento := key.
		nomeDepartamento = #empregados ifFalse: [
			empregados := value.
			Transcript cr; show: 'Departamento: ', nomeDepartamento.
			empregados do: [:empregado|
			Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario].
		]
	]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:57'!
listarEmpregadosdoDepartamento: dep
	Transcript
		cr;
		show: 'Empregados:'.
	dep empregados
		do: [ :empregado |
			Transcript
				cr;
				tab;
				show: empregado matricula;
				space;
				show: empregado nome;
				space;
				show: empregado salario ]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 20:33'!
listarNomesDepartamentos
	| nomes |
	Transcript cr; show: 'Nomes dos departamentos: '.
	nomes := empresa nomesDepartamentos.
	nomes do: [:each|
		Transcript space; show: each
	]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 20:34'!
listarNomesEmpregados
	| nomes |
	Transcript cr; show: 'Nomes de empregados:'.
	nomes := empresa nomesEmpregados.
	nomes do: [:each|
		Transcript space; show: each
	]! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 20:35'!
listarNumeroEmpregados
	Transcript cr; show: 'Número de empregados: ', empresa numeroEmpregados asString.
! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 09:36'!
listarSomaSalariosEmpregados
	Transcript cr; show: 'Soma dos salários dos empregados: ', empresa somaSalariosEmpregados asString.! !

!Aplicacao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 21:40'!
run
	Transcript clear.
	self listarEmpregados.
	self listarNomesEmpregados.
	self listarNumeroEmpregados.
	self listarEmpregadosComSalariosAltos.
	self listarSomaSalariosEmpregados.
	self listarEmpregadoComMaiorSalario.
	self listarNomesDepartamentos.
	self listarEmpregadosPorDepartamento! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Aplicacao class
	instanceVariableNames: ''!

Object subclass: #AdaptiveBase
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!AdaptiveBase methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:32'!
accept: aVisitor
	aVisitor visit: self! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

AdaptiveBase class
	instanceVariableNames: ''!

AdaptiveBase subclass: #Departamento
	instanceVariableNames: 'nome empregados divisoes crudManager empregadosCrudManager divisoesCrudManager'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:10'!
acceptVisitor: aVisitor
	aVisitor visitDepartamento: self! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/24/2012 08:48'!
adicionarDivisao: aDivisao
	^ divisoes := divisoesCrudManager addElement: aDivisao ! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/24/2012 08:50'!
adicionarEmpregado: anEmpregado
	^ empregados := empregadosCrudManager addElement: anEmpregado ! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 10:19'!
empregadosSalarioMaiorQue: aSmallInteger
	| result |
	result := OrderedCollection new.
	empregados do: [:each| result addAll: (each empregadosSalarioMaiorQue: aSmallInteger)].
	divisoes do: [:each| result addAll: (each empregadosSalarioMaiorQue: aSmallInteger)].
	^ result! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:43'!
initialize
	empregados := EmptyList  new.
	divisoes := EmptyList  new.
	empregadosCrudManager := CRUDManager collection: empregados idSelector: #matricula.
	divisoesCrudManager := CRUDManager collection: divisoes idSelector: #nome.
! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/17/2012 19:48'!
listarDivisoes
	self divisoes
		do: [:divisao|
			Transcript
				space;
				show: divisao nome
				] ! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 07:40'!
listarEmpregados
	self empregados
		do: [:empregado | Transcript cr; tab;
			show: empregado matricula; space;
			show: empregado nome; space;
			show: empregado salario].
	self divisoes do: [:divisao|
		Transcript cr; show: 'Divisão: '; show: divisao nome.
		divisao listarEmpregados]! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:28'!
nomesEmpregados
	| result |
	result := OrderedCollection new.
	empregados do: [:each| result addAll: each nomesEmpregados].
	divisoes do: [:each| result addAll: each nomesEmpregados].
	^ result! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 07:03'!
numeroEmpregados
	| result |
	result := 0.
	empregados do: [:each| result := result + each numeroEmpregados].
	divisoes do: [:each| result := result + each numeroEmpregados].
	^ result! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 09:58'!
printOn: aStream
	super printOn: aStream.
	aStream nextPutAll: ': ', nome! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:31'!
recuperarDivisaoNome: aByteString
	^ divisoesCrudManager getElementById: aByteString! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:27'!
recuperarEmpregadoMatricula: aSmallInteger
	^ crudManager getElementById: aSmallInteger! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:32'!
removerDivisaoNome: aString
	^ divisoesCrudManager deleteElementById: aString! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:32'!
removerEmpregadoMatricula: aSmallInteger
	^ empregadosCrudManager deleteElementById: aSmallInteger! !

!Departamento methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:47'!
todosEmpregados
	| result |
	result := OrderedCollection new.
	empregados do: [:each| result addAll: each todosEmpregados].
	divisoes do: [:each| result addAll: each todosEmpregados].
	^ result! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:33'!
divisoes
	^ divisoes! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:24'!
empregados
	^ empregados! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 09:23'!
nome
	^ nome! !

!Departamento methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 09:23'!
nome: anObject
	nome := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Departamento class
	instanceVariableNames: ''!

!Departamento class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/16/2012 09:26'!
nome: aString
	^ self new nome: aString! !

AdaptiveBase subclass: #List
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!List methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 19:20'!
add: anElement
	^ NonEmptyList first: anElement rest: self! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

List class
	instanceVariableNames: ''!

List subclass: #NonEmptyList
	instanceVariableNames: 'head tail'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:13'!
append: anElement
	^ NonEmptyList first: head rest: (tail append: anElement)! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:13'!
do: aBlockClosure
	aBlockClosure value: head.
	tail do: aBlockClosure ! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:13'!
head
	^ head! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:14'!
head: anElement
	head := anElement! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:39'!
select: aBlockClosure
	| newCollection |
	newCollection := EmptyList new.
	self do: [:each | (aBlockClosure value: each) ifTrue: [newCollection := newCollection add: each]].
	^newCollection! !

!NonEmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:19'!
tail: anEmptyList
	tail := anEmptyList! !

!NonEmptyList methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/25/2012 16:58'!
tail
	^ tail! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

NonEmptyList class
	instanceVariableNames: ''!

!NonEmptyList class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:19'!
first: anElement rest: aList
	^ self new
		head: anElement;
		tail: aList! !

List subclass: #EmptyList
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 19:44'!
append: anElement
	^ NonEmptyList first: anElement rest: self! !

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 19:39'!
do: aBlockClosure ! !

!EmptyList methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:31'!
select: aBlockClosure ! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

EmptyList class
	instanceVariableNames: ''!

AdaptiveBase subclass: #Empregado
	instanceVariableNames: 'matricula nome salario'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:31'!
matricula
	^ matricula! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:31'!
matricula: anObject
	matricula := anObject! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
nome
	^ nome! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
nome: anObject
	nome := anObject! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
salario
	^ salario! !

!Empregado methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/14/2012 07:26'!
salario: anObject
	salario := anObject! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:10'!
acceptVisitor: aVisitor
	aVisitor visitEmpregado: self! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 10:21'!
empregadosSalarioMaiorQue: aSmallInteger
	| result |
	result := OrderedCollection new.
	(self salario > aSmallInteger) ifTrue: [result add: self].
	^ result! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:29'!
nomesEmpregados
	| result |
	result := OrderedCollection new.
	result add: self nome.
	^ result! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 07:06'!
numeroEmpregados
	| result |
	result := 1.
	^ result! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 10:00'!
printOn: aStream
	super printOn: aStream.
	aStream nextPutAll: ': ', nome! !

!Empregado methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:49'!
todosEmpregados
	| result |
	result := OrderedCollection new.
	result add: self.
	^ result! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Empregado class
	instanceVariableNames: 'proximaMatricula'!

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:56'!
initialize
	"
	self initialize
	"
	self reinicieMatriculas! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:32'!
matricula: anInteger nome: aString salario: aFloat
	^ self new
	      matricula: anInteger;
		nome: aString;
		salario: aFloat ! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:28'!
nome: aString salario: aFloat
	^ self new
		nome: aString;
		salario: aFloat ! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:37'!
proximaMatricula
	proximaMatricula := proximaMatricula + 1.
	^ proximaMatricula! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 07:55'!
reinicieMatriculas
	proximaMatricula := 0..! !

!Empregado class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/14/2012 21:26'!
ultimaMatricula
	^ proximaMatricula! !

AdaptiveBase subclass: #Divisao
	instanceVariableNames: 'nome empregados crudManager'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:10'!
acceptVisitor: aVisitor
	aVisitor visitDivisao: self! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/24/2012 08:50'!
adicionarEmpregado: anEmpregado
	^ empregados := crudManager addElement: anEmpregado ! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 10:22'!
empregadosSalarioMaiorQue: aSmallInteger
	| result |
	result := OrderedCollection new.
	empregados do: [:each| result addAll: (each empregadosSalarioMaiorQue: aSmallInteger)].
	^ result! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:02'!
initialize
	empregados := EmptyList  new.
	crudManager := CRUDManager collection: empregados idSelector: #matricula.
! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
listarEmpregados
	self empregados
		do: [ :empregado |
			Transcript
				cr;
				tab;
				show: empregado matricula;
				space;
				show: empregado nome;
				space;
				show: empregado salario ]! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:30'!
nomesEmpregados
	| result |
	result := OrderedCollection new.
	empregados do: [:each| result addAll: each nomesEmpregados].
	^ result! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 07:04'!
numeroEmpregados
	| result |
	result := 0.
	empregados do: [:each| result := result + each numeroEmpregados].
	^ result! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 09:59'!
printOn: aStream
	super printOn: aStream.
	aStream nextPutAll: ': ', nome! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:34'!
recuperarEmpregadoMatricula: aSmallInteger
	^ crudManager getElementById: aSmallInteger! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:34'!
removerEmpregadoMatricula: aSmallInteger
	^ crudManager deleteElementById: aSmallInteger! !

!Divisao methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:48'!
todosEmpregados
	| result |
	result := OrderedCollection new.
	empregados do: [:each| result addAll: each todosEmpregados].
	^ result! !

!Divisao methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
empregados
	^ empregados! !

!Divisao methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
nome
	^ nome! !

!Divisao methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
nome: anObject
	nome := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Divisao class
	instanceVariableNames: ''!

!Divisao class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/17/2012 19:30'!
nome: aString
	^ self new nome: aString! !

Object subclass: #Accumulator
	instanceVariableNames: 'value'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Accumulator methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 22:15'!
value
	^ value! !

!Accumulator methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/21/2012 22:04'!
value: anObject
	value := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Accumulator class
	instanceVariableNames: ''!

!Accumulator class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:06'!
value: aSmallInteger
	^self new value: aSmallInteger ! !

Visitor subclass: #EmpregadosSalarioMaiorQueVisitor
	instanceVariableNames: 'salario'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:41'!
salario
	^ salario! !

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:40'!
salario: aSmallInteger
	salario := aSmallInteger ! !

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:29'!
visitDepartamento: umDepartamento
	umDepartamento empregados do: [:each| each acceptVisitor: self].
	umDepartamento divisoes do: [:each| each acceptVisitor: self]	! !

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/22/2012 07:52'!
visitDivisao: umaDivisao
	umaDivisao empregados do: [:each| each acceptVisitor: self]! !

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:32'!
visitEmpregado: umEmpregado
	(umEmpregado salario > self salario) ifTrue: [
	result add: umEmpregado]! !

!EmpregadosSalarioMaiorQueVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:29'!
visitEmpresa: umaEmpresa
	umaEmpresa departamentos do: [:each| each acceptVisitor: self]! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

EmpregadosSalarioMaiorQueVisitor class
	instanceVariableNames: ''!

!EmpregadosSalarioMaiorQueVisitor class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 22:39'!
salario: aSmallInteger result: anOrderedCollection
	^ self new
		salario: aSmallInteger ;
		result: anOrderedCollection! !

Object subclass: #Operation
	instanceVariableNames: 'result sourceClass targetClass wrappers visitor signatureSymbol prefix sufix'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:38'!
addWrapperTo: aClass withPrefix: aBlockClosure
	wrappers at: aClass name asSymbol put: (Wrapper prefix: aBlockClosure) ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 21:11'!
addWrapperTo: aClass withSufix: aBlockClosure
	wrappers at: aClass name asSymbol put: (Wrapper sufix: aBlockClosure) ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 06:11'!
compile
	self compileEntryPoint! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 06:11'!
compileEntryPoint
	sourceClass compile: self createEntryPointSource! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/26/2012 06:11'!
createEntryPointSource
	| sourceCode |
	sourceCode := '<1s>
	<t>"Generated code"
	<t>| result visitor |
	<t>visitor := (Operation atSignature: #<2s>) visitor.
	visitor arguments: thisContext arguments.
	<t>visitor visit: self.
	<t>^ visitor result value'.
	^ sourceCode expandMacrosWith: (self signatureWithArgumentsFrom: signatureSymbol) with: signatureSymbol

! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:47'!
hasWrapperInClass: aClass
	^ wrappers isEmpty not and: [wrappers includesKey: aClass] ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:02'!
initialize
	wrappers := Dictionary new.
	visitor := OperationVisitor forOperation: self! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 11:43'!
prefix
	^ prefix! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 11:39'!
prefix: aBlockClosure
	prefix := aBlockClosure! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:35'!
prefixAt: aClassName
	^ (wrappers at: aClassName) prefix! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 12:44'!
result
	^ result! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 06:51'!
result: anObject
	result := anObject ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 20:52'!
signature: aByteSymbol
	signatureSymbol := aByteSymbol ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 23:06'!
signatureWithArgumentsFrom: aByteSymbol
	| stream count keywords |
	stream := WriteStream on: ''.
	count := 1.
	keywords := aByteSymbol keywords.

	(keywords size = 1 and: [(keywords first includes: $:) not] )ifTrue: [^ keywords first].

	keywords do: [:keyword|
		stream nextPutAll: keyword, ' anObject', count asString.
		count := count + 1
		].
	^ stream contents! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 06:52'!
sourceClass: aClass
	sourceClass := aClass! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:34'!
sufix
	^ sufix! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:03'!
sufix: aBlockClosure
	sufix := aBlockClosure! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:36'!
sufixAt: aClassName
	^ (wrappers at: aClassName) sufix! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 06:53'!
targetClass: aClass
	targetClass := aClass! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:03'!
visitor
	^visitor ! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 18:42'!
wrapperFor: aWrappedClassName
	^ wrappers at: aWrappedClassName ifAbsent: [^ nil]! !

!Operation methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 07:18'!
wrapperTo: aClass with: aWraperBlock
	| wrapper |
	wrapper := wrappers at: aClass name ifAbsent: [
		wrappers at: aClass name put: Wrapper new.
	]..
	aWraperBlock value: wrapper ! !

!Operation methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/25/2012 20:52'!
signature
	^ signatureSymbol! !

!Operation methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/27/2012 20:20'!
targetClass
	^ targetClass! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Operation class
	instanceVariableNames: 'operations'!

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:45'!
atSignature: aSignature
	^ operations at: aSignature! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:54'!
initialize
	"
	self initialize
	"
	operations := Dictionary new! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:58'!
registerOperation: anOperation
	operations at: anOperation signature put: anOperation! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 11:37'!
signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass
	^ self signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass prefix: nil sufix: nil! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 11:38'!
signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass prefix: aBlockClosure
	^ self signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass prefix: aBlockClosure sufix: nil! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 11:32'!
signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass prefix: prefixBlock sufix: sufixBlock
	| operation |
	operation := self new
		signature: aByteSymbol ;
		result: anObject ;
		sourceClass: aSourceClass ;
		targetClass: aTargetClass ;
		prefix: prefixBlock;
		sufix: sufixBlock .

	self registerOperation: operation.
	^ operation! !

!Operation class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 19:00'!
signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass sufix: aBlockClosure
	^ self signature: aByteSymbol result: anObject from: aSourceClass to: aTargetClass prefix: nil sufix: aBlockClosure! !

Object subclass: #CRUDManager
	instanceVariableNames: 'collection idSelector'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!CRUDManager methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:25'!
addElement: anElement
	^ collection := collection add: anElement! !

!CRUDManager methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:22'!
collection: aDictionary
	collection := aDictionary! !

!CRUDManager methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:08'!
deleteElementById: anId
	^ collection removeKey: anId! !

!CRUDManager methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 13:20'!
getElementById: anId
	^ (collection select: [:each| (each perform: idSelector) = anId]) head! !

!CRUDManager methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:23'!
idSelector: aByteSymbol
	idSelector := aByteSymbol! !

!CRUDManager methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/18/2012 13:19'!
collection
	^ collection! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

CRUDManager class
	instanceVariableNames: ''!

!CRUDManager class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:24'!
collection: aCollection idSelector: aSymbol
	^ self new
		collection: aCollection;
		idSelector: aSymbol

		! !

Object subclass: #Wrapper
	instanceVariableNames: 'prefix sufix'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Wrapper methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:39'!
prefix
	^ prefix! !

!Wrapper methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:39'!
prefix: aBlockClosure
	prefix := aBlockClosure ! !

!Wrapper methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:40'!
sufix
	^ sufix! !

!Wrapper methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/28/2012 07:50'!
sufix: anObject
	sufix := anObject! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Wrapper class
	instanceVariableNames: 'sufix'!

!Wrapper class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:39'!
prefix: aBlockClosure
	^self new
		prefix: aBlockClosure ! !

!Wrapper class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/28/2012 07:42'!
sufix: aBlockClosure
	sufix := aBlockClosure ! !

AdaptiveBase subclass: #Empresa
	instanceVariableNames: 'nome departamentos crudManager'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!Empresa methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 10:59'!
departamentos
	^ departamentos! !

!Empresa methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 10:59'!
nome
	^ nome! !

!Empresa methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/16/2012 10:59'!
nome: anObject
	nome := anObject! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:09'!
acceptVisitor: aVisitor
	aVisitor visitEmpresa: self! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/24/2012 08:27'!
adicionarDepartamento: aDepartamento
	^ departamentos := crudManager addElement: aDepartamento! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 11:01'!
empregadoComMaiorSalario
		"Generated code"
		| result visitor |
		visitor := (Operation atSignature: #empregadoComMaiorSalario) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 11:01'!
empregadosPorDepartamento
		"Generated code"
		| result visitor |
		visitor := (Operation atSignature: #empregadosPorDepartamento) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 11:01'!
empregadosSalarioMaiorQue: anObject1
		"Generated code"
		| result visitor |
		visitor := (Operation atSignature: #empregadosSalarioMaiorQue:) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 20:01'!
initialize
	departamentos := EmptyList new.
	crudManager := CRUDManager collection: departamentos idSelector: #nome.

	self
		adicionarDepartamento: (Departamento nome: 'A');
		adicionarDepartamento: (Departamento nome: 'B');
		adicionarDepartamento: (Departamento nome: 'C').

	Empregado reinicieMatriculas.

	(self recuperarDepartamentoNome: 'A')
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'João' salario: 5000);
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Maria' salario: 6000);
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Paulo' salario: 3000).
	(self recuperarDepartamentoNome: 'B')
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Carla' salario: 7000);
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Pedro' salario: 2000).
	(self recuperarDepartamentoNome: 'C')
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Mateus' salario: 5000).

	(self recuperarDepartamentoNome: 'A')
		adicionarDivisao: (Divisao nome: 'D').
	(self recuperarDepartamentoNome: 'B')
		adicionarDivisao: (Divisao nome: 'E');
		adicionarDivisao: (Divisao nome: 'F').
	(self recuperarDepartamentoNome: 'C')
		adicionarDivisao: (Divisao nome: 'G');
		adicionarDivisao: (Divisao nome: 'H');
		adicionarDivisao: (Divisao nome: 'I').

	((self recuperarDepartamentoNome: 'A') recuperarDivisaoNome: 'D')
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Paulo' salario: 5200);
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Tatiana' salario: 6100);
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Joana' salario: 3500).
	((self recuperarDepartamentoNome: 'B') recuperarDivisaoNome: 'E')
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Diego' salario: 2200);
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Natacha' salario: 8100).
	((self recuperarDepartamentoNome: 'B') recuperarDivisaoNome: 'F')
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Carolina' salario: 7100).

	((self recuperarDepartamentoNome: 'C') recuperarDivisaoNome: 'G')
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Rodrigo' salario: 4100).
	((self recuperarDepartamentoNome: 'C') recuperarDivisaoNome: 'H')
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Pedro' salario: 2200);
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Raissa' salario: 8100).
	((self recuperarDepartamentoNome: 'C') recuperarDivisaoNome: 'I')
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Francisco' salario: 5200);
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Melissa' salario: 6100);
		adicionarEmpregado: (Empregado matricula: Empregado proximaMatricula nome: 'Betània' salario: 3500).

		! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/16/2012 12:16'!
listarDepartamentos
	self departamentos
		do: [:departamento|
			Transcript
				space;
				show: departamento nome
				] ! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 07:54'!
listarEmpregados
	| empregados |
	Transcript cr; show: 'Empregados:'.
	empregados := self todosEmpregados.
	empregados do: [:empregado|
		Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
	]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 10:23'!
listarEmpregadosComSalariosAltos
	| empregados |
	Transcript cr; show: 'Empregados com salarios altos:'.
	empregados := self empregadosSalarioMaiorQue: 7000.
	empregados do: [:empregado|
		Transcript cr; tab; show: empregado matricula; space; show: empregado nome; space; show: empregado salario.
	]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/16/2012 11:40'!
listarEmpregadosPorDepartamento
	self departamentos do: [:departamento|
		Transcript cr; show: departamento nome.
		departamento listarEmpregados
	]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/19/2012 16:32'!
listarNomesEmpregados
	| nomes |
	Transcript cr; show: 'Nomes de empregados:'.
	nomes := self nomesEmpregados.
	nomes do: [:each|
		Transcript space; show: each
	]! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/20/2012 09:47'!
listarNumeroEmpregados
	Transcript cr; show: 'Número de empregados: ', self numeroEmpregados asString.
! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 11:01'!
nomesDepartamentos
		"Generated code"
		| result visitor |
		visitor := (Operation atSignature: #nomesDepartamentos) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 11:01'!
nomesEmpregados
		"Generated code"
		| result visitor |
		visitor := (Operation atSignature: #nomesEmpregados) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 11:01'!
numeroEmpregados
		"Generated code"
		| result visitor |
		visitor := (Operation atSignature: #numeroEmpregados) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 07:49'!
printOn: aStream
	super printOn: aStream.
	aStream nextPutAll: ': ', nome! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:20'!
recuperarDepartamentoNome: aByteString
	^ crudManager getElementById: aByteString! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/18/2012 13:21'!
removerDepartamentoNome: aString
	^ crudManager deleteElementById: aString! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 11:01'!
somaSalariosEmpregados
		"Generated code"
		| result visitor |
		visitor := (Operation atSignature: #somaSalariosEmpregados) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

!Empresa methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/29/2012 11:01'!
todosEmpregados
		"Generated code"
		| result visitor |
		visitor := (Operation atSignature: #todosEmpregados) visitor.
	visitor arguments: thisContext arguments.
		visitor visit: self.
		^ visitor result value! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

Empresa class
	instanceVariableNames: ''!

!Empresa class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 07:47'!
nome: aByteString
	^ self new
		nome: aByteString ! !

Visitor subclass: #TodosEmpregadosVisitor
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!TodosEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:22'!
visitDepartamento: umDepartamento
	umDepartamento empregados do: [:each| each acceptVisitor: self].
	umDepartamento divisoes do: [:each| each acceptVisitor: self]	! !

!TodosEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/22/2012 07:52'!
visitDivisao: umaDivisao
	umaDivisao empregados do: [:each| each acceptVisitor: self]! !

!TodosEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:25'!
visitEmpregado: umEmpregado
	result add: umEmpregado! !

!TodosEmpregadosVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/21/2012 08:20'!
visitEmpresa: umaEmpresa
	umaEmpresa departamentos do: [:each| each acceptVisitor: self]! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

TodosEmpregadosVisitor class
	instanceVariableNames: ''!

Visitor subclass: #OperationVisitor
	instanceVariableNames: 'operation arguments'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'AdaptiveProgrammingBlogPost-Examples'!

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 23:12'!
arguments
	^ arguments! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 08:40'!
hasWrapperIn: aClass
	^ operation hasWrapperInClass: aClass! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:12'!
operation: anOperation
	operation := anOperation ! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 11:43'!
prefix
	^ operation prefix! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 12:43'!
result
	^ operation result! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/25/2012 17:23'!
result: anObject
	operation result: anObject! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 13:33'!
sufix
	^ operation sufix! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 20:19'!
targetClass
	^ operation targetClass! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 20:18'!
visit: visitedObject
	| wrapper |
	"Prefix processing"
	self prefix ifNotNil: [:block| block cull: self cull: visitedObject].
	(wrapper := self wrapperFor: visitedObject class name) ifNotNil: [ wrapper prefix ifNotNil: [:prefix| prefix cull: self cull: visitedObject]].

	visitedObject class = self targetClass ifFalse: [
		"Traversal"
		visitedObject class allInstVarNames
			do: [:var |
				(visitedObject respondsTo: var asSymbol)
					ifTrue: [(visitedObject perform: var asSymbol)
						ifNotNil: [:varValue |
							self visit: varValue
						]
				]
		].
	].

	"Sufix processing"
	wrapper ifNotNil: [ wrapper sufix ifNotNil: [:sufix| sufix cull: self cull: visitedObject]].
	self sufix ifNotNil: [:block| block cull: self cull: visitedObject].! !

!OperationVisitor methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/27/2012 18:38'!
wrapperFor: aWrappedClassName
	^ operation wrapperFor: aWrappedClassName
! !

!OperationVisitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/26/2012 06:01'!
arguments: anObject
	arguments := anObject! !

!OperationVisitor methodsFor: 'accessing' stamp: 'FranciscoAryMartins 6/25/2012 12:40'!
operation
	^ operation! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

OperationVisitor class
	instanceVariableNames: 'operation'!

!OperationVisitor class methodsFor: 'as yet unclassified' stamp: 'FranciscoAryMartins 6/23/2012 07:11'!
forOperation: anOperation
	^ self new operation: anOperation ! !

Empregado initialize!
Operation initialize!

No próximo post vamos lidar com fazer o bypass de alguns traversal.

Continua na parte 8.

Sou associada à revista Star Palco que dá ingressos e descontos para peças no Rio de Janeiro. Sábado dia 16, meu marido e eu fomos com um casal amigo assistir à peça “Uma Noite na Lua”com o ator Gregório Duvivier. A peça é sobre o fluxo de pensamento de um autor teatral tentando escrever uma peça enquanto pensa na mulher que o deixou. Muito interessante! Amei!!!! Recomendo muito!!! O texto é maravilhoso, super bem escrito. O Ator muitíssimo talentoso. A iluminação dá um espetáculo. Imperdível!

Não deixe para comprar o ingresso na última hora, pois pode ficar sem o seu. Quase aconteceu conosco! A peça é às 21h e chegamos por volta de 20:15h. Na bilheteria já constava o aviso de ESGOTADO. Tivemos que colocar nosso nome na lista de espera e rezar para que alguns convidados não fossem, já que às 21h a bilheteria passaria a vender os…

Ver o post original 65 mais palavras

Vacations in a Can

A teardrop trailer, also known as a teardrop camper trailer, is a streamlined,[1] compact,[2]lightweight,[2] travel trailer, which gets its name from its teardrop profile. They usually only have sleeping space for two adults and often have a basic kitchen in the rear.

Fonte: http://vacations-in-a-can.com/

Smalltalk: a Reflective Language

As in the LISP tradition, SMALLTALK is almost entirely written in itself. It offers important advantages such as large portability, dynamicity, a fully unified world, graphical user interface builders, connection to databases, powerful development tools, etc. In this paper we discuss the trait that underlies all these features: REFLECTION. We quote one of its definitions and in the first part of this paper go through the different reflective aspects of SMALLTALK. We expand five major aspects in detail: meta-operations, the classes/metaclasses model, the reified compiler, message sending and the behavioral representation through the reification of the executive stack frame of each process. We illustrate their use with significant applications, based both on our industrial and research experiences. In the second part of the paper, we introduce and fully developpre/post conditions in SMALLTALK, dealing with extensions of the model, the compiler, and the development environment.

Fonte: Smalltalk: a Reflective Language