I'm creating my model with modelview and services. This is the best way to create with swipeRefresh
I don't know if I'm doing it the right way so I'm asking for your help
who can give feedback thank you very much.
In fact everything is working perfectly I'm just in doubt about this part:
val viewModel: MyViewModel = viewModel()
val isRefreshing by viewModel.isRefreshing.collectAsState()
my method SwipeRefresh:
#Composable
fun SwipeRefresh( content: #Composable (lists:ArrayList<ShoppingCart>) -> Unit){
val viewModel: MyViewModel = viewModel()
val isRefreshing by viewModel.isRefreshing.collectAsState()
com.google.accompanist.swiperefresh.SwipeRefresh(
state = rememberSwipeRefreshState(isRefreshing),
onRefresh = { viewModel.refresh() },
indicator = { state, trigger ->
SwipeRefreshIndicator(
// Pass the SwipeRefreshState + trigger through
state = state,
refreshTriggerDistance = trigger,
// Enable the scale animation
scale = true,
// Change the color and shape
shape = MaterialTheme.shapes.small,
)
}
) {
if(isRefreshing){
if(tipos=="frutas"){
tipos = "fruta"
}
frutas.tipo=tipos
frutas.getFrutas()
when(tipos){
"saladas"->{
val s by frutas.saladasData.collectAsState(initial = emptyList())
list = ArrayList(s)
}
"fruta"->{
val f by frutas.frutaData.collectAsState(initial = emptyList())
list = ArrayList(f)
}
"temperos"->{
val t by frutas.temperosData.collectAsState(initial = emptyList())
list = ArrayList(t)
}
}
}
Log.i("LIST",list.toString())
val t = list.filter { it.product_title!="" }
if(list.isNotEmpty() && t.isNotEmpty()){
content(list)
}else{
helpers.loadingComponent()
}
}
}
My ViewModel:
package com.example.quitanda.models
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
class FrutasViewModel(
private val frutasServices: Services,
):ViewModel() {
private val _frutasData: MutableStateFlow<List<ShoppingCart>> = MutableStateFlow(listOf(ShoppingCart()))
val frutasData: StateFlow<List<ShoppingCart>>
get() = _frutasData
private val _frutaData: MutableStateFlow<List<ShoppingCart>> = MutableStateFlow(listOf(ShoppingCart()))
val frutaData: StateFlow<List<ShoppingCart>>
get() = _frutaData
private val _saladasData: MutableStateFlow<List<ShoppingCart>> = MutableStateFlow(listOf(ShoppingCart()))
val saladasData: StateFlow<List<ShoppingCart>>
get() = _saladasData
private val _temperosData: MutableStateFlow<List<ShoppingCart>> = MutableStateFlow(listOf(ShoppingCart()))
val temperosData: StateFlow<List<ShoppingCart>>
get() = _temperosData
lateinit var tipo:String
fun getFrutas(){
viewModelScope.launch {
try {
when(tipo){
"fruta"->{
val fruta = frutasServices.getFrutas1()
_frutaData.value = fruta
}
"frutas"->{
val frutas = frutasServices.getFruta()
_frutasData.value = frutas
}
"saladas"->{
val saladas = frutasServices.getSaladas()
_saladasData.value = saladas
}
"temperos"->{
val temperos = frutasServices.getTemperos()
_temperosData.value = temperos
}
}
}catch (e:Exception){
Log.d("Service error",e.toString())
}
}
}
}
Service:
package com.example.quitanda.models
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.GET
interface Services {
#GET("category/")
suspend fun getFruta(): List<ShoppingCart>
#GET("category/7")
suspend fun getFrutas1(): List<ShoppingCart>
#GET("category/8")
suspend fun getSaladas(): List<ShoppingCart>
#GET("category/9")
suspend fun getTemperos(): List<ShoppingCart>
}
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl("http://192.168.2.157:4000/")
.addConverterFactory(MoshiConverterFactory.create())
.build()
val frutasServices: Services = retrofit.create(Services::class.java)
My Activity:
package com.example.quitanda
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Menu
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.ShoppingCart
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController
import androidx.navigation.compose.*
import com.example.quitanda.classes.EntryAbstract
import com.example.quitanda.classes.Helpers
import com.example.quitanda.models.FrutasViewModel
import com.example.quitanda.models.ShoppingCart
import com.example.quitanda.models.frutasServices
import com.google.accompanist.pager.ExperimentalPagerApi
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
#Suppress("UNCHECKED_CAST")
#ExperimentalPagerApi
class MainActivity : ComponentActivity() {
private val entryAbstract = EntryAbstract()
private var counter = mutableStateOf(0)
private var ids = mutableStateListOf<ShoppingCart>()
private lateinit var listFrutas:ArrayList<ShoppingCart>
private lateinit var listSaladas:ArrayList<ShoppingCart>
private lateinit var listChas:ArrayList<ShoppingCart>
private val helpers = Helpers()
private val viewModel by viewModels<FrutasViewModel> {
object : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return FrutasViewModel(frutasServices) as T
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent{
if(intent.hasExtra("produtos")) {
ids = remember { intent.getParcelableArrayListExtra<ShoppingCart>("produtos")!!
.toMutableStateList()}
if (ids.isNotEmpty()) {
val aray = ids.count()
counter.value = aray
}
}
viewModel.tipo="frutas"
viewModel.getFrutas()
val l by viewModel.frutasData.collectAsState(initial = emptyList())
if (l.isEmpty()) {
helpers.loadingComponent()
} else {
val i = l.filter { it.category_id==7 }
val o = l.filter { it.category_id==8 }
val p = l.filter { it.category_id==9 }
listFrutas = ArrayList(i)
listSaladas = ArrayList(o)
listChas = ArrayList(p)
entryAbstract.cart =ids
entryAbstract.ccounter =counter
entryAbstract.frutas = viewModel
MainContent()
}
}
}
ShoppingCart:
package com.example.quitanda.models
import android.os.Parcelable
import com.squareup.moshi.Json
import kotlinx.parcelize.Parcelize
#Parcelize
data class ShoppingCart(
var count:Int=0,
#field:Json(name="product_title")
var product_title:String="",
#field:Json(name="product_id")
var product_id:Int=0,
#field:Json(name="photo_photo")
var photo_photo:String="",
#field:Json(name="product_quant")
var product_quant:Int=0,
#field:Json(name="category_name")
var category_name:String="",
#field:Json(name="category_id")
var category_id:Int=0,
#field:Json(name="product_description")
var product_description:String="",
#field:Json(name="product_price_un")
var product_price_un:String?="",
#field:Json(name="product_price_kg")
var product_price_kg:String?="",
var tipos:String=""): Parcelable
I understand seeing my MyViewModel
class MyViewModel : ViewModel() {
private val _isRefreshing = MutableStateFlow(false)
val isRefreshing: StateFlow<Boolean>
get() = _isRefreshing.asStateFlow()
fun refresh() {
// This doesn't handle multiple 'refreshing' tasks, don't use this
viewModelScope.launch {
// A fake 2 second 'refresh'
_isRefreshing.emit(true)
delay(2000)
_isRefreshing.emit(false)
}
}
}
how I make a viewmodel with multiple returns is a little different
Related
I am using recycler view to load documents from firestore. Now my recycler view lists has three buttons. One of the button name is notify. When I click notify button(btn_notify) I want to make the button visibity to gone using holder.button.visibility = View.GONE. But what happens is that when I change the button visibility to gone, the clicked button visibility changes to gone. At the same time the other recycler view lists button visibility also changes to gone. Why this error is happening.
[![enter image description here][1]][1]
package com.example.bloodbankcompany.recyclerview
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.bloodbankcompany.*
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.messaging.FirebaseMessaging
import com.google.gson.Gson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.lang.Exception
const val TOPIC = "/topics/myTopic"
class MyAdapter2(private val userList: ArrayList<User2>): RecyclerView.Adapter<MyAdapter2.MyViewHolder>(){
var id: String = ""
private lateinit var userArrayList: ArrayList<User2>
private val mFireStore = FirebaseFirestore.getInstance()
val TAG = "MyAdapter2"
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter2.MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.list_item2,parent,false)
return MyViewHolder(itemView)
}
//
// interface OnItemClickListener {
// fun onItemClick(position: Int)
// }
override fun onBindViewHolder(holder: MyAdapter2.MyViewHolder, position: Int) {
// holder.bind( position ,onItemClickListener)
val user:User2 = userList[position]
holder.name.text= user.name
holder.phone.text= user.phone
holder.address.text =user.address
holder.bloodGroup.text= user.bloodgroup
holder.id.text = user.id
holder.status.text= user.status
holder.donatedby.text = user.donatedBy.toString()
val statust = user.status?.trim()
val requester_name = user.name
val requester_no = user.phone
holder.emailn.text= user.email
val idp: String? =user.id
val phonen: String? =user.phone
val emailt: String? = user.email
holder.button.setOnClickListener {
holder.button.visibility = View.GONE
val washingtonre = mFireStore.collection("applicationForm").document("$idp")
washingtonre.update("status","Verified").addOnCompleteListener {
holder.status.text = "Verified"
val title = "New blood donation request."
val message = "Please contact $requester_name at $requester_no."
//val recipientToken = etToken.text.toString()
if(title.isNotEmpty() && message.isNotEmpty()) {
PushNotificationNotif(
NotificationDataNotif(title, message),
TOPIC
// recipientToken
).also {
sendNotification(it)
}
}
}
}
holder.phonen.setOnClickListener {
val context=holder.button.context
val intent1 = Intent(Intent.ACTION_DIAL)
intent1.data = Uri.parse("tel:" + phonen)
context.startActivity(intent1)
}
holder.bemail.setOnClickListener {
val context1=holder.button.context
val intent= Intent(Intent.ACTION_SEND)
intent.data = Uri.parse("mailto:" + emailt)
intent.type = "text/plain"
intent.putExtra(Intent.EXTRA_EMAIL, emailt)
intent.putExtra(Intent.EXTRA_SUBJECT, " ")
intent.putExtra(Intent.EXTRA_TEXT, " ")
intent.setType("message/rfc822")
try {
// context1.startActivity(Intent.createChooser(intent, "Choose email Client"))
context1.startActivity(intent)
} catch (e: Exception){
}
}
}
#SuppressLint("LongLogTag")
private fun sendNotification(notification: PushNotificationNotif) = CoroutineScope(
Dispatchers.IO).launch {
try {
val response = RetrofitInstanceNotif.api.postNotification(notification)
if(response.isSuccessful) {
Log.d(TAG, "Response: ${Gson().toJson(response)}")
} else {
Log.e(TAG, response.errorBody().toString())
}
} catch(e: Exception) {
Log.e(TAG, e.toString())
}
}
override fun getItemCount(): Int {
return userList.size
}
public class MyViewHolder(itemView : View): RecyclerView.ViewHolder(itemView){
// fun bind(position: Int, listener: OnItemClickListener) {
// button.setOnClickListener { v -> listener.onItemClick(position) }
// }
val name : TextView = itemView.findViewById(R.id.tvfirstname1)
val phone :TextView= itemView.findViewById(R.id.tvphone11)
val address : TextView= itemView.findViewById(R.id.tvaddress1)
val bloodGroup: TextView =itemView.findViewById(R.id.tvbloodg1)
val id: TextView = itemView.findViewById(R.id.tvid)
val status: TextView = itemView.findViewById(R.id.tvstatus1)
// val donationsta: TextView = itemView.findViewById(R.id.tvdonated1)
var io: String? = ""
val button: Button = itemView.findViewById(R.id.btn_notify)
val phonen: Button =itemView.findViewById(R.id.btn_phone1)
val emailn: TextView = itemView.findViewById(R.id.tvemail1)
val bemail: TextView = itemView.findViewById(R.id.btn_email1)
val donatedby: TextView=itemView.findViewById(R.id.tvdonated1)
}
} ```
/** This is the recyclerview activity code
package com.example.bloodbankcompany.recyclerview
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.WindowManager
import android.widget.Adapter
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.bloodbankcompany.MyAdapter
import com.example.bloodbankcompany.R
import com.example.bloodbankcompany.User1
import com.example.bloodbankcompany.User2
import com.google.firebase.firestore.*
import kotlinx.android.synthetic.main.activity_blood_application_form.*
import kotlinx.android.synthetic.main.activity_main2.*
import java.lang.NullPointerException
class MainActivity2 : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var userArrayList: ArrayList<User2>
private lateinit var myAdapter: MyAdapter2
private val mFireStore = FirebaseFirestore.getInstance()
var db = FirebaseFirestore.getInstance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
// setupActionBar()
recyclerView= findViewById(R.id.recyclerview)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.setHasFixedSize(true)
userArrayList= arrayListOf()
myAdapter =MyAdapter2(userArrayList)
recyclerView.adapter = myAdapter
EventChangeListener()
}
private fun EventChangeListener() {
try {
mFireStore.collection("applicationForm").addSnapshotListener(object :
EventListener<QuerySnapshot> {
override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
if (error != null) {
Log.e("firestore error", error.message.toString())
}
try {
for (dc: DocumentChange in value?.documentChanges!!) {
if (dc.type == DocumentChange.Type.ADDED) {
userArrayList.add(dc.document.toObject(User2::class.java))
}
// Toast.makeText(applicationContext,userArrayList.toString(), Toast.LENGTH_SHORT).show()
}
} catch (e:NullPointerException){
}
myAdapter.notifyDataSetChanged()
}
})
} catch (e:NullPointerException){
}
}
}
[1]: https://i.stack.imgur.com/loob8.jpg
I have one activity with 2 recyclerViews, both recyclers are used with Firebase. One of the recyclers displays the results of a query, the other recycler has a listener that updates every time there is an update in Firebase. I added a searchView to filter the results from Firebase. The issue I'm having is when I'm trying to search the results from the Firebase query, when I start typing I see results but when I click the X to stop searching, the adapter does not reload the array and i don't see the list of items unless I reload the activity. I'm not sure what I'm missing here. Any help/suggestion is greatly appreciated. Here is my code:
Adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Filter
import android.widget.Filterable
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.eduardoz.ezmdapp.Model.Charges
import com.eduardoz.ezmdapp.R
class ChargesAdapter (private var charges: ArrayList<Charges>
, private var chargesAll: ArrayList<Charges>
, private val itemClick: (Charges) -> Unit)
: RecyclerView.Adapter<ChargesAdapter.ViewHolder>()
, Filterable {
inner class ViewHolder(itemView: View, val itemClick: (Charges) -> Unit) :
RecyclerView.ViewHolder(itemView) {
private val chargeCode = itemView.findViewById<TextView>(R.id.chargeCodeTxt)
private val chargeDescription = itemView.findViewById<TextView>(R.id.chargeDescriptionTxt)
fun bindCharges(charges: Charges) {
chargeCode?.text = charges.chargeCode
chargeDescription?.text = charges.chargeDescription
itemView.setOnClickListener { itemClick(charges) }
}
}
init {
this.charges = charges
chargesAll = java.util.ArrayList(charges)
}
override fun getItemCount(): Int {
return charges.count()
}
override fun onBindViewHolder(holder: ChargesAdapter.ViewHolder, position: Int) {
holder.bindCharges(charges[position])
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChargesAdapter.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.charges_list, parent, false)
return ViewHolder(view, itemClick)
}
override fun getFilter(): Filter {
return searchFilter
}
private val searchFilter: Filter = object: Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
val filteredList: ArrayList<Charges> = ArrayList()
if (constraint!!.isEmpty()) {
filteredList.addAll(chargesAll)
} else {
for(item in chargesAll) {
if
(item.chargeDescription.toLowerCase().contains(constraint.toString().toLowerCase())) {
filteredList.add(item)
}
}
}
val searchResults = FilterResults()
searchResults.values = filteredList
return searchResults
}
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
charges.clear()
charges.addAll(results!!.values as Collection<Charges>)
notifyDataSetChanged()
}
}
}
Activity
descriptionSearch.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
if (newText.isNotEmpty()) {
searchViewBar(newText)
} else {
if (newText.isEmpty()) { //I ADDED THIS TO RELOAD THE ADAPTER
charges.clear()
chargeList()
}
}
return false
}
})
private fun searchViewBar(newText: String) {
chargesListener = chargesCollectionRef
.whereGreaterThanOrEqualTo(CHARGE_DESCRIPTION, newText)
.whereLessThanOrEqualTo(CHARGE_DESCRIPTION, newText+"z")
.addSnapshotListener(this) { snapshot, exception ->
if (exception != null) {
println("error")
}
if (snapshot != null) {
charges.clear()
parseData(snapshot)
}
}
}
fun parseData(snapshot: QuerySnapshot) {
for (document in snapshot.documents) {
val data = document.data
val chargeCode = data!![CHARGE_CODE] as String
val chargeDescription = data[CHARGE_DESCRIPTION] as String
val chargeSpecialty = data[CHARGE_SPECIALTY] as String
val newChargeList = Charges(chargeCode, chargeDescription, chargeSpecialty)
charges.add(newChargeList)
}
chargesFromAdapter.notifyDataSetChanged()
}
How can I take screen shot of Entire on Screen regular intervals (random between 2 to 5 minutes) without click event using Adobe flex and action script. Currently I am doing it with the Mouse_Up Event and then calling the timer and then saving each image with different name
package
{
import flash.desktop.NativeProcess;
import flash.desktop.NativeProcessStartupInfo;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageDisplayState;
import flash.display.StageScaleMode;
import flash.events.MouseEvent;
import flash.events.NativeProcessExitEvent;
import flash.events.TimerEvent;
import flash.filesystem.File;
import flash.system.Capabilities;
import flash.utils.Timer;
public class Grabber extends Sprite
{
private var stageCover:Sprite;
private var captureRect:Sprite;
private var sx:Number;
private var sy:Number;
private var np:NativeProcess;
private var npi:NativeProcessStartupInfo;
public function Grabber()
{
super();
stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stageCover = new Sprite();
stageCover.graphics.beginFill(0xFFFFFF, 0.01);
stageCover.graphics.drawRect(0, 0, Capabilities.screenResolutionX, Capabilities.screenResolutionY);
addChild(stageCover);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
captureRect = new Sprite();
captureRect.graphics.lineStyle(2, 0xFFFFFF);
addChild(captureRect);
np = new NativeProcess();
npi = new NativeProcessStartupInfo();
}
private function onTimerComplete( event:TimerEvent):void
{
captureRect.graphics.clear();
var args:Vector.<String> = new Vector.<String>();
args.push("-l");
sx =0;
args.push(sx.toString());
args.push("-t");
sy = 0 ;
args.push(sy.toString());
args.push("-r");
var a:Number = Capabilities.screenResolutionX;
args.push(a.toString());
args.push("-b");
var b:Number= Capabilities.screenResolutionY;
args.push(b.toString());
args.push("-out");
args.push(File.desktopDirectory.nativePath + "/grab.jpeg");
npi.arguments = args;
npi.executable = File.applicationDirectory.resolvePath("GrabberCommand.exe");
np.start(npi);
}
private function onMouseUp(event:MouseEvent):void
{
var timer:Timer=new Timer( 10*1000*Math.random(),1 );
timer.addEventListener( TimerEvent.TIMER, onTimerComplete );
timer.start();
}
}
}
XML Properties are
SystemChrome none
Transparent true
SupportedProfiles extendedDesktop
I actually did something like this before.
You will need a Timer that calls the following function at intervals (whatever intervals you like):
private function captureScreenshots(event:MouseEvent):void
{
var imgEnc:IImageEncoder;
var screenshotArray:Array = new Array();
if(myView.encodingCombo.selectedItem == "PNG")
{
imgEnc = pngEnc; //private const pngEnc:PNGEncoder = new PNGEncoder();
}
else
{
imgEnc = jpgEnc; //private const jpgEnc:JPEGEncoder = new JPEGEncoder();
}
var windowsArray:Array = NativeApplication.nativeApplication.openedWindows;
for each(var window:NativeWindow in windowsArray)
{
if(window && window.stage is IBitmapDrawable)
{
var imageSnapshot:ImageSnapshot = ImageSnapshot.captureImage(window.stage as IBitmapDrawable, 0, imgEnc);
screenshotArray.push(imageSnapshot);
}
}
windowsArray = null;
}
You can then use a FileStream to write them to a directory, but that would be a different question.
I am trying to add the unpublished components entry in my custom storage extension. We know that we don't have any base class in Tridion for ComponentUndeploy as we have for deploy "ComponentDeploy", so I am trying to use ComponentPresentationUndeploy class to track the components which are getting and below is sample code how I am trying to track.
package com.tridion.custom.extensions;
import com.tridion.broker.StorageException;
import com.tridion.configuration.Configuration;
import com.tridion.configuration.ConfigurationException;
import com.tridion.deployer.DeploymentHandler;
import com.tridion.deployer.ProcessingException;
import com.tridion.deployer.Processor;
import com.tridion.deployer.modules.ComponentPresentationUndeploy;
import com.tridion.storage.ComponentMeta;
import com.tridion.storage.StorageManagerFactory;
import com.tridion.storage.StorageTypeMapping;
import com.tridion.storage.dao.ItemDAO;
import com.tridion.storage.dao.ItemTypeSelector;
import com.tridion.storage.dao.PublishAction;
import com.tridion.storage.dao.PublishActionDAO;
import com.tridion.storage.mapper.MapperFactory;
import com.tridion.transport.transportpackage.ComponentPresentationKey;
import com.tridion.transport.transportpackage.ProcessorInstructions;
import com.tridion.transport.transportpackage.TransportPackage;
import com.tridion.util.TCDURI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.Iterator;
public class SearchComponentUndeployer extends ComponentPresentationUndeploy {
private static Logger log = LoggerFactory
.getLogger(SearchComponentUndeployer.class);
public SearchComponentUndeployer(Configuration paramConfiguration,
Processor paramProcessor) throws ConfigurationException {
super(paramConfiguration, paramProcessor);
}
#SuppressWarnings("rawtypes")
public void process(TransportPackage paramTransportPackage) throws ProcessingException
{
ProcessorInstructions localProcessorInstructions = paramTransportPackage.getProcessorInstructions();
try
{
Iterator localIterator = localProcessorInstructions.getArguments();
while (localIterator.hasNext())
{
Object localObject = localIterator.next();
if (localObject instanceof ComponentPresentationKey)
{
ComponentPresentationKey localComponentPresentationKey = (ComponentPresentationKey) localObject;
long[] arrayOfLong = new long[2];
arrayOfLong[0] = localComponentPresentationKey.getComponentKey().getId().getItemId();
arrayOfLong[1] = localComponentPresentationKey.getTemplateKey().getId().getItemId();
int PubID = localComponentPresentationKey.getComponentKey().getId().getPublicationId();
String tcmID = Integer.toString(localComponentPresentationKey.getComponentKey().getId().getItemId());
log.info("SearchComponentUndeployer -PubID" + PubID);
log.info("SearchComponentUndeployer -tcmID" + tcmID);
ItemDAO itemDAO = ((ItemDAO) StorageManagerFactory.getDAO(PubID, StorageTypeMapping.COMPONENT_META));
log.info("SearchComponentUndeployer -itemDAO"+ itemDAO.getStorageId());
ComponentMeta compObject = (ComponentMeta) MapperFactory.mapItemMetaInstance(itemDAO.findByPrimaryKey(PubID, localComponentPresentationKey.getComponentKey().getId().getItemId(),ItemTypeSelector.COMPONENT));
log.info("SearchComponentUndeployer -compObject"+ compObject.getTitle());
String formatTCMID = String.format("tcm:%d-%s-64", PubID,tcmID);
log.info("SearchComponentUndeployer - formatTCMID -"+ formatTCMID);
String strIgnorePubIds = "232,481";
String strPubId = Integer.toString(PubID);
Date lastPublishedDate = compObject.getLastPublishDate();
String schemaID = Integer.toString(compObject.getSchemaId());
if (!strIgnorePubIds.contains(strPubId))
{
PublishAction publishAction = new PublishAction();
publishAction.setAction("DEL");
publishAction.setTcmUri(formatTCMID);
publishAction.setItemType(16);
publishAction.setPublicationID(PubID);
publishAction.setLastPublishedDate(lastPublishedDate);
publishAction.setSchemaID(schemaID);
PublishActionDAO publishActionDAO = (PublishActionDAO) StorageManagerFactory.getDefaultDAO("PublishAction");
log.debug("SearchComponentUndeployer Going to Store bean -" + publishAction.toString());
publishAction = publishActionDAO.store(publishAction);
log.debug("SearchComponentUndeployer Stored bean -" + publishAction);
}
DeploymentHandler.undeploy(new TCDURI(PubID, 73014444080L, arrayOfLong));
}
}
}
catch (StorageException e)
{
log.error("Could not undeploy component presentation", e);
}
}
}
Any idea why I am not getting any entry for components in my database
Edit: Added sample code from PageUndeploy implementation done by me:
Object argument = iterator.next();
if (argument instanceof PageKey)
{
PageKey pageKey = (PageKey) argument;
TCDURI pageMetaURI = new TCDURI(pageKey.getId() .getPublicationId(), 1168231104576L, pageKey.getId().getItemId());
PageMeta pageMeta = this.pageMetaHome.findByPrimaryKey(pageMetaURI.getPublicationId(),(int) pageMetaURI.getItemId());
if (pageMeta == null)
{
DeploymentHandler.undeploy(pageMetaURI);
}
else
{
//Here I need to loop for componentpresentation and get component object
}
}
You can try this as I just taken class name from your input
List<ComponentPresentationMeta> lstCompObjects= pageMeta.getComponentPresentationMetas();
if(lstCompObjects != null && !lstCompObjects.isEmpty())
{
for(ComponentPresentationMeta compMeta : lstCompObjects)
{
String compID = Integer.toString(compMeta.getComponentId());
ItemDAO itemDAO = ((ItemDAO) StorageManagerFactory.getDAO(compMeta.getPublicationId(), StorageTypeMapping.COMPONENT_META));
ComponentMeta compObject = (ComponentMeta) MapperFactory.mapItemMetaInstance(itemDAO.findByPrimaryKey(compMeta.getPublicationId(), compMeta.getComponentId(),ItemTypeSelector.COMPONENT));
PublishAction compPublishAction = new PublishAction();
compPublishAction.setAction("DEL");
compPublishAction.setTcmUri(compID);
compPublishAction.setItemType(16);
compPublishAction.setPublicationID(compMeta.getPublicationId());
compPublishAction.setLastPublishedDate(compObject.getLastPublicationDate());
compPublishAction.setSchemaID(Integer.toString(compObject.getSchemaId()));
compPublishAction = publishActionDAO.store(compPublishAction);
}
}
I know there are a number of posts dealing with this issue. But, I'm still not understanding it.
I keep getting a "1120: Access of undefined property CSSloader." in the following script:
package as3.comp{
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.text.StyleSheet;
public class cont extends MovieClip {
public var contentWidth:Number;
public var contentHeight:Number;
private var myXML:XML;
private var myLoader:URLLoader;
public function cont():void {
//Start
}
public function start():void {
myTooltip.start();
myTooltip.followMouse(false);
myTooltip.hide();
myWaiting.start();
myWaiting.hide();
myXML = new XML();
myXML.ignoreComments=true;
myXML.ignoreWhitespace=true;
contentWidth=100;
contentHeight=100;
contentSpace.width=contentWidth;
contentSpace.height=contentHeight;
//myWaiting.hide(); //hide clock
}
public function loadMc(contentFile:String):void {
var pictLdr:Loader = new Loader();
var pictURL:String=contentFile;
var pictURLReq:URLRequest=new URLRequest(pictURL);
pictLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoadedF);
pictLdr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, preloader);
pictLdr.load(pictURLReq);
contentLoadMC.addChild(pictLdr);
}
private function imgLoadedF(event:Event):void {
myTooltip.hide();
MovieClip(parent.parent).addContentMovie(this);
MovieClip(parent.parent).refresh();
}
private function preloader(event:ProgressEvent):void {
var pcent:Number=event.bytesLoaded/event.bytesTotal*100;
myTooltip.show(""+int(pcent));
}
public function loadCSS(event:Event):void {
var CSSloader:URLLoader = new URLLoader();
var req_css:URLRequest = new URLRequest("example.css");
CSSloader.load(req_css);
CSSloader.addEventListener("complete", loadXML);
}
public function loadXML(contentFile:String) {
var XML_URL:String=contentFile;
var myXMLURL:URLRequest=new URLRequest(XML_URL);
myLoader=new URLLoader(myXMLURL);
myLoader.addEventListener("complete", xmlLoaded);
}
private function xmlLoaded(event:Event):void {
myXML=XML(myLoader.data);
myXML.ignoreWhite = true;
var sheet:StyleSheet = new StyleSheet();
sheet.parseCSS(CSSloader.data);
myHtmlText.styleSheet = sheet;
myHtmlText.htmlText="HERE" + myXML.pageTop;
myHtmlText.width=contentWidth-10;
myHtmlText.height=myHtmlText.textHeight+30;
myHtmlText.x=10;
myHtmlText.y=10;
contentSpace.width=contentWidth;
contentSpace.height=myHtmlText.height+4;
myWaiting.hide();
MovieClip(parent.parent).addContentMovie(this);
MovieClip(parent.parent).refresh();
myLoader.removeEventListener("complete", xmlLoaded);
}
public function loadContent(contentFile:String) {
if (contentFile.substr(-3)=="xml") {
myWaiting.show();//show clock
loadXML(contentFile);
} else {
myTooltip.show("0");
loadMc(contentFile);
}
}
}
}
I've tried adding the code within loadCSS to both loadXML and xmlLoaded, but get the same error.
Any help would be GREATLY appreciated. Thanks.
You declared CSSloader in the function loadCSS, but you get the error in the function xmlloaded, which is a different scope. If you want CSSloader to be scoped for all functions, you'll have to declare it as a variable outside these functions - by convention at the top. (Unfortunately you have omitted the context of this code, but I assume this is inside a class?).