--@atlcompiler atl2006
--Copyright (c) 2009 Mia-Software, 2017 Inria.
--All rights reserved. This program and the accompanying materials
--are made available under the terms of the Eclipse Public License v1.0
--which accompanies this distribution, and is available at
--http://www.eclipse.org/legal/epl-v10.html
---
--Contributors:
--	  Gabriel BARBIER (Mia-Software) - initial API and implementation
--    Fabien GIQUEL (Mia-Software) - initial API and implementation
--	  Hugo Bruneliere (Inria) - Bug 526229 - InfixExpression rule update
--								Bug 526234 - SwitchStatementToActionElement update
--
-- @nsURI kdm=http://www.eclipse.org/MoDisco/kdm/action
-- @nsURI java=http://www.eclipse.org/MoDisco/Java/0.2.incubation/java
--
--Transform Java Models to KDM models

module javaToKdm; -- Module Template
create OUT : kdm from IN : java;

rule InitializerToControlElement extends BodyDeclarationToAbstractCodeElement {
	from src : java!Initializer
	to tgt : kdm!ControlElement (
		codeElement <- src.body
	)
}

-- helpers --

-- specific case to attach all single elements to root model
endpoint rule manageDetachedElements() {

  do {
  		for (alone in kdm!AbstractCodeElement.allInstances()) {
  			if (alone.refImmediateComposite().oclIsUndefined()) {
  				thisModule.externalModel.codeElement <- alone;
  			}
  		}
   }
} 

helper def: externalModel : kdm!CodeModel = OclUndefined;


-- computes name of a generic type
helper context java!TypeDeclaration def : getGenericName() : String = 
	self.name + '<' + self.typeParameters
	->collect(T | if (self.typeParameters->indexOf(T) < self.typeParameters->size()) then T.name  + ', ' else T.name endif)
	->sum() + '>';
	
--returns referenced type, or one created on the fly in case of UnresolvedItem 
--this is used when creating variables or parameters which are containers for this kind of type in kdm
helper context java!TypeAccess def : getType() : kdm!Datatype =
	self.type->getExtendsType();

helper context java!NamedElement def : getExtendsType() : kdm!Datatype =
	if self.oclIsKindOf(java!UnresolvedItem) then
		if self.refImmediateComposite().oclIsTypeOf(java!ClassDeclaration) then
			thisModule->CreateClassUnit(self) -- TODO why ?
		else
			thisModule->CreateInterfaceUnit(self)
		endif
	else -- java!Type or java!Package
		self
	endif;

-- to be able to filter expressions that are not useful, or need to be managed manually
helper def : filterExpression(expression : java!Expression) : java!Expression =
	if (expression.oclIsUndefined()) then
		Sequence{}
	else
		if (expression.oclIsKindOf(java!SingleVariableAccess)
				or expression.oclIsKindOf(java!TypeAccess)
				or expression.oclIsKindOf(java!UnresolvedItemAccess)) then
			Sequence{}
		else 
			Sequence{expression}
		endif
	endif;

-- rules --

-- ===================================================== ---
--  Rules for the structure of a program
--  This part gives all the transformations for the structure of a Java program
-- ===================================================== ---

-- Transforms a Model into a code model
rule ModelToModel{
	from
		src : java!Model
	to
		kdmModel : kdm!CodeModel(
			name <- src.name
			,codeElement <- src.ownedElements->select(e| e.proxy = false)
			,codeElement <- kdmLanguageUnit
		)
		,kdmLanguageUnit : kdm!LanguageUnit(
			name <- 'Common Java datatypes',
			codeElement <- src.orphanTypes->select(e| e.oclIsKindOf(java!PrimitiveType)),
			codeElement <- stringType
		)
		,externalModel : kdm!CodeModel (
			name <- 'externals'
			,codeElement <- src.ownedElements->select(e| e.proxy = true)
			,codeElement <- src.orphanTypes->select(e| not e.oclIsKindOf(java!PrimitiveType))
		)
		,sourcesModel : kdm!InventoryModel (
			name <- 'source references',
			inventoryElement <- src.compilationUnits,
			inventoryElement <- src.archives
		)
		,kdmSegment : kdm!Segment mapsTo src (
			model <- kdmModel
			,model <- externalModel
			,model <- sourcesModel
		)
		,stringType : kdm!StringType (
			name <- 'string'
		)
		
	do {
		thisModule.externalModel <- externalModel;
	}

}

-- Transforms a package declaration into a package
rule PackageToPackage {
	from 
		src:java!Package
	to 
		tgt:kdm!Package(
			name<-src.name
			--get the subpackages owned by the matched package
			,codeElement<-src.ownedPackages
			--adds classes and interfaces
			,codeElement<-src.ownedElements				
		)
}

-- ===================================================== ---
--
-- abstract rule to manage source reference in kdm model
-- in java, corresponding metaclass is ASTNode
-- in kdm, it is AbstractCodeElement (no better choice)
--
-- ===================================================== ---

abstract rule ASTNodeToAbstractCodeElement {
	from src :java!ASTNode
	to tgt :kdm!AbstractCodeElement (
		-- comments
		comment <- src.comments,
		-- source file management
		source <- sourceRef
	)
	,sourceRef : kdm!SourceRef (
		language <- 'java'
		,region <- sourceRegion
	)
	,sourceRegion : kdm!SourceRegion (
		language <- 'java'
-- size expensive and redundant with SourceFile information
--		,path <- if (src.originalCompilationUnit.oclIsUndefined()) then
--					'internal'
--				else
--					src.originalCompilationUnit.originalFilePath
--				endif
		,file <- if (src.originalCompilationUnit.oclIsUndefined()) then
					src.originalClassFile
				else
					src.originalCompilationUnit
				endif
	)
}

abstract rule NamedElementToAbstractCodeElement extends ASTNodeToAbstractCodeElement {
	from src :java!NamedElement
	to tgt :kdm!AbstractCodeElement (
		name <- src.name
	)
}

abstract rule BodyDeclarationToAbstractCodeElement extends NamedElementToAbstractCodeElement {
	from src :java!BodyDeclaration
	to tgt :kdm!AbstractCodeElement (
		-- attributes to store additional information (visibility stays redundant)
		attribute <- if (src.modifier.oclIsUndefined()) then
						Sequence{}
					else
						src.modifier
					endif
		-- annotations
		,codeRelation <- src.annotations
	)
}
abstract rule AbstractTypeDeclarationToDatatype extends BodyDeclarationToAbstractCodeElement {
	from src :java!AbstractTypeDeclaration
	to tgt :kdm!Datatype (
		-- imports
		codeRelation <- if (src.originalCompilationUnit.oclIsUndefined()) then
					Sequence{}
				else
					src.originalCompilationUnit.imports
				endif
		-- inheritance
		,codeRelation <- src.superInterfaces->collect(e | 
			if (src.oclIsTypeOf(java!ClassDeclaration)) then 
				thisModule.CreateImplements(e)
			else
				thisModule.CreateExtends(e)
			endif) -- end collect
		-- annotations
		,codeRelation <- src.annotations
		-- TODO use superClass
		-- comments
		,comment <- src.commentsBeforeBody
		,comment <- src.commentsAfterBody
		,comment <- src.comments 
		,comment <- if (src.originalCompilationUnit.oclIsUndefined()
						or not src.refImmediateComposite().oclIsTypeOf(java!Package)) then
					Sequence{}
				else -- top level type declaration -> retrieving CU heading comments
					src.originalCompilationUnit.comments
				endif
	)
}

