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.

Anúncios

3 Respostas para “Adaptive Programming – Part 8

  1. Pingback: Adaptive Programming – Part 9 | Crab Log

  2. Pingback: Adaptive Programming – Part 7 | Crab Log

  3. Pingback: Adaptive Programming – Part 1 | Crab Log

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s