-- @nsURI XML=http://www.eclipse.org/MoDisco/Xml/0.1.incubation/XML
-- @nsURI java=http://www.eclipse.org/MoDisco/Java/0.2.incubation/java
-- @path ASEC=/DetectionCharaceOfMalware/metamodels/ASEC.ecore

module Manifest2Security;
create OUT : ASEC from IN : XML, IN1 : java;

helper context XML!Element def : getAttributes(element_name : String) :  Sequence(XML!Element) =
	self.children->select(c | c.name = element_name);

helper context XML!Element def : getAttribute(element_name : String) : XML!Element =
	self.getAttributes(element_name)->first();
													

helper def:name_of_components:Sequence(OclAny)=
	Sequence{'activity',
	         'receiver',
			 'service',
			 'provider'
	};
	
	

	
helper def:stringOfPermission2ProtectionLevel :Map(OclAny,OclAny) = 
	Map{--Normal
('android.permission.GET_PACKAGE_SIZE',#Normal),('android.permission.FLASHLIGHT',#Normal),('android.permission.EXPAND_STATUS_BAR',#Normal),('android.permission.KILL_BACKGROUND_PROCESSES',#Normal),
('android.permission.SET_WALLPAPER',#Normal),('android.permission.SET_WALLPAPER_HINTS',#Normal),('android.permission.VIBRATE',#Normal),('android.permission.DISABLE_KEYGUARD',#Normal),
('android.permission.FLASHLIGHT',#Normal),('android.permission.ACCESS_LOCATION_EXTRA_COMMANDS',#Normal),('android.permission.ACCESS_NETWORK_STATE',#Normal),('android.permission.ACCESS_WIFI_STATE',#Normal),
('android.permission.BATTERY_STATS',#Normal),('android.permission.GET_ACCOUNTS',#Normal),('android.permission.GET_PACKAGE_SIZE',#Normal),('android.permission.READ_SYNC_SETTINGS',#Normal),
('android.permission.READ_SYNC_STATS',#Normal),('android.permission.RECEIVE_BOOT_COMPLETED',#Normal),('android.permission.SUBSCRIBED_FEEDS_READ',#Normal),('android.permission.WRITE_USER_DICTIONARY',#Normal),('android.permission.BROADCAST_STICKY',#Normal),
--Dangerous
('android.permission.ACCESS_FINE_LOCATION',#Dangerous),('android.permission.ACCESS_COARSE_LOCATION',#Dangerous),('android.permission.READ_SMS',#Dangerous),('android.permission.SEND_SMS',#Dangerous),
('android.permission.RECEIVE_MMS',#Dangerous),('android.permission.RECEIVE_SMS',#Dangerous),('android.permission.SEND_SMS',#Dangerous),('android.permission.SUBSCRIBED_FEEDS_WRITE',#Dangerous),
('android.permission.MODIFY_AUDIO_SETTINGS',#Dangerous),('android.permission.MODIFY_PHONE_STATE',#Dangerous),('android.permission.MOUNT_FORMAT_FILESYSTEMS',#Dangerous),('android.permission.WAKE_LOCK',#Dangerous),
('android.permission.WRITE_APN_SETTINGS',#Dangerous),('android.permission.WRITE_CALENDAR',#Dangerous),('android.permission.WRITE_CONTACTS',#Dangerous),('android.permission.WRITE_EXTERNAL_STORAGE',#Dangerous),
('android.permission.WRITE_OWNER_DATA',#Dangerous),('android.permission.WRITE_SETTINGS',#Dangerous),('android.permission.WRITE_SMS',#Dangerous),('android.permission.SET_ALWAYS_FINISH',#Dangerous),
('android.permission.SET_ANIMATION_SCALE',#Dangerous),('android.permission.SET_DEBUG_APP',#Dangerous),('android.permission.SET_PROCESS_LIMIT',#Dangerous),('android.permission.SET_TIME_ZONE',#Dangerous),
('android.permission.SIGNAL_PERSISTENT_PROCESSES',#Dangerous),('android.permission.SYSTEM_ALERT_WINDOW',#Dangerous),('android.permission.MANAGE_ACCOUNTS',#Dangerous),('android.permission.MODIFY_AUDIO_SETTINGS',#Dangerous),
('android.permission.MODIFY_PHONE_STATE',#Dangerous),('android.permission.MOUNT_FORMAT_FILESYSTEMS',#Dangerous),('android.permission.MOUNT_UNMOUNT_FILESYSTEMS',#Dangerous),('android.permission.PERSISTENT_ACTIVITY',#Dangerous),
('android.permission.PROCESS_OUTGOING_CALLS',#Dangerous),('android.permission.READ_CALENDAR',#Dangerous),('android.permission.READ_CONTACTS',#Dangerous),('android.permission.READ_LOGS',#Dangerous),
('android.permission.READ_OWNER_DATA',#Dangerous),('android.permission.READ_PHONE_STATE',#Dangerous),('android.permission.READ_SMS',#Dangerous),('android.permission.READ_USER_DICTIONARY',#Dangerous),('android.permission.USE_CREDENTIALS',#Dangerous),
--Signature
('android.permission.ACCESS_SURFACE_FLINGER', #Signature),('android.permission.ACCOUNT_MANAGER', #Signature),('android.permission.BRICK', #Signature),('android.permission.BIND_INPUT_METHOD', #Signature),('android.permission.SHUTDOWN', #Signature),
('android.permission.SET_ACTIVITY_WATCHER', #Signature),(';android.permission.SET_ORIENTATION', #Signature),('android.permission.HARDWARE_TEST', #Signature),('android.permission.UPDATE_DEVICE_STATS', #Signature),('android.permission.CLEAR_APP_USER_DATA', #Signature),
('android.permission.COPY_PROTECTED_DATA', #Signature),('android.permission.CHANGE_COMPONENT_ENABLED_STATE', #Signature),('android.permission.FORCE_BACK', #Signature),('android.permission.INJECT_EVENTS', #Signature),('android.permission.INTERNAL_SYSTEM_WINDOW', #Signature),
('android.permission.MANAGE_APP_TOKENS', #Signature),('android.permission.BROADCAST_PACKAGE_REMOVED', #Signature),('android.permission.BROADCAST_SMS', #Signature),('android.permission.BROADCAST_WAP_PUSH', #Signature),('android.permission.PACKAGE_USAGE_STATS', #Signature),
('android.permission.CHANGE_BACKGROUND_DATA_SETTING', #Signature),('android.permission.BIND_DEVICE_ADMIN', #Signature),('android.permission.READ_FRAME_BUFFER', #Signature),('android.permission.DEVICE_POWER', #Signature),
('android.permission.DIAGNOSTIC', #Signature),('android.permission.FACTORY_TEST', #Signature),('android.permission.FORCE_STOP_PACKAGES', #Signature),('android.permission.GLOBAL_SEARCH_CONTROL', #Signature),
--SignatureOrSystem
('android.permission.ACCESS_CHECKIN_PROPERTIES',#SignatureOrSystem),('android.permission.BACKUP',#SignatureOrSystem),('android.permission.BIND_APPWIDGET',#SignatureOrSystem),('android.permission.BIND_WALLPAPER',#SignatureOrSystem),
('android.permission.CALL_PRIVILEGED',#SignatureOrSystem),('android.permission.CONTROL_LOCATION_UPDATES',#SignatureOrSystem),('android.permission.DELETE_CACHE_FILES',#SignatureOrSystem),('android.permission.DELETE_PACKAGES',#SignatureOrSystem),
('android.permission.GLOBAL_SEARCH',#SignatureOrSystem),('android.permission.INSTALL_LOCATION_PROVIDER',#SignatureOrSystem),('android.permission.INSTALL_PACKAGES',#SignatureOrSystem),('android.permission.MASTER_CLEAR',#SignatureOrSystem),
('android.permission.REBOOT',#SignatureOrSystem),('android.permission.SET_TIME',#SignatureOrSystem),('android.permission.STATUS_BAR',#SignatureOrSystem),('android.permission.WRITE_GSERVICES',#SignatureOrSystem),('android.permission.WRITE_SECURE_SETTINGS',#SignatureOrSystem)

};
	
helper def:string2ProtectionLevel :Map(OclAny,OclAny) = 
	Map{('normal',#Normal),('dangerous',#Dangerous), ('signature', #Signature),('signatureOrSystem',#SignatureOrSystem),('signature|signatureOrSystem',#SignatureOrSystem)} ;



helper def:string2Boolean:Map(OclAny,OclAny) = 
	Map{('false',false),('true',true)} ;
	
	
	
helper context XML!Element def:getAttributeofchildren (element_name : String):XML!Attribute=
	self.children->select(c | c.name='android:name');

helper context XML!Element def:getIntentFilter:Sequence(XML!Element)=
	self.children->select(c | c.name='intent-filter');



--helpers for intent--
helper context OclAny def:getClassInstanceCreationOfIntent:Sequence(java!ClassInstanceCreation)=
	java!ClassInstanceCreation.allInstances()->select(c | c.type.type.name='Intent');

helper context java!ClassInstanceCreation def:getNameOfIntent:String=
	if self.refImmediateComposite().oclIsTypeOf(java!VariableDeclarationFragment) then
	         self.getContainerOfIntent.name
		else
			'no name'
	endif;


helper context OclAny def : getContainerOfIntent : java!VariableDeclarationFragment =
	if self.oclIsTypeOf(java!VariableDeclarationFragment) then
		self
	else
			self.refImmediateComposite().getContainerOfIntent
endif;



helper def:name_of_method_of_Set_Component:Sequence(OclAny)=
	Sequence{'setComponent',
 	         'setClass',
			 'setClassName'
			 
	         
	};
	
helper def:name_of_method_of_Set_Data:Sequence(OclAny)=
	Sequence{'setData',
 	         'setDataAndType',
			 'putExtra',
			 'setDataAndNormalize',
			 'setDataAndTypeAndNormalize',
			 'setType'
			 
	         
	};
	
	
 helper def:name_of_method_of_intent:Sequence(OclAny)=
	Sequence{'sendBroadcast',
 	         'sendOrderedBroadcast',
			 'sendStickyBroadcast',
			 'sendStickyOrderedBroadcast',
			 'startActivity',
			 'startActivityForResult',
			 'startService',
			 'bindService'
			 
 
	         
	};
	

	
helper context OclAny def : getContainerOfSingleVariableSAccess : java!MethodInvocation =
	if self.oclIsTypeOf(java!MethodInvocation) then
		self
	   else
			self.refImmediateComposite().getContainerOfSingleVariableSAccess
endif;

helper context java!AbstractMethodInvocation def:getNameofSingleVariableAccess : Sequence(java!SingleVariableAccess) =
	self.arguments->flatten()->select(c | c.oclIsTypeOf(java!SingleVariableAccess));



helper context OclAny def:getData : Sequence(java!SingleVariableAccess)=
	self.getContainerOfIntent.usageInVariableAccess->select(c | c.oclIsTypeOf(java!MethodInvocation))->flatten()->select(c | c.getContainerOfSingleVariableSAccess.method.name='setData')->flatten();


helper context java!SingleVariableAccess def: getSetDataMethod:java!MethodInvocation =
  self.getContainerOfSingleVariableSAccess;


helper context java!SingleVariableAccess def: getMethodOfIntent:java!MethodInvocation =
  self.getContainerOfSingleVariableSAccess;
  
  

	


helper context java!AbstractMethodInvocation def:getArgument:Sequence(java!StringLiteral)=
	self.arguments->flatten()->select(c | c.oclIsTypeOf(java!StringLiteral));

helper context OclAny def : getContainerOfVariable : java!ClassDeclaration =
	if self.oclIsTypeOf(java!ClassDeclaration) then
		self
	   else
			self.refImmediateComposite().getContainerOfVariable
endif;





helper context java!VariableDeclaration def: IsPermission :Boolean=
	if self.getContainerOfVariable.name='permission' then
	 true
	else
		false
		endif;
	    

helper context java!AbstractMethodInvocation def:getNameofStringLiteral : Sequence(java!StringLiteral) =
	self.arguments->flatten()->select(c | c.oclIsTypeOf(java!StringLiteral));


helper context java!ClassInstanceCreation def:getSingleVariableAccess:Sequence(java!SingleVariableAccess)=
	self.arguments->flatten()->select(c | c.oclIsTypeOf(java!SingleVariableAccess));


helper context java!SingleVariableAccess def: getSetActionMethod:java!MethodInvocation =
 --self.getContainerOfSingleVariableSAccess.getSingleVariableAccessinArgument.escapedValue;
  self.getContainerOfSingleVariableSAccess;
  
  
helper context java!AbstractMethodInvocation def:getName:OclAny=
	self.arguments->first();


helper context java!ClassInstanceCreation def:getStringLiteral:Sequence(java!StringLiteral)=
	self.arguments->flatten()->select(c | c.oclIsTypeOf(java!StringLiteral));

helper context java!SingleVariableDeclaration def:IsString:Boolean=
	if self.type.type.name='String' then
	   true
	   else
	   	false
		endif;
	

helper context java!SingleVariableDeclaration def:getString:String=
self.type.type.name;
	
helper context java!SingleVariableDeclaration def:IsAction:Boolean=
	if self.type.type.oclIsTypeOf(java!ClassDeclaration) then
	     if self.type.type.name='String' then
		    true
		   else
		   	false
		 endif
		else
		 false
	endif;


helper context java!SingleVariableAccess def:getSingleVariableDec:java!SingleVariableDeclaration=
	
	if self.variable.oclIsTypeOf(java!SingleVariableDeclaration) then
	      self.variable
	 else
	 OclUndefined
endif;

helper context java!SingleVariableAccess def:getVariableDeclarationFragment:java!VariableDeclarationFragment=
	
	if self.variable.oclIsTypeOf(java!VariableDeclarationFragment) then
	      self.variable
	 else
	 OclUndefined
endif;


helper context OclAny def : getContainerOfMethodForVariable :java!VariableDeclarationFragment =
	if self.oclIsTypeOf(java!VariableDeclarationFragment) then
		self
	   else
			self.refImmediateComposite().getContainerOfMethodForVariable
endif;




	
 helper def:name_of_method_of_getDate_from_Intent:Sequence(OclAny)=
	Sequence{'getBooleanArrayExtra',
 	         'getBooleanExtra',
			 'getBundleExtra',
			 'getByteArrayExtra',
			 'getByteExtra',
			 'getCharArrayExtra',
			 'getCharExtra',
			 'getCharSequenceArrayExtra',
			 'getCharSequenceArrayListExtra',
			 'getCharSequenceExtra',
			 'getData',
			 'getDataString',
			 'getDoubleArrayExtra',
			 'getDoubleExtra',
			 'getExtras',
			 'getFloatArrayExtra',
			 'getFloatExtra',
			 'getIntArrayExtra',
			 'getIntExtra',
			 'getIntegerArrayListExtra',
			 'getLongArrayExtra',
			 'getLongExtra',
			 'getParcelableArrayExtra',
			 'getParcelableArrayListExtra',
			 'getParcelableExtra',
			 'getSerializableExtra',
			 'getShortArrayExtra',
			 'getShortExtra',
			 'getStringArrayExtra',
			 'getStringArrayListExtra',
			 'getStringExtra'
			 	};



helper context OclAny def : getContainerOfSingleVariableAccess :java!MethodInvocation =
	if self.oclIsTypeOf(java!MethodInvocation) then
		self
	   else
			self.refImmediateComposite().getContainerOfSingleVariableAccess
endif;


helper context java!SingleVariableAccess def:haveData :Boolean=
	if self.refImmediateComposite().oclIsTypeOf(java!MethodInvocation) then
	       if thisModule.name_of_method_of_getDate_from_Intent.includes(self.getContainerOfSingleVariableSAccess.method.name) then
		      true
		      else
		      false
		   endif
	 else
      false
   endif;


helper context OclAny def : getContainerOfMethodInvocation :java!MethodInvocation =
	if self.oclIsTypeOf(java!MethodInvocation) then
		self
	   else
			self.refImmediateComposite().getContainerOfMethodInvocation
endif;

helper context java!MethodInvocation def:havegetDataMethod:Boolean=
	if self.refImmediateComposite().oclIsTypeOf(java!VariableDeclarationFragment) then
	      if self.getContainerOfMethodForVariable.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation))->select(c | c.haveData).notEmpty() then
		     true
		    else
		  	 false
		  endif
	  else
	 if self.refImmediateComposite().oclIsTypeOf(java!MethodInvocation) then
	        if thisModule.name_of_method_of_getDate_from_Intent.includes(self.getContainerOfMethodInvocation.method.name) then
		      true
		     else
		      false
		    endif
	   else
	    false
	 endif
	endif;

helper context java!MethodInvocation def:IsMyMethod(Name:String):Boolean=
	if Name.endsWith(self.originalCompilationUnit.name) then
	  true
	 else
	   false
	 endif;

helper context OclAny def:getAllgetIntentMethod (NameComp:String):Sequence(java!MethodDeclaration)=
	java!MethodDeclaration.allInstances()->select(c | thisModule.name_of_method_of_getDate_from_Intent.includes(c.name))->select(c | c.usages->flatten()->exists(m | NameComp.endsWith(m.originalCompilationUnit.name)));



helper context OclAny def : getContainerOfIntentForMethod : java!MethodInvocation =
	if self.oclIsTypeOf(java!MethodInvocation) then
		self
	   else
			self.refImmediateComposite().getContainerOfIntentForMethod
endif;

helper context OclAny def : getPackageOfApp(name_of_package:String) :  Boolean =
	--self.
	if java!Package.allInstances()->select(c | c.name = name_of_package).notEmpty() then
	true
	else
		false
		endif;


--for transformation Root TO ApplicationPolicyFile:
rule Root2ApplicationPolicyFile {
	from
		s: XML!Root (s.name = 'manifest')
	to
		t: ASEC!ApplicationPolicyFile (
			
			Package <- if s.getAttribute('package').oclIsUndefined() then
			              OclUndefined
						  else
						  s.getAttribute('package').value
						  endif,
			
			VersionCode <- if s.getAttribute('android:versionCode').oclIsUndefined() then
			              OclUndefined
						  else
						  s.getAttribute('android:versionCode').value
						  endif,
			
			VersionName <- if s.getAttribute('android:versionName').oclIsUndefined() then
			              OclUndefined
						  else
						  s.getAttribute('android:versionName').value
						  endif,
			
			applicationlevelPermission <-s.children ->select(c | c.name='uses-permission'),
			app <- s.children ->select(c | c.name='application'),
			UsesSDK <- s.children->select(c | c.name='uses-sdk'),
			UsesNewPermissions <- s.children->select(c | c.name='permission'),
			UsesNewGroupPermissions <- s.children->select(c | c.name='permission-group'),
		 	Intents <- thisModule.getClassInstanceCreationOfIntent->collect(c | thisModule.CreateIntent(c))
		)
}

--for Create UsesPermission:
rule Element2UsesPermission{ 
	from
	    s:XML!Element  (s.name='uses-permission')
	to
	    t:ASEC!UsesPermission(
	    	name <- s.getAttribute('android:name').value,
			Permisionkind <- thisModule.stringOfPermission2ProtectionLevel.get(s.getAttribute('android:name').value)
	    )
}


--for Create Application:
rule Element2Application{ 
	from
	    s:XML!Element  (s.name='application')
	to
	    t:ASEC!Application(
	    	Label <- s.getAttribute('android:label').value,
			icon <- if s.getAttribute('android:icon').oclIsUndefined() then
			          OclUndefined
					  else
					  	s.getAttribute('android:icon').value
					endif,
			permission <-if s.getAttribute('android:permission').oclIsUndefined() then
			              OclUndefined
						 else
						   s.getAttribute('android:permission').value
						 endif,
			Components <-   s.children-> select(c | thisModule.name_of_components.includes(c.name)   )
			
			
	    )
}


--for Create SDK:
rule Element2SDK{
	from
	    s:XML!Element (s.name='uses-sdk' )
	to
	   t:ASEC!SDK(
	   	
	   	targetSdkVersion <- if s.getAttribute('android:targetSdkVersion').oclIsUndefined() then
		                    OclUndefined
							else
							s.getAttribute('android:targetSdkVersion').value
							endif,
	   
	   	minSdkVersion <- if s.getAttribute('android:minSdkVersion').oclIsUndefined() then
		                    OclUndefined
							else
							s.getAttribute('android:minSdkVersion').value
							endif,
							
		maxSdkVersion <- if s.getAttribute('android:maxSdkVersion').oclIsUndefined() then
		                    OclUndefined
							else
							s.getAttribute('android:maxSdkVersion').value
							endif				
	   
	   )
}


--for Create NewPermission:
rule Element2NewPermission{
	from
	s:XML!Element (s.name='permission')
	to
	t:ASEC!NewPermission(
	name <- s.getAttribute('android:name').value,
	
	label <- if s.getAttribute('android:label').oclIsUndefined() then
	         OclUndefined
			  else
			  s.getAttribute('android:label').value
			 endif,
	Description <- if s.getAttribute('android:description').oclIsUndefined() then
	          OclUndefined
			  else
			  s.getAttribute('android:description').value
			 endif,
	Permisionkind <- if s.getAttribute('android:protectionLevel').oclIsUndefined() then
	        OclUndefined
			  else
			thisModule.string2ProtectionLevel.get(s.getAttribute('android:protectionLevel').value)
			 endif,
			 
	PermissionGroup <- if s.getAttribute('android:permissionGroup').oclIsUndefined() then
	                  OclUndefined
					   else
						s.getAttribute('android:permissionGroup').value
						endif
		
	)
}


--for Create Component:
rule Element2Component {
	from
	    s:XML!Element (thisModule.name_of_components.includes(s.name)  )
	to
	    t:ASEC!Component (
	        
	    	name <- if s.getAttribute('android:name').oclIsUndefined() then
			          OclUndefined
					  else
			           s.getAttribute('android:name').value
					  endif,
			 
			label <- if s.getAttribute('android:label').oclIsUndefined() then
			             OclUndefined
						 else
						   s.getAttribute('android:label').value
						 endif,
						 
			icon <- if s.getAttribute('android:icon').oclIsUndefined() then
			              OclUndefined
						 else
						   s.getAttribute('android:icon').value
						 endif,
						 
			permission <- if s.getAttribute('android:permission').oclIsUndefined() then
			              OclUndefined
						 else
						   s.getAttribute('android:permission').value
						 endif,
						 
			enabled <- 	if s.getAttribute('android:enabled').oclIsUndefined() then
			              false
						 else
						 	thisModule.string2Boolean.get(s.getAttribute('android:enabled').value)
						 endif,
		  
	       process <- if s.getAttribute('android:process').oclIsUndefined() then
			              OclUndefined
						 else
						   s.getAttribute('android:process').value
						 endif,
		exported <- if s.getAttribute('android:exported').oclIsUndefined() then
		                if not s.getIntentFilter.notEmpty() then
	                        false
						 else
							true
						endif
					else
					 thisModule.string2Boolean.get(s.getAttribute('android:exported').value)	
							
					endif,
					
		 Data <- if thisModule.getAllgetIntentMethod(s.getAttribute('android:name').value+'.java').notEmpty() then
				              true
						    else
						      false
						  endif
						 
		
	    )
}



--for Create Activity:
rule Element2Activity extends Element2Component {
        from
		    s:XML!Element(s.name='activity')
			
		to
		    t:ASEC!Activity(
		    	
		          filters  <- s.children ->select(c | c.name='intent-filter')
				
		    )
			
}


--for Create Service:
rule Element2Service extends Element2Component {
        from
		    s:XML!Element(s.name='service')
			
		to
		    t:ASEC!Service
			(
				
			filters <- s.children ->select(c | c.name='intent-filter')
			
			)

			
}


--for Create receiver:
rule Element2receiver extends Element2Component {
        from
		    s:XML!Element(s.name='receiver')
			
		to
		    t:ASEC!BroadcastReceiver(
		    	
		    filters  <- s.children ->select(c | c.name='intent-filter'),
			Source <- #XML
		
		    )

			
}


rule Element2receiverfromjava  {
	from
	   s:java!MethodDeclaration (s.name='registerReceiver')
	to
	   t:ASEC!BroadcastReceiver(
	   	name <- s.parameters-> select(c | c.oclIsTypeOf(java!SingleVariableDeclaration))->flatten().first().name,
		filters <- s.parameters->select(c | c.oclIsTypeOf(java!SingleVariableDeclaration))->flatten()->select(c | c.type.type.name='IntentFilter')->collect(c | thisModule.CreateIntentFilterfromJava(c)),
		Source <- #JAVA
	   	
	   
	   	
	  
	   
	  )
}
  

--for Create provider:
--rule Element2provider extends Element2Component {
    --    from
		 --   s:XML!Element(s.name='provider')
			
		--to
		 --   t:ASEC!ContentProvider

			
--}


--for Create ContentProvider:
rule Element2ContentProvider extends Element2Component {
	from
	    s:XML!Element (s.name='provider')
	to 
	    t:ASEC!ContentProvider(
	    
	    	authorities <- if s.getAttribute('android:authorities').oclIsUndefined() then
			                 OclUndefined
							 else
							 s.getAttribute('android:authorities').value
							 endif
			--grantUriPermissions <- if s.getAttribute('android:grantUriPermissions').oclIsUndefined() then
			              --             false
							--		 else
							--		   	true
							--	   endif
			
	    
	    )
	    
}


--for Create intentFilter:
rule Element2intentFilter {
	
   from
	    s:XML!Element (s.name='intent-filter')
		
    to
	   t:ASEC!intentFilter (
	    	
	   
	   actions <- s.children ->select(c | c.name='action'),
	   category <- s.children ->select(c | c.name='category'),
	   data <- s.children->select(c | c.name='data')
	    
	    )
	
}


--for Create Action:
rule Element2Action{
	
	from 
	    s:XML!Element (s.name= 'action')
	to
	    t:ASEC!Action(
	    	
	    name <- s.getAttribute('android:name').value
	    
	    )
		
}

--for Create Category:
rule Element2Category{
	
	from 
	    s:XML!Element (s.name= 'category')
	to
	    t:ASEC!Category(
	    	
	    name <- s.getAttribute('android:name').value
	    
	    )
		
}


--for Create Data:
rule Element2Data{
	
	from 
	    s:XML!Element (s.name= 'data')
	to
	    t:ASEC!Data(
	    
	    	dataType <- if s.getAttribute('android:mimType').oclIsUndefined() then
			            OclUndefined
						else
							s.getAttribute('android:mimType').value
					    endif
			
		--	URI <- 
	    )
		
}





--for Create PermissionGroup:
rule Element2PermissionGroup{
	from
	   s:XML!Element (s.name='permission-group')
    to
	   t:ASEC!PermissionGroup(
	   name <- s.getAttribute('android:name').value,
	   Description <- if s.getAttribute('android:description').oclIsUndefined() then
	                  OclUndefined
					  else
					   s.getAttribute('android:description').value
					  endif,
	  
	   icon <- if s.getAttribute('android:icon').oclIsUndefined() then
	                 OclUndefined
			    else
					  s.getAttribute('android:icon').value
				endif,
	  
	   

	   label <- if s.getAttribute('android:label').oclIsUndefined() then
	                  OclUndefined
			    else
					  s.getAttribute('android:label').value
				endif
	   
	   
	   
	   
	   )
}



lazy rule CreateIntentFilterfromJava{
	
from
s:java!SingleVariableDeclaration
to 
t:ASEC!intentFilter(
	)
}


--for Create Intent
lazy rule CreateIntent{
	from
	    s:java!ClassInstanceCreation
		
		
	to
	    t:ASEC!Intent(
	    	
name <- s.getNameOfIntent,

IntentKind <-  if s.method.parameters->select(c | c.type.type.oclIsTypeOf(java!ClassDeclaration))->select(c | c.type.type.name='Context').notEmpty() then
                       if s.method.parameters->select(c | c.type.type.oclIsTypeOf(java!ClassDeclaration))->select(c | c.type.type.name='Class').notEmpty()  then
						       #explicit
					     else
	   					      #implicit
				      endif
				  else
                     if s.refImmediateComposite().oclIsTypeOf(java!VariableDeclarationFragment) then
                          if  not s.getContainerOfIntent.usageInVariableAccess.oclIsUndefined()  then
				               if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation))->flatten()->select(c | thisModule.name_of_method_of_Set_Component.includes(c.refImmediateComposite().method.name)).notEmpty() then  
							        #explicit
						           else
						          	#implicit
							   endif
							  else
							  	#implicit
						 endif
						else
					     #implicit
					 endif
				endif,
				
Data <-    if s.refImmediateComposite().oclIsTypeOf(java!VariableDeclarationFragment) then 
             if not s.getContainerOfIntent.usageInVariableAccess.oclIsUndefined() then  
                 if s.getContainerOfIntent.usageInVariableAccess->flatten()->exists(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)) then
			         if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_Set_Data.includes(c.refImmediateComposite().method.name)).notEmpty() then
				        
						'yes'
					  else
					    'no'
						 
				    endif	
				 
			     else
			  	'no'
			    endif
		    else
		    'no'
			 	
		    endif
		else
		'no'
		endif,
		
Permission <- if s.refImmediateComposite().oclIsTypeOf(java!VariableDeclarationFragment) then 
                        if not s.getContainerOfIntent.usageInVariableAccess.oclIsUndefined() then 
				               if s.getContainerOfIntent.usageInVariableAccess->exists(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)) then
					                if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation))->flatten()->select(c | thisModule.name_of_method_of_intent.includes(c.refImmediateComposite().method.name)).notEmpty() then  
					                       if   s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation))->flatten()->select(c | thisModule.name_of_method_of_intent.includes(c.refImmediateComposite().method.name))->first().getContainerOfSingleVariableSAccess.arguments->exists(c | c.oclIsTypeOf(java!StringLiteral)) then
										           if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation))->flatten()->select(c | thisModule.name_of_method_of_intent.includes(c.refImmediateComposite().method.name))->first().getContainerOfSingleVariableSAccess.getNameofStringLiteral.first().escapedValue.startsWith('"android.permission') then
										               s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation))->flatten()->select(c | thisModule.name_of_method_of_intent.includes(c.refImmediateComposite().method.name))->first().getContainerOfSingleVariableSAccess.getNameofStringLiteral.first().escapedValue
												   else
													OclUndefined
												   endif
										
							                else
							                      if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation))->flatten()->select(c | thisModule.name_of_method_of_intent.includes(c.refImmediateComposite().method.name))->first().getContainerOfSingleVariableSAccess.arguments->exists(c | c.oclIsTypeOf(java!SingleVariableAccess)) then
												     if  s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation))->flatten()->select(c | thisModule.name_of_method_of_intent.includes(c.refImmediateComposite().method.name))->first().getContainerOfSingleVariableSAccess.getNameofSingleVariableAccess->select(c | c.variable.IsPermission).notEmpty() then
													       '"android.permission.' + s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation))->flatten()->select(c | thisModule.name_of_method_of_intent.includes(c.refImmediateComposite().method.name))->first().getContainerOfSingleVariableSAccess.getNameofSingleVariableAccess->select(c | c.variable.IsPermission).first().variable.name +'"'
													   
													  else
													       OclUndefined
													  endif
												  else
												  	OclUndefined
												  endif
							              	endif
								 
								     else
							  	     OclUndefined
								     endif
						       else
					           OclUndefined
					           endif
				       else
				       OclUndefined
					   endif
					 else
			  	--firstmethod must focus
			  OclUndefined
			  endif,
			  
Action <-  if s.arguments->flatten()->exists(c | c.oclIsTypeOf(java!StringLiteral)) then
                  s.getStringLiteral.first().escapedValue
			       else
		                	if s.arguments->flatten()->exists(c | c.oclIsTypeOf(java!SingleVariableAccess)) then
				         	     if s.getSingleVariableAccess->select(c | c.variable.oclIsTypeOf(java!SingleVariableDeclaration)).notEmpty() then
					                   if  s.getSingleVariableAccess->select(c | c.variable.oclIsTypeOf(java!SingleVariableDeclaration))->first().getSingleVariableDec.type.type.name='String' then
								             s.getSingleVariableAccess->select(c | c.variable.oclIsTypeOf(java!SingleVariableDeclaration))->first().variable.name
								          else
								          	   OclUndefined
										endif
								      
								    else
								    	
								    	--add
								    	if s.getSingleVariableAccess->select(c | c.variable.oclIsTypeOf(java!VariableDeclarationFragment)).notEmpty() then
										    if s.getSingleVariableAccess->select(c | c.variable.oclIsTypeOf(java!VariableDeclarationFragment)).first().getVariableDeclarationFragment.variablesContainer.oclIsTypeOf(java!FieldDeclaration) then
						                       s.getSingleVariableAccess->select(c | c.variable.oclIsTypeOf(java!VariableDeclarationFragment))->first().variable.name
											  else
											  	OclUndefined
											endif
											
											else
												OclUndefined
										endif
						          endif
						   
					       else
						          
					 
			             
			            	if s.refImmediateComposite().oclIsTypeOf(java!VariableDeclarationFragment) then
							
							     if not s.getContainerOfIntent.usageInVariableAccess.oclIsUndefined() then 
							           if s.getContainerOfIntent.usageInVariableAccess->flatten()->exists(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)) then
							                if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | c.refImmediateComposite().method.name='setAction').notEmpty() then
								               if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | c.refImmediateComposite().method.name='setAction').first().getSetActionMethod.getName.oclIsTypeOf(java!StringLiteral) then
										           s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | c.refImmediateComposite().method.name='setAction').first().getSetActionMethod.getNameofStringLiteral.first().escapedValue
											          else
										                if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | c.refImmediateComposite().method.name='setAction').first().getSetActionMethod.getName.oclIsTypeOf(java!SingleVariableDeclaration) then
										                   s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | c.refImmediateComposite().method.name='setAction').first().getSetActionMethod.getNameofSingleVariableAccess.first().variable.name
										                 else
										                   OclUndefined
											            endif
											   endif
										  
							                else
							           	    OclUndefined
								            endif
							           else
			                          OclUndefined
							          endif
								  else
								  OclUndefined
							 endif
						    else
						    	OclUndefined
						   endif
			 endif
			endif,
			
MethodForSend <-  if s.refImmediateComposite().oclIsTypeOf(java!VariableDeclarationFragment) then 
                          if not s.getContainerOfIntent.usageInVariableAccess.oclIsUndefined() then  
                                if s.getContainerOfIntent.usageInVariableAccess->flatten()->exists(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)) then
			                           if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_intent.includes(c.refImmediateComposite().method.name)).notEmpty() then
				                            s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_intent.includes(c.refImmediateComposite().method.name))->first().getContainerOfSingleVariableSAccess.method.name
						                   else
						                   	OclUndefined
									   endif
								    else
								   OclUndefined
							    endif
							  else
							 OclUndefined
							endif
					   else
					   	if s.refImmediateComposite().oclIsTypeOf(java!MethodInvocation) then
						        if thisModule.name_of_method_of_intent.includes(s.getContainerOfIntentForMethod.method.name) then
						           s.getContainerOfIntentForMethod.method.name
							      else
							   	   OclUndefined
								endif
							  else
							  OclUndefined
						endif
				    endif,
					