rule ModifierToAttribute {
	from src : java!Modifier
	to tgt : kdm!Attribute (
			tag <- 'export',
			value <- src.visibility.toString()
					+
					 (if (src.inheritance = #none) then
						''
					 else
					 	' ' + src.inheritance.toString()
					 endif)
					 
		)
}

-- ===================================================== ---
--  Rules for the classes
--  This part gives all the transformations for the classes of a Java program
-- the transformations being quite different when the considered class is generic (Java meaning)
-- ===================================================== ---

-- Transfoms a class declaration into a class unit
rule ClassDeclarationToClassUnit extends AbstractTypeDeclarationToDatatype {
	from src:java!ClassDeclaration (
			src.typeParameters.isEmpty()
	)
	using{
		-- For attributes, we have to separate FieldDeclaration and VariableDeclarationFragment usage
		javaAttributes :java!NamedElement = src.bodyDeclarations->select(e| e.oclIsTypeOf(java!FieldDeclaration))
			->collect(f| if (f.fragments->isEmpty()) then f else f.fragments endif);	
	}
	to tgt: kdm!ClassUnit(
		isAbstract <- if src.modifier.oclIsUndefined() then
						OclUndefined
					else
						src.modifier.inheritance = #"abstract"
					endif
		-- attributes
		,codeElement <- javaAttributes
		-- other elements
		,codeElement <- src.bodyDeclarations->select(e | not e.oclIsTypeOf(java!FieldDeclaration))	
	)
	do {
		-- inheritance
		tgt.codeRelation <- if src.superClass.oclIsUndefined() then
							Sequence{}
						else
							thisModule.CreateExtends(src.superClass)
						endif;
		
	}
}

-- Transfoms a class declaration into a class unit
rule AnonymousClassDeclarationToClassUnit extends ASTNodeToAbstractCodeElement {
	from src:java!AnonymousClassDeclaration
	using{
		-- For attributes, we have to separate FieldDeclaration and VariableDeclarationFragment usage
		javaAttributes :java!NamedElement = src.bodyDeclarations->select(e| e.oclIsTypeOf(java!FieldDeclaration))
			->collect(f| if (f.fragments->isEmpty()) then f else f.fragments endif);
		originalTypeAccess :java!TypeAccess = src.refImmediateComposite().type;
	}
	to tgt: kdm!ClassUnit(
		name <- 'Anonymous type'
		-- attributes
		,codeElement <- javaAttributes
		-- other elements
		,codeElement <- src.bodyDeclarations->select(e | not e.oclIsTypeOf(java!FieldDeclaration))
		-- imports
		,codeRelation <- if (src.originalCompilationUnit.oclIsUndefined()) then
					Sequence{}
				else
					src.originalCompilationUnit.imports
				endif
		-- inheritance
		,codeRelation <- if (originalTypeAccess.oclIsUndefined()) then
							Sequence{}
						else
							thisModule.CreateImplementsForTemplated(tgt, originalTypeAccess)
						endif
			
		-- TODO use superClass
		-- comments
		,comment <- src.comments 
		,comment <- if (src.originalCompilationUnit.oclIsUndefined()
						or not src.refImmediateComposite().oclIsTypeOf(java!Package)) then
					Sequence{}
				else -- top level type declaration -> retrieving CU heading comments
					src.originalCompilationUnit.comments
				endif
	)
}

-- ===================================================== ---
--  Rules for the interfaces
--  This part gives all the transformations for the interfaces of a java program
-- the transformations being quite different when the considered interface is generic (java meaning)
-- ===================================================== ---

-- Transfoms an interface
rule InterfaceDeclarationToInterfaceUnit extends AbstractTypeDeclarationToDatatype {
	from src:java!InterfaceDeclaration (
			src.typeParameters.isEmpty()
	)
	using{
		-- For attributes, we have to separate FieldDeclaration and VariableDeclarationFragment usage
		javaAttributes :java!NamedElement = src.bodyDeclarations->select(e| e.oclIsTypeOf(java!FieldDeclaration))
			->collect(f| if (f.fragments->isEmpty()) then f else f.fragments endif);	
	}
	to tgt:kdm!InterfaceUnit(
		-- attributes
		codeElement <- javaAttributes
		-- other elements
		,codeElement <- src.bodyDeclarations->select(e | not e.oclIsTypeOf(java!FieldDeclaration))
	)
}

-- ===================================================== ---
--  Rules for the Enums
--  This part gives the transformation for the enums of a java programm
-- ===================================================== ---

-- Transforms a enumerated type
rule EnumDeclarationToEnumeratedType extends AbstractTypeDeclarationToDatatype {
	from src : java!EnumDeclaration
	using{
		-- For attributes, we have to separate FieldDeclaration and VariableDeclarationFragment usage
		javaAttributes :java!NamedElement = src.bodyDeclarations->select(e| e.oclIsTypeOf(java!FieldDeclaration))
			->collect(f| if (f.fragments->isEmpty()) then f else f.fragments endif);	
	}
	to tgt : kdm!EnumeratedType(
		-- enumerated values
		value <- src.enumConstants
		-- TODO not allowed by kdm implementation !
		-- attributes
		,codeElement <- javaAttributes
		-- other elements
		,codeElement <- src.bodyDeclarations->select(e | not e.oclIsTypeOf(java!FieldDeclaration))
	)
}

-- transforms an array type into an array type
rule ArrayTypeToArrayType {
	from src :java!ArrayType
	to tgt :kdm!ArrayType (
		name <- src.name
		-- size attribute will contains dimension information instead of size
		,size <- src.dimensions
		,itemUnit <- realType
		,indexUnit <- indexUnit
	)
	, realType :kdm!ItemUnit (
		type <- src.elementType->getType()
	)
	, indexUnit : kdm!IndexUnit (
		type <- java!PrimitiveTypeInt.allInstances()->first()
	)
}

-- transforms a wild card into a TypeUnit (DefinedType)
rule WildCardTypeToTypeUnit {
	from src :java!WildCardType
	to tgt :kdm!TypeUnit (
		type <- if (src.bound.oclIsUndefined()) then
					OclUndefined
				else
					src.bound->getType()
				endif
	)
}

-- transforms an Annotation type into an InterfaceUnit (with an annotation)
rule AnnotationTypeDeclarationToInterfaceUnit extends AbstractTypeDeclarationToDatatype {
	from src :java!AnnotationTypeDeclaration
	using{
		-- For attributes, we have to separate FieldDeclaration and VariableDeclarationFragment usage
		javaAttributes :java!NamedElement = src.bodyDeclarations->select(e| e.oclIsTypeOf(java!FieldDeclaration))
			->collect(f| if (f.fragments->isEmpty()) then f else f.fragments endif);	
	}
	to tgt :kdm!InterfaceUnit (
		annotation <- annotation
		-- specific for annotation types, we have to redefine these initializations ???
		-- ATL mechanism of extends does not work very well ...
		,codeRelation <- src.annotations
		,codeRelation <- if (src.originalCompilationUnit.oclIsUndefined()) then
					Sequence{}
				else
					src.originalCompilationUnit.imports
				endif
		-- attributes
		,codeElement <- javaAttributes
		-- other elements, it should be AnnotationTypeMemberDeclaration
		,codeElement <- src.bodyDeclarations->select(e | not e.oclIsTypeOf(java!FieldDeclaration))
	)
	,annotation :kdm!Annotation (
		text <- 'annotation'
	)
}
-- transforms an AnnotationTypeMemberDeclaration into a MemberUnit
-- it is here because ATL superimposition does not allow rules extensions.
rule AnnotationTypeMemberDeclarationToMemberUnit extends BodyDeclarationToAbstractCodeElement {
	from src :java!AnnotationTypeMemberDeclaration
	to tgt :kdm!MemberUnit (
		type <- if (src.type.oclIsUndefined()) then
						OclUndefined
					else
						src.type->getType()
					endif
	)
}
-- ========================================================
--  Rules for generic types (class, interface)
-- ========================================================
-- Transfoms a type with generic declarations into a TemplateUnit containing a type unit
abstract rule TypeDeclarationToTemplateUnit {
	from src : java!TypeDeclaration (
			not src.typeParameters.isEmpty()
	)
	to tgt : kdm!TemplateUnit( -- template parameter should be first
			name <- src->getGenericName()
			,codeElement <- src.typeParameters
			,codeElement <- type
	)
	, type : kdm!Datatype (
		name <- src.name
		-- imports
		,codeRelation <- if (src.originalCompilationUnit.oclIsUndefined()) then
					Sequence{}
				else
					src.originalCompilationUnit.imports
				endif
		-- inheritance
		,codeRelation <- src.superInterfaces->collect(e | 
			if (src.oclIsTypeOf(java!ClassDeclaration)) then 
				thisModule.CreateImplementsForTemplated(type, e)
			else
				thisModule.CreateExtendsForTemplated(type, e)
			endif) -- end collect
		-- comments
		,comment <- src.comments
		,comment <- if (src.originalCompilationUnit.oclIsUndefined()
						or not src.refImmediateComposite().oclIsTypeOf(java!Package)) then
					Sequence{}
				else -- top level type declaration -> retrieving CU heading comments
					src.originalCompilationUnit.comments
				endif
		-- source file management
		,source <- sourceRef
		-- attributes to store additional informations (visibility stay redundant)
		,attribute <- if (src.modifier.oclIsUndefined()) then
						Sequence{}
					else
						src.modifier
					endif
		-- annotations
		,codeRelation <- src.annotations
	)
	,sourceRef : kdm!SourceRef (
		language <- 'java'
		,region <- sourceRegion
	)
	,sourceRegion : kdm!SourceRegion (
		language <- 'java'
-- size expensive and redundant with SourceFile information
--		,path <- if (src.originalCompilationUnit.oclIsUndefined()) then
--					'internal'
--				else
--					src.originalCompilationUnit.originalFilePath
--				endif
		,file <- if (src.originalCompilationUnit.oclIsUndefined()) then
					src.originalClassFile
				else
					src.originalCompilationUnit
				endif
	)
}
-- Transfoms a class with generic declarations into a TemplateUnit containing a class unit
rule ClassDeclarationToTemplateUnit extends TypeDeclarationToTemplateUnit {
	from src : java!ClassDeclaration (
			not src.typeParameters.isEmpty()
	)
	using{
		-- For attributes, we have to separate FieldDeclaration and VariableDeclarationFragment usage
		javaAttributes :java!NamedElement = src.bodyDeclarations->select(e| e.oclIsTypeOf(java!FieldDeclaration))
			->collect(f| if (f.fragments->isEmpty()) then f else f.fragments endif);	
	}
	to tgt : kdm!TemplateUnit()
	, type : kdm!ClassUnit(
		isAbstract <- if src.modifier.oclIsUndefined() then
						OclUndefined
					else
						src.modifier.inheritance = 'abstract'
					endif
		-- attributes
		,codeElement <- javaAttributes
		-- other elements
		,codeElement <- src.bodyDeclarations->select(e | not e.oclIsTypeOf(java!FieldDeclaration))
		
	)
	do {
		-- inheritance
		type.codeRelation <- if src.superClass.oclIsUndefined() then
							Sequence{}
						else
							thisModule.CreateExtendsForTemplated(type, src.superClass)
						endif;
	}
}
	
-- Transfoms a generic interface
rule InterfaceDeclarationToTemplateUnit extends TypeDeclarationToTemplateUnit {
	from src : java!InterfaceDeclaration(
			not src.typeParameters.isEmpty()
	)
	using{
		-- For attributes, we have to separate FieldDeclaration and VaraiableDeclarationFragment usage
		javaAttributes :java!NamedElement = src.bodyDeclarations->select(e| e.oclIsTypeOf(java!FieldDeclaration))
			->collect(f| if (f.fragments->isEmpty()) then f else f.fragments endif);	
	}
	to tgt : kdm!TemplateUnit()
	, type : kdm!InterfaceUnit(
		-- attributes
		codeElement <- javaAttributes
		-- other elements
		,codeElement <- src.bodyDeclarations->select(e | not e.oclIsTypeOf(java!FieldDeclaration))
	)
}

-- Transforms parameters declared by a generic type
rule TypeParameterToTemplateParameter {
	from src : java!TypeParameter
	to parameter : kdm!TemplateParameter (
		name <- src.name	
	)
}

-- ========================================================
--  Rules for usage of generic types
-- ========================================================

-- Transforms ParameterizedType to TemplateType
-- relationships ParameterTo link generic usage with type arguments
-- relationship InstanceOf links generic usage with generic type
rule ParameterizedTypeToTemplateType {
	from src : java!ParameterizedType
	to tgt : kdm!TemplateType (
		name <- src.name
		,codeRelation <- src.typeArguments->collect(t | thisModule->CreateParameterTo(t))
		,codeRelation <- typeLink
	)
	, typeLink : kdm!InstanceOf (
		from <- tgt
		,to <- if (src.type.type->oclIsKindOf(java!UnresolvedTypeDeclaration)) then
					OclUndefined -- typeParameters does not exist on UnresolvedTypeDeclaration
				else 
					if (src.type.type.typeParameters.isEmpty()) then
						OclUndefined
					else
						src.type->getType()
					endif
				endif
	)
}
	
-- ===================================================
-- CodeRelation section --
-- here is managed 'use' relations
-- and inheritance links (extends and implements)
-- ===================================================
	
-- Transforms an import declaration to an import declaration
rule ImportDeclarationToImports {
	from src : java!ImportDeclaration (
		not src.static	
	)
	to tgt : kdm!Imports(
			from <- src.refImmediateComposite().types->at(1),
			to <- src.importedElement->getExtendsType()
		)
}

--create the Extends for class or interface extension
lazy rule CreateExtends{
	from
		javaExtends:java!TypeAccess
	to
		kdmExtends:kdm!Extends(
			from <- javaExtends.refImmediateComposite(),
			to <- javaExtends->getType()
		)
}

lazy rule CreateExtendsForTemplated {
	from targetFrom :kdm!CodeItem, sourceTo :java!TypeAccess
	to tgt :kdm!Extends (
		from <- targetFrom
		,to <- sourceTo->getType()
	)
}

--create the Implements for interface implementation
lazy rule CreateImplements{
	from
		javaImplements:java!TypeAccess
	to 
		kdmImplements:kdm!Implements (
			from <- javaImplements.refImmediateComposite(),
			to <- javaImplements->getType()
		)
}

lazy rule CreateImplementsForTemplated {
	from targetFrom :kdm!CodeItem, sourceTo :java!TypeAccess
	to tgt :kdm!Implements (
		from <- targetFrom
		,to <- sourceTo->getType()
	)
}

-- create a class unit in case of extends relationships
unique lazy rule CreateClassUnit {
	from src : java!UnresovedItem
	to tgt : kdm!ClassUnit (
		name <- src.name
		)
}
-- create an interface unit in case of extends or implements relationships
unique lazy rule CreateInterfaceUnit {
	from src : java!UnresovedItem
	to tgt : kdm!InterfaceUnit (
		name <- src.name
		)
}

--create the ParameterTo for type arguments of generics usage
lazy rule CreateParameterTo{
	from
		src :java!TypeAccess
	to 
		tgt :kdm!ParameterTo (
			from <- src.refImmediateComposite(),
			to <- src->getType()
		)
}

-- ===================================================== ---
--  Rules for the primitive types
--  A primitive type can be translated into different types according to the "name" attribute
-- ===================================================== ---

--creates the Boolean primitive type
rule PrimitiveTypeBooleanToBooleanType{
	from 
		javaBoolean:java!PrimitiveTypeBoolean
	to
		kdmBoolean:kdm!BooleanType(
			name <- 'boolean'
		)
}
--creates the Byte primitive type
rule PrimitiveTypeByteToByteType{
	from 
		javaByte:java!PrimitiveTypeByte
	to
		kdmByte:kdm!OctetType(
			name <- 'byte'
		)
}
--creates the Char primitive type
rule PrimitiveTypeCharToCharType{
	from 
		javaChar:java!PrimitiveTypeChar
	to
		kdmChar:kdm!CharType(
			name <- 'char'
		)
}
--creates the Double primitive type
rule PrimitiveTypeDoubleToDoubleType{
	from 
		src:java!PrimitiveTypeDouble
	to
		kdmFLoat:kdm!FloatType(
			name <- 'double'
		)
}
--creates the Float primitive type
rule PrimitiveTypeFloatToFloatType{
	from 
		javaFloat:java!PrimitiveTypeFloat
	to
		kdmFloat:kdm!FloatType(
			name <- 'float'
		)
}
--creates the int primitive type
rule PrimitiveTypeIntToIntType{
	from 
		javaInt:java!PrimitiveTypeInt
	to
		kdmInteger:kdm!IntegerType(
			name  <- 'int'
		)
}
--creates the long primitive type
rule PrimitiveTypeLongToLongType{
	from 
		javaLong:java!PrimitiveTypeLong
	to
		kdmInteger:kdm!IntegerType(
			name <- 'long'
		)
}
--creates the short primitive type
rule PrimitiveTypeShortToShortType{
	from 
		javaShort:java!PrimitiveTypeShort
	to
		kdmInteger:kdm!IntegerType(
			name <- 'short'
		)
}
--creates the Void primitive type
rule PrimitiveTypeVoidToVoidType{
	from 
		javaVoid:java!PrimitiveTypeVoid
	to
		kdmVoid:kdm!VoidType(
			name <- 'void'
		)
}

-- ===================================================== ---
--  Rules for the artefacts of a program
--  
-- ===================================================== ---

rule CompilationUnitToSourceFile {
	from src : java!CompilationUnit
	to tgt : kdm!SourceFile (
		name <- src.name
		,language <- 'java'
		,path <- src.originalFilePath
	)
}

rule ArchiveToBinaryFile {
	from src : java!Archive
	to tgt : kdm!BinaryFile (
		path <- src.originalFilePath
		-- version <- TODO retrieve version from Manifest infos ?
	)
}

-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################

-- StructureWithMembers

-- helpers --

--returns an element of the ExportKind enumeration to set the visibility of the field or method
helper context java!BodyDeclaration def : getVisibility() : kdm!ExportKind = 
		if (self.modifier.oclIsUndefined()) then
			#unknown
		else
			if self.modifier.visibility.oclIsUndefined() then 
				#unknown
			else 
				if (self.modifier.visibility = #public)	then 
					#public
				else
					if (self.modifier.visibility = #protected) then
						#protected
					else
						if (self.modifier.visibility = #none) then
							if (self.abstractTypeDeclaration.oclIsTypeOf(java!InterfaceDeclaration)) then
								#public
							else
								#protected
							endif
						else
							#private
						endif
					endif			
				endif
			endif
		endif;

-- rules --

-- ===================================================
-- Transformation of attributes : Field, EnumConstant, AnnotationTypeMemberDeclaration
-- ===================================================

-- ===================================================== ---
--  Rules for the Fields
--  This part gives the transformation for the fields of a java type
-- ===================================================== ---

--create the classes and interface attributes
-- Hope : kdm does not allow interface attributes ! we have to change it
rule FieldDeclarationToMemberUnit extends BodyDeclarationToAbstractCodeElement {
	from src :java!FieldDeclaration (src.fragments->isEmpty())
	to tgt :kdm!MemberUnit(
		export <- src->getVisibility()	
		,type <- if (src.type.oclIsUndefined()) then
					OclUndefined
				else
					src.type->getType()
				endif
		,comment<-src.comments
	)
}



-- Transfoms an enumeration constant into a value
rule EnumConstantDeclarationToValue extends BodyDeclarationToAbstractCodeElement {
	from src : java!EnumConstantDeclaration
	to tgt : kdm!Value(
			name <- 'enum literal'
			,ext <- src.name
			,type <- src.refImmediateComposite()
			-- TODO waiting for a strategy for constant arguments
	)
}



-- ===================================================== ---
--  Rules for the methods
--  This part gives all the transformations for the methods
-- the transformations being quite different when the considered method is generic
-- ===================================================== ---

-- Transforms a method into a method unit
rule MethodDeclarationToMethodUnit extends BodyDeclarationToAbstractCodeElement {
	from src : java!AbstractMethodDeclaration(
			src.typeParameters.isEmpty()
		--and
			-- Anonymous types are not translated in kdm
			--src.anonymousClassDeclarationOwner.oclIsUndefined()
	)
	to tgt : kdm!MethodUnit(
		kind <- if (src.oclIsKindOf(java!ConstructorDeclaration)) then #constructor else #method endif
		,export <- src->getVisibility()
		-- signature management
		,type <- signature
		,codeElement <- signature
		-- body (block)
		,codeElement <- if (src.body.oclIsUndefined()) then Sequence{} else src.body endif
	)
	,signature : kdm!Signature(
		name <- src.name
		-- return parameter
		,parameterUnit <- if (src.oclIsKindOf(java!ConstructorDeclaration)) then
							Sequence{}
						  else 
						  	if (src.returnType.oclIsUndefined()) then
								Sequence{}
							else
								thisModule.CreateReturnParameterUnit(src.returnType)
							endif
						endif
		-- usual parameters
		,parameterUnit <- src.parameters
		-- exceptions thrown
		,parameterUnit <- src.thrownExceptions->collect(e | thisModule.CreateExceptionParameterUnit(e))
	)
	do {
		-- redefinitions / redefined MethodDeclaration
		tgt.codeRelation <- if (src.oclIsKindOf(java!ConstructorDeclaration)) then
							Sequence{}
						else 
							if (src.redefinedMethodDeclaration.oclIsUndefined()) then
								Sequence{}
							else
								thisModule.CreateImplementationOf(src, src.redefinedMethodDeclaration)
							endif
						endif;
		
	}
}

-- Transforms a method into a method unit
rule MethodDeclarationToTemplateUnit {
	from src : java!AbstractMethodDeclaration(
			(not src.typeParameters.isEmpty())
		--and
			-- Anonymous types are not translated in kdm
			--src.anonymousClassDeclarationOwner.oclIsUndefined()
	)
	to tgt : kdm!TemplateUnit( -- template parameter should be first
			name <- src.name
			,codeElement <- src.typeParameters
			,codeElement <- method
	)
	,method : kdm!MethodUnit(
			name <- src.name
			,kind <- if (src.oclIsKindOf(java!ConstructorDeclaration)) then #constructor else #method endif
			,export <- src->getVisibility()
			-- signature management
			,type <- signature
			,codeElement <- signature
			-- attributes to store additional information (visibility stay redundant)
			,attribute <- if (src.modifier.oclIsUndefined()) then
						Sequence{}
					else
						src.modifier
					endif
			-- annotations
			,codeRelation <- src.annotations
			-- comments
			,comment <- src.comments
			-- body (block)
			,codeElement <- if (src.body.oclIsUndefined()) then Sequence{} else src.body endif
			-- redefinitions / redefined MethodDeclaration
			,codeRelation <- if (src.oclIsKindOf(java!ConstructorDeclaration)) then
								Sequence{}
							else
								if (src.redefinedMethodDeclaration.oclIsUndefined()) then
									Sequence{}
								else
									thisModule.CreateImplementationOf(src, src.redefinedMethodDeclaration)
								endif
							endif
			-- source file management
			,source <- sourceRef
		)
		,sourceRef : kdm!SourceRef (
			language <- 'java'
			,region <- sourceRegion
		)
		,sourceRegion : kdm!SourceRegion (
			language <- 'java'
-- size expensive and redundant with SourceFile information
--		,path <- if (src.originalCompilationUnit.oclIsUndefined()) then
--					'internal'
--				else
--					src.originalCompilationUnit.originalFilePath
--				endif
			,file <- if (src.originalCompilationUnit.oclIsUndefined()) then
					src.originalClassFile
				else
					src.originalCompilationUnit
				endif
		)		
	,signature : kdm!Signature(
		name <- src.name
		-- return parameter
		,parameterUnit <- if (src.oclIsKindOf(java!ConstructorDeclaration)) then
								Sequence{}
							else
								if (src.returnType.oclIsUndefined()) then
									Sequence{}
								else
									thisModule.CreateReturnParameterUnit(src.returnType)
								endif
							endif
		-- usual parameters
		,parameterUnit <- src.parameters
		-- exceptions thrown
		,parameterUnit <- src.thrownExceptions->collect(e | thisModule.CreateExceptionParameterUnit(e))
	)
}

-- transforms a Block into a BlockUnit, it is here just to do articulation
-- between members and statements/expressions.
rule BlockToBlockUnit extends ASTNodeToAbstractCodeElement {
	from src : java!Block
	to tgt : kdm!BlockUnit(
		codeElement <- if (src.statements->isEmpty()) then Sequence{} else src.statements endif
	)
}

rule CommentToCommentUnit {
	from src : java!Comment (
		-- Anonymous types are not translated in kdm
		not src.refImmediateComposite().oclIsTypeOf(java!AnonymousClassDeclaration)
		and
		-- kdm!Imports can not own comments
		not src.refImmediateComposite().oclIsTypeOf(java!ImportDeclaration)
		and
		-- Some expressions are not managed
		not (src.refImmediateComposite().oclIsKindOf(java!Expression)
			 and thisModule->filterExpression(src.refImmediateComposite())->isEmpty())
		-- 
--		not src.refImmediateComposite().oclIsTypeOf(java!TypeAccess)
--		and
--		not src.refImmediateComposite().oclIsTypeOf(java!SingleVariableAccess)
	)
	to tgt : kdm!CommentUnit(
		text <- src.content
	)
}

-- to explicit relationship between methods
lazy rule CreateImplementationOf {
	from src :java!MethodDeclaration
		, redefined : java!MethodDeclaration
	to tgt :kdm!ImplementationOf (
		from <- src
		,to <- redefined
	)
}

-- ===================================================== ---
--  Rules for the method Parameters
--  This part gives the transformation for the parameters of a Java method
-- ===================================================== ---

-- Transforms a method parameter (other cases should be handled in further transformations)
rule SingleVariableDeclarationToParameterUnit extends NamedElementToAbstractCodeElement {
	from src : java!SingleVariableDeclaration (
			-- only for MethodDeclaration !
			if (src.methodDeclaration.oclIsUndefined()) then
				false
			else
				-- Anonymous types are not translated in kdm
				--src.methodDeclaration.anonymousClassDeclarationOwner.oclIsUndefined()
				true
			endif
	)
	to tgt : kdm!ParameterUnit(
			kind <- #unknown
			,type <- src.type->getType()
	)
}

--create the return Parameter
lazy rule CreateReturnParameterUnit {
	from src :java!TypeAccess
	to kdmParameter:kdm!ParameterUnit (
			kind <- #return,
			type <- src->getType()
			-- source file management
			,source <- sourceRef
		)
		,sourceRef : kdm!SourceRef (
			language <- 'java'
			,region <- sourceRegion
		)
		,sourceRegion : kdm!SourceRegion (
			language <- 'java'
-- size expensive and redundant with SourceFile information
--		,path <- if (src.originalCompilationUnit.oclIsUndefined()) then
--					'internal'
--				else
--					src.originalCompilationUnit.originalFilePath
--				endif
			,file <- if (src.originalCompilationUnit.oclIsUndefined()) then
					src.originalClassFile
				else
					src.originalCompilationUnit
				endif
		)
}

--create the exception Parameter
lazy rule CreateExceptionParameterUnit{
	from src :java!TypeAccess
	to kdmParameter:kdm!ParameterUnit (
			kind <- #throws,
			type <- src->getType()
			-- source file management
			,source <- sourceRef
		)
		,sourceRef : kdm!SourceRef (
			language <- 'java'
			,region <- sourceRegion
		)
		,sourceRegion : kdm!SourceRegion (
			language <- 'java'
-- size expensive and redundant with SourceFile information
--		,path <- if (src.originalCompilationUnit.oclIsUndefined()) then
--					'internal'
--				else
--					src.originalCompilationUnit.originalFilePath
--				endif
			,file <- if (src.originalCompilationUnit.oclIsUndefined()) then
					src.originalClassFile
				else
					src.originalCompilationUnit
				endif
		)
}

-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################

-- Statements

-- helpers --


-- rules --

-- handling statements and expressions :
	-- everything must go through an ActionElement : indeed, "action relationships" can only
	-- be owned by an ActionElement ...
	-- alternatively, they can be put in the codeElement collection? Is it correct?
-- because of this limitation, all expressions will be expressed as ActionElement's also (like statements)
-- and action relationships will be explicitly created instead of using mapping.
-- so for each expression we will have one ActionElement and perhaps one or more ActionRelation.

-- ===================================================
-- Transformation of code in blocks: if, while, for, etc.
-- There are 23 statements in all, but Block is already handled by the parent transformation
-- ===================================================

-- AssertStatement
rule AssertStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!AssertStatement
	to tgt :kdm!ActionElement(
		kind <- 'assert'
		,name <- 'assert'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,codeElement <- if(src.message.oclIsUndefined()) then Sequence{} else Sequence{src.message} endif
	)
}

-- BreakStatement
rule BreakStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!BreakStatement
	to tgt :kdm!ActionElement(
		kind <- 'break'
		-- referenced elements
		, actionRelation <- if (src.label.oclIsUndefined()) then Sequence{} else thisModule->CreateCallsForLabel(src) endif
	)
}

-- create a Calls from a Method invocation (target element is binding with a TemplateUnit and we want a MethodUnit !)
lazy rule CreateCallsForGenericMethod {
	from src :java!AbstractMethodInvocation
	to tgt :kdm!Calls(
		from <- src
		,to <- thisModule.resolveTemp(src.method, 'method')
	)
}

-- create a Calls from a Method invocation
lazy rule CreateCalls {
	from src :java!AbstractMethodInvocation (
		-- Methods from anonymous types will not be translated
		-- because they will not have owners in kdm
		src.method.anonymousClassDeclarationOwner.oclIsUndefined()
	)
	to tgt :kdm!Calls(
		from <- src
		,to <- src.method
	)
}

-- create a Calls from a Label goto
lazy rule CreateCallsForLabel {
	from src :java!Statement
	to tgt :kdm!Calls(
		from <- src
		,to <- src.label
	)
}

-- CatchClause
rule CatchClauseToCatchUnit extends ASTNodeToAbstractCodeElement {
	from src : java!CatchClause
	to tgt :kdm!CatchUnit(
		kind <- 'catch'
		,name <- 'catch'
		-- referenced elements
		,codeElement <- if(src.body.oclIsUndefined()) then Sequence{} else src.body endif
		,codeElement <- if(src.exception.oclIsUndefined()) then Sequence{} else src.exception endif
		,actionRelation <- exceptionFlow
	)
	,exceptionFlow :kdm!ExceptionFlow (
		from <- src.refImmediateComposite()
		,to <- src
	)
}

-- Transforms a method parameter (other cases should be handled in further transformations)
rule SingleVariableDeclarationToStorableUnit extends NamedElementToAbstractCodeElement {
	from src : java!SingleVariableDeclaration (
		-- only for CatchClause and EnhancedForStatement !
		src.methodDeclaration.oclIsUndefined()
	)
	to tgt : kdm!StorableUnit(
		kind <- #local
		-- attributes to store additional information (final, etc.)
		,attribute <- if (src.modifier.oclIsUndefined()) then
						Sequence{}
					else
						src.modifier
					endif
		,type <- src.type->getType()
		,codeElement <- if (src.initializer.oclIsUndefined()) then Sequence{} else Sequence{src.initializer} endif	
	)
}

-- ConstructorInvocation
rule ConstructorInvocationToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ConstructorInvocation
	to tgt :kdm!ActionElement(
		kind <- 'constructor invocation'
		-- referenced elements
		,actionRelation <- if (src.method.oclIsUndefined()) then Sequence{} else
			if (src.method.typeParameters.isEmpty()) then
									thisModule->CreateCalls(src)
								else 
									thisModule->CreateCallsForGenericMethod(src)
								endif
			endif
		,codeElement <- src.arguments
	)
}

-- ContinueStatement
rule ContinueStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ContinueStatement
	to tgt :kdm!ActionElement(
		kind <- 'continue'
		,name <- 'continue'
		-- referenced elements
		, actionRelation <- if (src.label.oclIsUndefined()) then Sequence{} else thisModule->CreateCallsForLabel(src) endif
	)
}