SendComponentName <- s.originalCompilationUnit.name,









--if s.refImmediateComposite().oclIsTypeOf(java!VariableDeclarationFragment) then
        --                     if not s.getContainerOfIntent.usageInVariableAccess.oclIsUndefined() then
		--					    if s.getContainerOfIntent.usageInVariableAccess->flatten()->exists(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)) then
				--				        if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_Set_Component.includes(c.refImmediateComposite().method.name)).notEmpty() then
			--							    
					--				 s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_Set_Component.includes(c.refImmediateComposite().method.name)).first().getContainerOfSingleVariableSAccess.arguments->select(c | c.oclIsTypeOf(java!StringLiteral)).first().escapedValue       
										
							--			else
											   
								--			OclUndefined
									--	endif
								--else
									
								--	OclUndefined
								--endif
							-- else
							 	
							 	
							--	OclUndefined
							-- endif
                       --else
                       
                      -- 	OclUndefined
                      -- 	endif


			 
SendToInternalComp <- if  s.refImmediateComposite().oclIsTypeOf(java!VariableDeclarationFragment) then
                        if not s.getContainerOfIntent.usageInVariableAccess.oclIsUndefined() then 
		                    if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_Set_Component.includes(c.refImmediateComposite().method.name)).notEmpty() then
                                 if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_Set_Component.includes(c.refImmediateComposite().method.name)).first().getContainerOfSingleVariableSAccess.arguments->select(c | c.oclIsTypeOf(java!StringLiteral)).notEmpty() then
								     if thisModule.getPackageOfApp(s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_Set_Component.includes(c.refImmediateComposite().method.name)).first().getContainerOfSingleVariableSAccess.arguments->select(c | c.oclIsTypeOf(java!StringLiteral)).first().escapedValue ) then
							--if thisModule.getPackageOfApp(s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_Set_Component.includes(c.refImmediateComposite().method.name)).first().getContainerOfSingleVariableSAccess.arguments->select(c | c.oclIsTypeOf(java!StringLiteral)).first().escapedValue ) then
                                     true
					                 else
						 	         OclUndefined
						          endif
						        else
								false
						        endif
						     else
							false
							endif
						else
						false
					endif
					else
						false
						endif	,
						
						TargetComponentName <- 
if s.refImmediateComposite().oclIsTypeOf(java!VariableDeclarationFragment) then
                             if not s.getContainerOfIntent.usageInVariableAccess.oclIsUndefined() then
							    if s.getContainerOfIntent.usageInVariableAccess->flatten()->exists(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)) then
								        if s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_Set_Component.includes(c.refImmediateComposite().method.name)).notEmpty() then
										   if  s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_Set_Component.includes(c.refImmediateComposite().method.name)).first().getContainerOfSingleVariableSAccess.arguments->select(c | c.oclIsTypeOf(java!StringLiteral)).notEmpty() then    
									            s.getContainerOfIntent.usageInVariableAccess->flatten()->select(c | c.refImmediateComposite().oclIsTypeOf(java!MethodInvocation)).flatten()->select(c | thisModule.name_of_method_of_Set_Component.includes(c.refImmediateComposite().method.name)).first().getContainerOfSingleVariableSAccess.arguments->select(c | c.oclIsTypeOf(java!StringLiteral)).first().escapedValue       
										   else
											OclUndefined
										   endif
								        else
									    OclUndefined
								        endif
							     else
								OclUndefined
							 endif
                            else
                       
                       	OclUndefined
                       	endif
						else
							OclUndefined
							endif
			
			  						  
)
}