-- DoStatement
rule DoStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!DoStatement
	to tgt :kdm!ActionElement(
		kind <- 'do'
		,name <- 'do'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,codeElement <- if(src.body.oclIsUndefined()) then Sequence{} else src.body endif
	)
}

-- EmptyStatement
rule EmptyStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!EmptyStatement
	to tgt :kdm!ActionElement(
		kind <- 'empty'
		,name <- 'empty'
		-- referenced elements
	)
}

-- EnhancedForStatement
rule EnhancedForStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!EnhancedForStatement
	to tgt :kdm!ActionElement(
		kind <- 'foreach'
		,name <- 'foreach'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,codeElement <- if(src.body.oclIsUndefined()) then Sequence{} else src.body endif
		,codeElement <- if(src.parameter.oclIsUndefined()) then Sequence{} else src.parameter endif
	)
}

-- ExpressionStatement
rule ExpressionStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ExpressionStatement
	to tgt :kdm!ActionElement(
		kind <- 'expression statement'
		,name <- 'expression statement'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
	)
}

-- ForStatement
rule ForStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ForStatement
	to tgt :kdm!ActionElement(
		kind <- 'for'
		,name <- 'for'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,codeElement <- src.initializers
		,codeElement <- src.updaters
		,codeElement <- if(src.body.oclIsUndefined()) then Sequence{} else src.body endif
	)
}

-- IfStatement
rule IfStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!IfStatement
	to tgt :kdm!ActionElement(
		kind <- 'if'
		,name <- 'if'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,codeElement <- if(src.thenStatement.oclIsUndefined()) then Sequence{} else src.thenStatement endif
		,codeElement <- if(src.elseStatement.oclIsUndefined()) then Sequence{} else src.elseStatement endif
	)
}

-- LabeledStatement
rule LabeledStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!LabeledStatement
	to tgt :kdm!ActionElement(
		kind <- 'label'
		,name <- 'label'
		-- referenced elements
		,codeElement <- if(src.body.oclIsUndefined()) then Sequence{} else src.body endif
	)
}

-- ReturnStatement
rule ReturnStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ReturnStatement
	to tgt :kdm!ActionElement(
		kind <- 'return'
		,name <- 'return'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
	)
}

-- SuperConstructorInvocation
rule SuperConstructorInvocationToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!SuperConstructorInvocation
	to tgt :kdm!ActionElement(
		kind <- 'super constructor invocation'
		,name <- 'super constructor invocation'
		-- referenced elements
		,actionRelation <- if (src.method.oclIsUndefined()) then Sequence{} else
			if (src.method.typeParameters.isEmpty()) then
									thisModule->CreateCalls(src)
								else 
									thisModule->CreateCallsForGenericMethod(src)
								endif
			endif
		,codeElement <- src.arguments->collect(e | thisModule->filterExpression(e))->flatten()
		,codeElement <- thisModule->filterExpression(src.expression)
	)
}

-- SwitchCase
rule SwitchCaseToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!SwitchCase
	to tgt :kdm!ActionElement(
		kind <- 'case'
		,name <- 'case'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
	)
}

-- SwitchStatement
rule SwitchStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!SwitchStatement
	to tgt :kdm!ActionElement(
		kind <- 'switch'
		,name <- 'switch'
		-- referenced elements
		,actionRelation <- 
			if(src.expression.oclIsUndefined()) then 
            	Sequence{}
			else 
				if (src.expression.oclIsTypeOf(java!SingleVariableAccess)) then
		    		thisModule->CreateReads(src.expression)
				else
					Sequence{}
				endif
			endif
		,codeElement <- thisModule->filterExpression(src.expression)
		,codeElement <- src.statements
	)
}

-- SynchronizedStatement
rule SynchronizedStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!SynchronizedStatement
	to tgt :kdm!ActionElement(
		kind <- 'synchronized'
		,name <- 'synchronized'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,codeElement <- if(src.body.oclIsUndefined()) then Sequence{} else src.body endif
	)
}

-- ThrowStatement
rule ThrowStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ThrowStatement
	to tgt :kdm!ActionElement(
		kind <- 'throw'
		,name <- 'throw'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
	)
}

-- TypeDeclarationStatement
rule TypeDeclarationStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!TypeDeclarationStatement
	to tgt :kdm!ActionElement(
		kind <- 'type declaration'
		,name <- 'type declaration'
		-- referenced elements
		,codeElement <- if(src.declaration.oclIsUndefined()) then Sequence{} else src.declaration endif
	)
}

-- TryStatement
rule TryStatementToTryUnit extends ASTNodeToAbstractCodeElement {
	from src : java!TryStatement
	to tgt :kdm!TryUnit(
		kind <- 'try'
		,name <- 'try'
		-- referenced elements
		,codeElement <- if(src.body.oclIsUndefined()) then Sequence{} else src.body endif
		,codeElement <- if(src.finally.oclIsUndefined()) then Sequence{} else src.finally endif
		,codeElement <- src.catchClauses
	)
}

-- VariableDeclarationStatement
rule VariableDeclarationStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!VariableDeclarationStatement
	to tgt :kdm!ActionElement(
		kind <- 'variable declaration'
		,name <- 'variable declaration'
		-- referenced elements
		,codeElement <- src.fragments
		,codeRelation <- src.annotations
		-- management of fragments initializers (when it is a class instance creation)
		,codeElement <- src.fragments->select(fragment | fragment.initializer.oclIsTypeOf(java!ClassInstanceCreation))
									->collect(fragment | fragment.initializer)
	)
}

-- VariableDeclarationFragment
-- Transforms a local variable
-- we have to find a solution to store action element potentially
-- created from initializer.
-- However, in a storable unit, we cannot contain action elements directly ...

rule VariableDeclarationFragmentInLocalDeclarationToStorableUnit extends NamedElementToAbstractCodeElement {
	from src : java!VariableDeclarationFragment (
		-- not for FieldDeclaration !
		not src.variablesContainer.oclIsKindOf(java!FieldDeclaration)
	)
	to tgt : kdm!StorableUnit(
		name <- src.name
		,kind <- #local
		-- attributes to store additional information (final, etc.)
		,attribute <- if (src.refImmediateComposite().oclIsTypeOf(java!Model)) then -- Unresolved items
						Sequence{}
					else
						if (src.refImmediateComposite().modifier.oclIsUndefined()) then
							Sequence{}
						else
							src.refImmediateComposite().modifier
						endif
					endif
		,type <- if (src.variablesContainer.oclIsUndefined()) then OclUndefined -- Unresolved items
				 else 
				 	if (src.variablesContainer.type.oclIsUndefined()) then OclUndefined
				 	else src.variablesContainer.type->getType() endif
				 endif
		,codeRelation <- if (src.initializer.oclIsUndefined()) then Sequence{}
						else thisModule->CreateHasValue(src, src.initializer) endif
		-- in some cases, if initializer is a complex expression,
		-- we don't know how to store created elements in the storable unit
		
	)
}

lazy rule CreateHasValue {
	from src : java!VariableDeclaration,
		value : java!Expression
	to tgt : kdm!HasValue (
		from <- src
		,to <- if (value.oclIsTypeOf(java!SingleVariableAccess)) then
					value.variable
				else
					if (value.oclIsTypeOf(java!UnresolvedItemAccess)) then
						-- TODO add a better management of unresolved items ...
						thisModule->CreateDatatype(value) -- type of element is java!UnresolvedItem
					else
						value
					endif
				endif
	)
}

lazy rule CreateDatatype {
	from src : java!UnresolvedItemAccess
	to tgt : kdm!Datatype (
		name <- src.element.name
	)
}
-- VariableDeclarationFragment
-- Transforms a global variable (other cases should be handled in further transformations)
rule VariableDeclarationFragmentInFieldToStorableUnit extends NamedElementToAbstractCodeElement {
	from src : java!VariableDeclarationFragment (
		-- only for FieldDeclaration !
		src.variablesContainer.oclIsKindOf(java!FieldDeclaration)
	)
	to tgt : kdm!StorableUnit(
		kind <- if (src.variablesContainer.modifier.oclIsUndefined()) then
					#global
				else
					if (src.variablesContainer.modifier.static) then
						#static
					else
						#global
					endif
				endif
		-- attributes to store additional information (final, etc.)
		,attribute <- if src.variablesContainer.modifier.oclIsUndefined() then
						Sequence{}
					else
						src.variablesContainer.modifier
					endif
		,type <- if (src.variablesContainer.type.oclIsUndefined()) then OclUndefined
					else src.variablesContainer.type->getType() endif
		-- ok, but how to store action element that will be potentially created from initializer ?
		,codeRelation <- if (src.initializer.oclIsUndefined()) then Sequence{}
						else thisModule->CreateHasValue(src, src.initializer) endif
		,codeRelation <- src.variablesContainer.annotations
		,comment<-src.variablesContainer.comments
	)
}

-- WhileStatement
rule WhileStatementToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!WhileStatement
	to tgt :kdm!ActionElement(
		kind <- 'while'
		,name <- 'while'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,codeElement <- if(src.body.oclIsUndefined()) then Sequence{} else src.body endif
	)
}

-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################
-- ##########################################################################

-- Expressions

-- rules --


-- handling statements and expressions :
	-- everything must go through an ActionElement : indeed, "action relationships" can only
	-- be owned by an ActionElement ...
	-- alternatively, they can be put in the codeElement collection? Is it correct?
-- because of this limitation, all expressions will be expressed as ActionElement's also (like statements)
-- and action relationships will be explicitly created instead of using mapping.
-- so for each expression we will have one ActionElement and perhaps one or more ActionRelation.

-- ===================================================
-- Transformation of code in blocks: if, while, for, etc.
--
-- There are 27 statements in all.
-- But some model elements will also be handled (AnnotationMemberValuePair for example)
-- ===================================================

-- As explained below, for each expression we will be mapping to an ActionElement
-- and this is this element that will be able to contain ActionRelation!

-- Annotation
-- specific case
-- an annotation is always applied on a body declaration element,
-- so it should be mapped to a subclass of AbstractCodeRelationship
--rule AnnotationToActionElement extends ASTNodeToAbstractCodeElement {
--	from src : java!Annotation
--	to tgt :kdm!ActionElement(
--		kind <- 'annotation'
--		,name <- 'annotation'
		-- referenced elements
--		,actionRelation <- if(src.type.oclIsUndefined()) then Sequence{} else thisModule->CreateCreates(src.type) endif
--		,codeElement <- src.values -- collection
--	)
--}

rule AnnotationToHasValue {
	from src : java!Annotation (
				-- specific filter for annotation as value of another annotation (single value or array)
				not src.refImmediateComposite().oclIsTypeOf(java!AnnotationMemberValuePair)
				--and not src.refImmediateComposite().oclIsTypeOf(java!ArrayInitializer)
	)
	to tgt :kdm!HasValue(
		from <- src->filterRefImmediateCompositeForAnnotation()
		,to <- src.type->getType()
		-- specify that it is an annotation
		,annotation <- annotation
		-- store parameters as attributes
		,attribute <- src.values
	)
	, annotation :kdm!Annotation(
		text <- 'annotation'
	)
}

-- specific case for field declarations that have an annotation
-- if the field declaration has fragments, then the HasValue.form should use the fragment.
helper context java!Annotation def : filterRefImmediateCompositeForAnnotation() : OclAny =
	if (self.refImmediateComposite().oclIsTypeOf(java!FieldDeclaration)) then
		if (self.refImmediateComposite().fragments->isEmpty()) then
			self.refImmediateComposite()
		else
			self.refImmediateComposite().fragments->first()
		endif
	else
		if (self.refImmediateComposite().oclIsTypeOf(java!VariableDeclarationStatement)) then
			self.refImmediateComposite().fragments->first()
		else
			if (self.refImmediateComposite().oclIsTypeOf(java!ArrayInitializer)
					or self.refImmediateComposite().oclIsTypeOf(java!AnnotationMemberValuePair)) then
				OclUndefined
			else
				self.refImmediateComposite()
			endif
		endif
	endif;

lazy rule CreateCreates {
	from src :java!TypeAccess
	to tgt :kdm!Creates (
		from <- src.refImmediateComposite()
		,to <- src->getType()
	)
}

-- AnnotationMemberValuePair
--rule AnnotationMemberValuePairToActionElement extends NamedElementToAbstractCodeElement {
--	from src : java!AnnotationMemberValuePair
--	to tgt :kdm!ActionElement(
--		kind <- 'annotation member value'
--		,name <- 'annotation member value'
--		-- referenced elements
--		,actionRelation <- if(src.member.oclIsUndefined()) then Sequence{} else thisModule->CreateWritesForAnnotationMember(src) endif
--		,codeElement <- if(src.value.oclIsUndefined()) then Sequence{} else Sequence{src.value} endif
--	)
--}

-- TODO Works only for values which are literals, not values which are code expressions (uncommon use case)
rule AnnotationMemberValuePairToAttribute {
	from src : java!AnnotationMemberValuePair
	to tgt :kdm!Attribute(
		tag <- if(src.member.oclIsUndefined()) then 'no member' else src.member.name endif
		,value <- if(src.value.oclIsUndefined()) 
					then 'no value' 
					else 
						if (src.value.oclIsKindOf(java!NumberLiteral)) then
							src.value.tokenValue.toString()
						else
							if (src.value.oclIsKindOf(java!StringLiteral) or 
									src.value.oclIsKindOf(java!CharacterLiteral)) then
								src.value.escapedValue
							else
								if (src.value.oclIsKindOf(java!BooleanLiteral)) then
									src.value.value.toString()
								else
									if (src.value.oclIsKindOf(java!Annotation)) then
										src.value.type.type.name
									else
										'value expression'
									endif
								endif
							endif
						endif
					endif
	)
}

lazy rule CreateWritesForAnnotationMember {
	from src :java!AnnotationMemberValuePair
	to tgt :kdm!Writes (
		from <- src
		,to <- src.member
	)
}

lazy rule CreateWritesForVariableAccess {
	from src :java!SingleVariableAccess
	to tgt :kdm!Writes (
		from <- src.refImmediateComposite()
		,to <- src.variable
	)
}


-- ArrayAccess
rule ArrayAccessToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ArrayAccess
	to tgt :kdm!ActionElement(
		kind <- 'array access'
		,name <- 'array access'
		-- referenced elements
		-- if attribut "array" is a reference (access), we have to create corresponding relationship
		,codeElement <- thisModule->filterExpression(src.array)
		,actionRelation <- if(src.array.oclIsUndefined()) then 
							Sequence{} 
						else 
							if (src.array.oclIsTypeOf(java!SingleVariableAccess)) then
								thisModule->CreateAddresses(src.array)
							else
								Sequence{}
							endif
						endif
		,codeElement <- thisModule->filterExpression(src.index)
	)
}

-- ArrayCreation
rule ArrayCreationToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ArrayCreation
	to tgt :kdm!ActionElement(
		kind <- 'array creation'
		,name <- 'array creation'
		-- referenced elements
		,actionRelation <- if(src.type.oclIsUndefined()) then Sequence{} else thisModule->CreateCreates(src.type) endif
		,codeElement <- src.dimensions->collect(e | thisModule->filterExpression(e))->flatten()
		,codeElement <- thisModule->filterExpression(src.initializer)
	)
}

-- ArrayInitializer
rule ArrayInitializerToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ArrayInitializer (
		-- filter initialier of AnnotationMemberValuePair
		not src.refImmediateComposite().oclIsTypeOf(java!AnnotationMemberValuePair)
	)
	to tgt :kdm!ActionElement(
		kind <- 'array initializer'
		,name <- 'array initializer'
		-- referenced elements
		,codeElement <- src.expressions->select(e | not e.oclIsTypeOf(java!Annotation))
							->collect(e | thisModule->filterExpression(e))->flatten()
		-- referenced elements
		,codeRelation <- src.expressions->select(e | e.oclIsTypeOf(java!Annotation))
	)
}

-- ArrayLengthAccess
rule ArrayLengthAccessToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ArrayLengthAccess
	to tgt :kdm!ActionElement(
		kind <- 'array length access'
		,name <- 'array length access'
		-- referenced elements
		-- TODO should we create a Reads object ? the length field doesn't exist, so ...
		,codeElement <- thisModule->filterExpression(src.array)
	)
}

-- Assignment
rule AssignmentToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!Assignment
	to tgt :kdm!ActionElement(
		kind <- 'assignment'
		-- operator
		,name <- if (src.operator.oclIsUndefined()) then 'assignment' else src.operator.toString() endif
		-- referenced elements
		-- left hand side
		,actionRelation <- if(src.leftHandSide.oclIsUndefined()) then Sequence{} else 
							if (src.leftHandSide.oclIsTypeOf(java!SingleVariableAccess)) then
								thisModule->CreateWritesForVariableAccess(src.leftHandSide)
							else
								Sequence{}
							endif
						endif
		,codeElement <- thisModule->filterExpression(src.leftHandSide)
		-- right hand side
		,actionRelation <- if(src.rightHandSide.oclIsUndefined()) then Sequence{} else 
							if (src.rightHandSide.oclIsTypeOf(java!SingleVariableAccess)) then
								thisModule->CreateReads(src.rightHandSide)
							else
								Sequence{}
							endif
						endif
		,codeElement <- thisModule->filterExpression(src.rightHandSide)
	)
}

-- generally apply to fields
lazy rule CreateReads {
	from src :java!SingleVariableAccess
	to tgt :kdm!Reads (
		from <- src.refImmediateComposite()
		,to <- src.variable
	)
}

-- BooleanLiteral
rule BooleanLiteralToValue extends ASTNodeToAbstractCodeElement {
	from src : java!BooleanLiteral
	to tgt :kdm!Value(
		name <- 'boolean literal'
		,ext <- if (src.value) then 'true' else 'false' endif
		,type <- kdm!BooleanType.allInstances()->first()
	)
}


-- CastExpression
rule CastExpressionToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!CastExpression
	to tgt :kdm!ActionElement(
		kind <- 'cast'
		,name <- 'cast'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,actionRelation <- if(src.type.oclIsUndefined()) then Sequence{} else thisModule->CreateUsesType(src.type) endif
	)
}

-- generally apply to cast or type conversion
lazy rule CreateUsesType {
	from src :java!TypeAccess
	to tgt :kdm!UsesType (
		from <- src.refImmediateComposite()
		,to <- src.type
	)
}

-- CharacterLiteral
rule CharacterLiteralToValue extends ASTNodeToAbstractCodeElement {
	from src : java!CharacterLiteral
	to tgt :kdm!Value(
		name <- 'character literal'
		,ext <- src.escapedValue
		,type <- kdm!CharType.allInstances()->first()
	)
}

-- ClassInstanceCreation
rule ClassInstanceCreationToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ClassInstanceCreation
	to tgt :kdm!ActionElement(
		kind <- 'class instance creation'
		,name <- 'class instance creation'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,codeElement <- src.arguments->collect(e | thisModule->filterExpression(e))->flatten()
		-- anonymous type are contained by class instance creation
		,codeElement <- if (src.anonymousClassDeclaration.oclIsUndefined()) then Sequence{} else src.anonymousClassDeclaration endif
		,actionRelation <- if(src.method.oclIsUndefined()) then Sequence{} else thisModule->CreateCalls(src) endif
		,actionRelation <- if(src.type.oclIsUndefined()) then Sequence{} else thisModule->CreateCreates(src.type) endif
		
	)
}

-- ConditionalExpression
rule ConditionalExpressionToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ConditionalExpression
	to tgt :kdm!ActionElement(
		kind <- 'conditional'
		,name <- 'conditional'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,codeElement <- thisModule->filterExpression(src.thenExpression)
		,codeElement <- thisModule->filterExpression(src.elseExpression)
	)
}

-- FieldAccess
rule FieldAccessToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!FieldAccess
	to tgt :kdm!ActionElement(
		kind <- 'field access'
		,name <- 'field access'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,actionRelation <- if(src.field.oclIsUndefined()) then Sequence{} else thisModule->CreateAddresses(src.field) endif
	)
}

lazy rule CreateAddresses {
	from src :java!SingleVariableAccess
	to tgt :kdm!Addresses (
		from <- src.refImmediateComposite()
		,to <- src.variable
	)
}

-- InfixExpression
rule InfixExpressionToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!InfixExpression
	to tgt :kdm!ActionElement(
		kind <- 'infix expression'
		,name <- src.operator.toString()
		-- referenced elements
		,actionRelation <-
			if (src.leftOperand.oclIsUndefined()) then
				Sequence{}
			else
				if (src.leftOperand.oclIsTypeOf(java!SingleVariableAccess)) then
					thisModule -> CreateReads(src.leftOperand)
				else
					Sequence{}
				endif
			endif
		,actionRelation <-
			if (src.rightOperand.oclIsUndefined()) then
				Sequence{}
			else 
				if (src.rightOperand.oclIsTypeOf(java!SingleVariableAccess)) then
					thisModule -> CreateReads(src.rightOperand)
				else
					Sequence{}
				endif
			endif
		,codeElement <- thisModule->filterExpression(src.leftOperand)
		,codeElement <- thisModule->filterExpression(src.rightOperand)
		,codeElement <- src.extendedOperands->collect(e | thisModule->filterExpression(e))->flatten()
	)
}

-- InstanceofExpression
rule InstanceofExpressionToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!InstanceofExpression
	to tgt :kdm!ActionElement(
		kind <- 'instanceof'
		,name <- 'instanceof'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.leftOperand)
		,actionRelation <- if(src.rightOperand.oclIsUndefined()) then Sequence{} else thisModule->CreateUsesType(src.rightOperand) endif
	)
}

-- MethodInvocation
rule MethodInvocationToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!MethodInvocation
	to tgt :kdm!ActionElement(
		kind <- 'method invocation'
		,name <- 'method invocation'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
		,codeElement <- src.arguments->collect(e | thisModule->filterExpression(e))->flatten()
		,actionRelation <- if(src.method.oclIsUndefined()) then
								Sequence{}
							else
								if (src.method.typeParameters.isEmpty()) then
									thisModule->CreateCalls(src)
								else 
									thisModule->CreateCallsForGenericMethod(src)
								endif
							endif
	)
}


-- NullLiteral
rule NullLiteralToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!NullLiteral
	to tgt :kdm!ActionElement(
		kind <- 'null'
		,name <- 'null'
	)
}

-- NumberLiteral
rule NumberLiteralToValue extends ASTNodeToAbstractCodeElement {
	from src : java!NumberLiteral
	to tgt :kdm!Value(
		name <- 'number literal'
		,ext <- src.tokenValue
		-- TODO : find the real type (int, float, ...)
		,type <- kdm!IntegerType.allInstances()->first()
	)
}

-- ParenthesizedExpression
rule ParenthesizedExpressionToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ParenthesizedExpression
	to tgt :kdm!ActionElement(
		kind <- 'parenthesized'
		,name <- 'parenthesized'
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.expression)
	)
}

-- PostfixExpression
rule PostfixExpressionToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!PostfixExpression
	to tgt :kdm!ActionElement(
		kind <- 'postfix expression'
		,name <- src.operator.toString()
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.operand)
	)
}

-- PrefixExpression
rule PrefixExpressionToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!PrefixExpression
	to tgt :kdm!ActionElement(
		kind <- 'prefix expression'
		,name <- src.operator.toString()
		-- referenced elements
		,codeElement <- thisModule->filterExpression(src.operand)
	)
}

-- StringLiteral
rule StringLiteralToValue extends ASTNodeToAbstractCodeElement {
	from src : java!StringLiteral (
			-- TODO waiting for a strategy for storing enum constant arguments
			not src.refImmediateComposite().oclIsKindOf(java!EnumConstantDeclaration))
	to tgt :kdm!Value(
		name <- 'string literal'
		,ext <- src.escapedValue
		,type <- kdm!StringType.allInstances()->first()
	)
}

-- SuperFieldAccess
rule SuperFieldAccessToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!SuperFieldAccess
	to tgt :kdm!ActionElement(
		kind <- 'super field access'
		,name <- 'super field access'
		-- referenced elements
		,actionRelation <- if(src.field.oclIsUndefined()) then Sequence{} else thisModule->CreateUsesType(src.field) endif
		,actionRelation <- if(src.qualifier.oclIsUndefined()) then Sequence{} else
								if (src.qualifier.oclIsTypeOf(java!SingleVariableAccess)) then
									thisModule->CreateReads(src.qualifier)
								else
									-- because it might apply to a type sometimes
									-- YourType.super.yourmethod();
									Sequence{}
								endif
							endif
	)
}

-- SuperMethodInvocation
rule SuperMethodInvocationToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!SuperMethodInvocation
	to tgt :kdm!ActionElement(
		kind <- 'super method invocation'
		,name <- 'super method invocation'
		-- referenced elements
		,codeElement <- src.arguments->collect(e | thisModule->filterExpression(e))->flatten()
		,actionRelation <- if(src.method.oclIsUndefined()) then Sequence{} else
			if (src.method.typeParameters.isEmpty()) then
									thisModule->CreateCalls(src)
								else 
									thisModule->CreateCallsForGenericMethod(src)
								endif
			endif
		,actionRelation <- if(src.qualifier.oclIsUndefined()) then Sequence{} else
								if (src.qualifier.oclIsTypeOf(java!SingleVariableAccess)) then
									thisModule->CreateReads(src.qualifier)
								else
									-- because it might apply to a type sometimes
									-- YourType.super.yourmethod();
									Sequence{}
								endif
							endif
	)
}

-- ThisExpression
rule ThisExpressionToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!ThisExpression
	to tgt :kdm!ActionElement(
		kind <- 'this'
		,name <- 'this'
		-- referenced elements
		,actionRelation <- if(src.qualifier.oclIsUndefined()) then Sequence{} else thisModule->CreateUsesType(src.qualifier) endif
	)
}

-- TypeLiteral
rule TypeLiteralToValue extends ASTNodeToAbstractCodeElement {
	from src : java!TypeLiteral
	to tgt :kdm!Value(
		name <- 'type literal'
		,type <- src.type->getType()
	)
}

-- VariableDeclarationExpression
rule VariableDeclarationExpressionToActionElement extends ASTNodeToAbstractCodeElement {
	from src : java!VariableDeclarationExpression
	to tgt :kdm!ActionElement(
		kind <- 'variable declaration'
		,name <- 'variable declaration'
		-- referenced elements
		,codeElement <- src.fragments->collect(e | thisModule->filterExpression(e))->flatten()
		,actionRelation <- if(src.type.oclIsUndefined()) then Sequence{} else thisModule->CreateUsesType(src.type) endif
	)
}
