From 89e3959cf393ce9eeb058304264d4f55f4fe9ca2 Mon Sep 17 00:00:00 2001
From: "Brad Payne (Vir Linden)" <vir@lindenlab.com>
Date: Fri, 7 Jun 2013 12:58:04 -0400
Subject: SH-4216 WIP - moved AISv3 commands and responders to llaisapi.* files

---
 indra/newview/CMakeLists.txt        |   2 +
 indra/newview/llaisapi.cpp          | 481 ++++++++++++++++++++++++++++++++++++
 indra/newview/llaisapi.h            | 143 +++++++++++
 indra/newview/llinventorymodel.cpp  | 248 +------------------
 indra/newview/llviewerinventory.cpp |   3 +
 5 files changed, 630 insertions(+), 247 deletions(-)
 create mode 100755 indra/newview/llaisapi.cpp
 create mode 100755 indra/newview/llaisapi.h

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 4560951900..dc9370bd69 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -98,6 +98,7 @@ include_directories(SYSTEM
 set(viewer_SOURCE_FILES
     groupchatlistener.cpp
     llaccountingcostmanager.cpp
+    llaisapi.cpp
     llagent.cpp
     llagentaccess.cpp
     llagentcamera.cpp
@@ -679,6 +680,7 @@ set(viewer_HEADER_FILES
     ViewerInstall.cmake
     groupchatlistener.h
     llaccountingcostmanager.h
+    llaisapi.h
     llagent.h
     llagentaccess.h
     llagentcamera.h
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
new file mode 100755
index 0000000000..6adf35efb8
--- /dev/null
+++ b/indra/newview/llaisapi.cpp
@@ -0,0 +1,481 @@
+/** 
+ * @file llaisapi.cpp
+ * @brief classes and functions for interfacing with the v3+ ais inventory service. 
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ *
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llaisapi.h"
+
+#include "llagent.h"
+#include "llcallbacklist.h"
+#include "llinventorymodel.h"
+#include "llsdutil.h"
+#include "llviewerregion.h"
+
+///----------------------------------------------------------------------------
+/// Classes for AISv3 support.
+///----------------------------------------------------------------------------
+
+// AISCommand - base class for retry-able HTTP requests using the AISv3 cap.
+AISCommand::AISCommand(LLPointer<LLInventoryCallback> callback):
+	mCallback(callback)
+{
+	mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10);
+}
+
+void AISCommand::run_command()
+{
+	mCommandFunc();
+}
+
+void AISCommand::setCommandFunc(command_func_type command_func)
+{
+	mCommandFunc = command_func;
+}
+	
+// virtual
+bool AISCommand::getResponseUUID(const LLSD& content, LLUUID& id)
+{
+	return false;
+}
+	
+/* virtual */
+void AISCommand::httpSuccess()
+{
+	// Command func holds a reference to self, need to release it
+	// after a success or final failure.
+	setCommandFunc(no_op);
+		
+	const LLSD& content = getContent();
+	if (!content.isMap())
+	{
+		failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
+		return;
+	}
+	mRetryPolicy->onSuccess();
+		
+	gInventory.onAISUpdateReceived("AISCommand", content);
+
+	if (mCallback)
+	{
+		LLUUID item_id; // will default to null if parse fails.
+		getResponseUUID(content,item_id);
+		mCallback->fire(item_id);
+	}
+}
+
+/*virtual*/
+void AISCommand::httpFailure()
+{
+	const LLSD& content = getContent();
+	S32 status = getStatus();
+	const std::string& reason = getReason();
+	const LLSD& headers = getResponseHeaders();
+	if (!content.isMap())
+	{
+		LL_DEBUGS("Inventory") << "Malformed response contents " << content
+							   << " status " << status << " reason " << reason << llendl;
+	}
+	else
+	{
+		LL_DEBUGS("Inventory") << "failed with content: " << ll_pretty_print_sd(content)
+							   << " status " << status << " reason " << reason << llendl;
+	}
+	mRetryPolicy->onFailure(status, headers);
+	F32 seconds_to_wait;
+	if (mRetryPolicy->shouldRetry(seconds_to_wait))
+	{
+		doAfterInterval(boost::bind(&AISCommand::run_command,this),seconds_to_wait);
+	}
+	else
+	{
+		// Command func holds a reference to self, need to release it
+		// after a success or final failure.
+		setCommandFunc(no_op);
+	}
+}
+
+//static
+bool AISCommand::getCap(std::string& cap)
+{
+	if (gAgent.getRegion())
+	{
+		cap = gAgent.getRegion()->getCapability("InventoryAPIv3");
+	}
+	if (!cap.empty())
+	{
+		return true;
+	}
+	return false;
+}
+
+RemoveItemCommand::RemoveItemCommand(const LLUUID& item_id,
+									 LLPointer<LLInventoryCallback> callback):
+	AISCommand(callback)
+{
+	std::string cap;
+	if (!getCap(cap))
+	{
+		llwarns << "No cap found" << llendl;
+		return;
+	}
+	std::string url = cap + std::string("/item/") + item_id.asString();
+	LL_DEBUGS("Inventory") << "url: " << url << llendl;
+	LLHTTPClient::ResponderPtr responder = this;
+	LLSD headers;
+	F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
+	command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout);
+	setCommandFunc(cmd);
+}
+
+RemoveCategoryCommand::RemoveCategoryCommand(const LLUUID& item_id,
+											 LLPointer<LLInventoryCallback> callback):
+	AISCommand(callback)
+{
+	std::string cap;
+	if (!getCap(cap))
+	{
+		llwarns << "No cap found" << llendl;
+		return;
+	}
+	std::string url = cap + std::string("/category/") + item_id.asString();
+	LL_DEBUGS("Inventory") << "url: " << url << llendl;
+	LLHTTPClient::ResponderPtr responder = this;
+	LLSD headers;
+	F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
+	command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout);
+	setCommandFunc(cmd);
+}
+
+PurgeDescendentsCommand::PurgeDescendentsCommand(const LLUUID& item_id,
+												 LLPointer<LLInventoryCallback> callback):
+	AISCommand(callback)
+{
+	std::string cap;
+	if (!getCap(cap))
+	{
+		llwarns << "No cap found" << llendl;
+		return;
+	}
+	std::string url = cap + std::string("/category/") + item_id.asString() + "/children";
+	LL_DEBUGS("Inventory") << "url: " << url << llendl;
+	LLCurl::ResponderPtr responder = this;
+	LLSD headers;
+	F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
+	command_func_type cmd = boost::bind(&LLHTTPClient::del, url, responder, headers, timeout);
+	setCommandFunc(cmd);
+}
+
+UpdateItemCommand::UpdateItemCommand(const LLUUID& item_id,
+									 const LLSD& updates,
+									 LLPointer<LLInventoryCallback> callback):
+	mUpdates(updates),
+	AISCommand(callback)
+{
+	std::string cap;
+	if (!getCap(cap))
+	{
+		llwarns << "No cap found" << llendl;
+		return;
+	}
+	std::string url = cap + std::string("/item/") + item_id.asString();
+	LL_DEBUGS("Inventory") << "url: " << url << llendl;
+	LLCurl::ResponderPtr responder = this;
+	LLSD headers;
+	headers["Content-Type"] = "application/llsd+xml";
+	F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
+	command_func_type cmd = boost::bind(&LLHTTPClient::patch, url, mUpdates, responder, headers, timeout);
+	setCommandFunc(cmd);
+}
+
+UpdateCategoryCommand::UpdateCategoryCommand(const LLUUID& item_id,
+											 const LLSD& updates,
+											 LLPointer<LLInventoryCallback> callback):
+	mUpdates(updates),
+	AISCommand(callback)
+{
+	std::string cap;
+	if (!getCap(cap))
+	{
+		llwarns << "No cap found" << llendl;
+		return;
+	}
+	std::string url = cap + std::string("/category/") + item_id.asString();
+	LL_DEBUGS("Inventory") << "url: " << url << llendl;
+	LLCurl::ResponderPtr responder = this;
+	LLSD headers;
+	headers["Content-Type"] = "application/llsd+xml";
+	F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
+	command_func_type cmd = boost::bind(&LLHTTPClient::patch, url, mUpdates, responder, headers, timeout);
+	setCommandFunc(cmd);
+}
+
+SlamFolderCommand::SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback):
+	mContents(contents),
+	AISCommand(callback)
+{
+	std::string cap;
+	if (!getCap(cap))
+	{
+		llwarns << "No cap found" << llendl;
+		return;
+	}
+	LLUUID tid;
+	tid.generate();
+	std::string url = cap + std::string("/category/") + folder_id.asString() + "/links?tid=" + tid.asString();
+	llinfos << url << llendl;
+	LLCurl::ResponderPtr responder = this;
+	LLSD headers;
+	headers["Content-Type"] = "application/llsd+xml";
+	F32 timeout = HTTP_REQUEST_EXPIRY_SECS;
+	command_func_type cmd = boost::bind(&LLHTTPClient::put, url, mContents, responder, headers, timeout);
+	setCommandFunc(cmd);
+}
+
+AISUpdate::AISUpdate(const LLSD& update)
+{
+	parseUpdate(update);
+}
+
+void AISUpdate::parseUpdate(const LLSD& update)
+{
+	// parse _categories_removed -> mObjectsDeleted
+	uuid_vec_t cat_ids;
+	parseUUIDArray(update,"_categories_removed",cat_ids);
+	for (uuid_vec_t::const_iterator it = cat_ids.begin();
+		 it != cat_ids.end(); ++it)
+	{
+		LLViewerInventoryCategory *cat = gInventory.getCategory(*it);
+		mCatDeltas[cat->getParentUUID()]--;
+		mObjectsDeleted.insert(*it);
+	}
+
+	// parse _categories_items_removed -> mObjectsDeleted
+	uuid_vec_t item_ids;
+	parseUUIDArray(update,"_category_items_removed",item_ids);
+	for (uuid_vec_t::const_iterator it = item_ids.begin();
+		 it != item_ids.end(); ++it)
+	{
+		LLViewerInventoryItem *item = gInventory.getItem(*it);
+		mCatDeltas[item->getParentUUID()]--;
+		mObjectsDeleted.insert(*it);
+	}
+
+	// parse _broken_links_removed -> mObjectsDeleted
+	uuid_vec_t broken_link_ids;
+	parseUUIDArray(update,"_broken_links_removed",broken_link_ids);
+	for (uuid_vec_t::const_iterator it = broken_link_ids.begin();
+		 it != broken_link_ids.end(); ++it)
+	{
+		LLViewerInventoryItem *item = gInventory.getItem(*it);
+		mCatDeltas[item->getParentUUID()]--;
+		mObjectsDeleted.insert(*it);
+	}
+
+	// parse _created_items
+	parseUUIDArray(update,"_created_items",mItemsCreatedIds);
+
+	if (update.has("_embedded"))
+	{
+		const LLSD& embedded = update["_embedded"];
+		for(LLSD::map_const_iterator it = embedded.beginMap(),
+				end = embedded.endMap();
+				it != end; ++it)
+		{
+			const std::string& field = (*it).first;
+			
+			// parse created links
+			if (field == "link")
+			{
+				const LLSD& links = embedded["link"];
+				parseCreatedLinks(links);
+			}
+			else
+			{
+				llwarns << "unrecognized embedded field " << field << llendl;
+			}
+		}
+		
+	}
+
+	// Parse item update at the top level.
+	if (update.has("item_id"))
+	{
+		LLUUID item_id = update["item_id"].asUUID();
+		LLPointer<LLViewerInventoryItem> new_item(new LLViewerInventoryItem);
+		BOOL rv = new_item->unpackMessage(update);
+		if (rv)
+		{
+			mItemsUpdated[item_id] = new_item;
+			// This statement is here to cause a new entry with 0
+			// delta to be created if it does not already exist;
+			// otherwise has no effect.
+			mCatDeltas[new_item->getParentUUID()];
+		}
+		else
+		{
+			llerrs << "unpack failed" << llendl;
+		}
+	}
+
+	// Parse updated category versions.
+	const std::string& ucv = "_updated_category_versions";
+	if (update.has(ucv))
+	{
+		for(LLSD::map_const_iterator it = update[ucv].beginMap(),
+				end = update[ucv].endMap();
+			it != end; ++it)
+		{
+			const LLUUID id((*it).first);
+			S32 version = (*it).second.asInteger();
+			mCatVersions[id] = version;
+		}
+	}
+}
+
+void AISUpdate::parseUUIDArray(const LLSD& content, const std::string& name, uuid_vec_t& ids)
+{
+	ids.clear();
+	if (content.has(name))
+	{
+		for(LLSD::array_const_iterator it = content[name].beginArray(),
+				end = content[name].endArray();
+				it != end; ++it)
+		{
+			ids.push_back((*it).asUUID());
+		}
+	}
+}
+
+void AISUpdate::parseLink(const LLUUID& link_id, const LLSD& link_map)
+{
+	LLPointer<LLViewerInventoryItem> new_link(new LLViewerInventoryItem);
+	BOOL rv = new_link->unpackMessage(link_map);
+	if (rv)
+	{
+		LLPermissions default_perms;
+		default_perms.init(gAgent.getID(),gAgent.getID(),LLUUID::null,LLUUID::null);
+		default_perms.initMasks(PERM_NONE,PERM_NONE,PERM_NONE,PERM_NONE,PERM_NONE);
+		new_link->setPermissions(default_perms);
+		LLSaleInfo default_sale_info;
+		new_link->setSaleInfo(default_sale_info);
+		//LL_DEBUGS("Inventory") << "creating link from llsd: " << ll_pretty_print_sd(link_map) << llendl;
+		mItemsCreated[link_id] = new_link;
+		const LLUUID& parent_id = new_link->getParentUUID();
+		mCatDeltas[parent_id]++;
+	}
+	else
+	{
+		llwarns << "failed to parse" << llendl;
+	}
+}
+
+void AISUpdate::parseCreatedLinks(const LLSD& links)
+{
+	for(LLSD::map_const_iterator linkit = links.beginMap(),
+			linkend = links.endMap();
+		linkit != linkend; ++linkit)
+	{
+		const LLUUID link_id((*linkit).first);
+		const LLSD& link_map = (*linkit).second;
+		uuid_vec_t::const_iterator pos =
+			std::find(mItemsCreatedIds.begin(),
+					  mItemsCreatedIds.end(),link_id);
+		if (pos != mItemsCreatedIds.end())
+		{
+			parseLink(link_id,link_map);
+		}
+		else
+		{
+			LL_DEBUGS("Inventory") << "Ignoring link not in created items list " << link_id << llendl;
+		}
+	}
+}
+
+void AISUpdate::doUpdate()
+{
+	// Do descendent/version accounting.
+	// Can remove this if/when we use the version info directly.
+	for (std::map<LLUUID,S32>::const_iterator catit = mCatDeltas.begin();
+		 catit != mCatDeltas.end(); ++catit)
+	{
+		const LLUUID cat_id(catit->first);
+		S32 delta = catit->second;
+		LLInventoryModel::LLCategoryUpdate up(cat_id, delta);
+		gInventory.accountForUpdate(up);
+	}
+	
+	// TODO - how can we use this version info? Need to be sure all
+	// changes are going through AIS first, or at least through
+	// something with a reliable responder.
+	for (uuid_int_map_t::iterator ucv_it = mCatVersions.begin();
+		 ucv_it != mCatVersions.end(); ++ucv_it)
+	{
+		const LLUUID id = ucv_it->first;
+		S32 version = ucv_it->second;
+		LLViewerInventoryCategory *cat = gInventory.getCategory(id);
+		if (cat->getVersion() != version)
+		{
+			llwarns << "Possible version mismatch, viewer " << cat->getVersion()
+					<< " server " << version << llendl;
+		}
+	}
+
+	// CREATE ITEMS
+	for (deferred_item_map_t::const_iterator create_it = mItemsCreated.begin();
+		 create_it != mItemsCreated.end(); ++create_it)
+	{
+		LLUUID item_id(create_it->first);
+		LLPointer<LLViewerInventoryItem> new_item = create_it->second;
+
+		// FIXME risky function since it calls updateServer() in some
+		// cases.  Maybe break out the update/create cases, in which
+		// case this is create.
+		LL_DEBUGS("Inventory") << "created item " << item_id << llendl;
+		gInventory.updateItem(new_item);
+	}
+	
+	// UPDATE ITEMS
+	for (deferred_item_map_t::const_iterator update_it = mItemsUpdated.begin();
+		 update_it != mItemsUpdated.end(); ++update_it)
+	{
+		LLUUID item_id(update_it->first);
+		LLPointer<LLViewerInventoryItem> new_item = update_it->second;
+		// FIXME risky function since it calls updateServer() in some
+		// cases.  Maybe break out the update/create cases, in which
+		// case this is update.
+		LL_DEBUGS("Inventory") << "updated item " << item_id << llendl;
+		gInventory.updateItem(new_item);
+	}
+
+	// DELETE OBJECTS
+	for (std::set<LLUUID>::const_iterator del_it = mObjectsDeleted.begin();
+		 del_it != mObjectsDeleted.end(); ++del_it)
+	{
+		LL_DEBUGS("Inventory") << "deleted item " << *del_it << llendl;
+		gInventory.onObjectDeletedFromServer(*del_it, false, false);
+	}
+}
+
diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h
new file mode 100755
index 0000000000..1f9555f004
--- /dev/null
+++ b/indra/newview/llaisapi.h
@@ -0,0 +1,143 @@
+/** 
+ * @file llaisapi.h
+ * @brief classes and functions for interfacing with the v3+ ais inventory service. 
+ *
+ * $LicenseInfo:firstyear=2013&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAISAPI_H
+#define LL_LLAISAPI_H
+
+#include "lluuid.h"
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include "llcurl.h"
+#include "llhttpclient.h"
+#include "llhttpretrypolicy.h"
+#include "llviewerinventory.h"
+
+class AISCommand: public LLHTTPClient::Responder
+{
+public:
+	typedef boost::function<void()> command_func_type;
+
+	AISCommand(LLPointer<LLInventoryCallback> callback);
+
+	virtual ~AISCommand() {}
+
+	void run_command();
+
+	void setCommandFunc(command_func_type command_func);
+	
+	// Need to do command-specific parsing to get an id here, for
+	// LLInventoryCallback::fire().  May or may not need to bother,
+	// since most LLInventoryCallbacks do their work in the
+	// destructor.
+	virtual bool getResponseUUID(const LLSD& content, LLUUID& id);
+	
+	/* virtual */ void httpSuccess();
+
+	/*virtual*/ void httpFailure();
+
+	static bool getCap(std::string& cap);
+
+private:
+	command_func_type mCommandFunc;
+	LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
+	LLPointer<LLInventoryCallback> mCallback;
+};
+
+class RemoveItemCommand: public AISCommand
+{
+public:
+	RemoveItemCommand(const LLUUID& item_id,
+					  LLPointer<LLInventoryCallback> callback);
+};
+
+class RemoveCategoryCommand: public AISCommand
+{
+public:
+	RemoveCategoryCommand(const LLUUID& item_id,
+						  LLPointer<LLInventoryCallback> callback);
+};
+
+class PurgeDescendentsCommand: public AISCommand
+{
+public:
+	PurgeDescendentsCommand(const LLUUID& item_id,
+							LLPointer<LLInventoryCallback> callback);
+};
+
+class UpdateItemCommand: public AISCommand
+{
+public:
+	UpdateItemCommand(const LLUUID& item_id,
+					  const LLSD& updates,
+					  LLPointer<LLInventoryCallback> callback);
+private:
+	LLSD mUpdates;
+};
+
+class UpdateCategoryCommand: public AISCommand
+{
+public:
+	UpdateCategoryCommand(const LLUUID& item_id,
+						  const LLSD& updates,
+						  LLPointer<LLInventoryCallback> callback);
+private:
+	LLSD mUpdates;
+};
+
+class SlamFolderCommand: public AISCommand
+{
+public:
+	SlamFolderCommand(const LLUUID& folder_id, const LLSD& contents, LLPointer<LLInventoryCallback> callback);
+	
+private:
+	LLSD mContents;
+};
+
+class AISUpdate
+{
+public:
+	AISUpdate(const LLSD& update);
+	void parseUpdate(const LLSD& update);
+	void parseUUIDArray(const LLSD& content, const std::string& name, uuid_vec_t& ids);
+	void parseLink(const LLUUID& link_id, const LLSD& link_map);
+	void parseCreatedLinks(const LLSD& links);
+	void doUpdate();
+private:
+	typedef std::map<LLUUID,S32> uuid_int_map_t;
+	uuid_int_map_t mCatDeltas;
+	uuid_int_map_t mCatVersions;
+
+	typedef std::map<LLUUID,LLPointer<LLViewerInventoryItem> > deferred_item_map_t;
+	deferred_item_map_t mItemsCreated;
+	deferred_item_map_t mItemsUpdated;
+
+	std::set<LLUUID> mObjectsDeleted;
+	uuid_vec_t mItemsCreatedIds;
+};
+
+#endif
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 3c7539a7f9..6dc193292e 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -27,6 +27,7 @@
 #include "llviewerprecompiledheaders.h"
 #include "llinventorymodel.h"
 
+#include "llaisapi.h"
 #include "llagent.h"
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
@@ -1154,253 +1155,6 @@ void LLInventoryModel::changeCategoryParent(LLViewerInventoryCategory* cat,
 	notifyObservers();
 }
 
-class AISUpdate
-{
-public:
-	AISUpdate(const LLSD& update);
-	void parseUpdate(const LLSD& update);
-	void parseUUIDArray(const LLSD& content, const std::string& name, uuid_vec_t& ids);
-	void parseLink(const LLUUID& link_id, const LLSD& link_map);
-	void parseCreatedLinks(const LLSD& links);
-	void doUpdate();
-private:
-	typedef std::map<LLUUID,S32> uuid_int_map_t;
-	uuid_int_map_t mCatDeltas;
-	uuid_int_map_t mCatVersions;
-
-	typedef std::map<LLUUID,LLPointer<LLViewerInventoryItem> > deferred_item_map_t;
-	deferred_item_map_t mItemsCreated;
-	deferred_item_map_t mItemsUpdated;
-
-	std::set<LLUUID> mObjectsDeleted;
-	uuid_vec_t mItemsCreatedIds;
-};
-
-AISUpdate::AISUpdate(const LLSD& update)
-{
-	parseUpdate(update);
-}
-
-void AISUpdate::parseUpdate(const LLSD& update)
-{
-	// parse _categories_removed -> mObjectsDeleted
-	uuid_vec_t cat_ids;
-	parseUUIDArray(update,"_categories_removed",cat_ids);
-	for (uuid_vec_t::const_iterator it = cat_ids.begin();
-		 it != cat_ids.end(); ++it)
-	{
-		LLViewerInventoryCategory *cat = gInventory.getCategory(*it);
-		mCatDeltas[cat->getParentUUID()]--;
-		mObjectsDeleted.insert(*it);
-	}
-
-	// parse _categories_items_removed -> mObjectsDeleted
-	uuid_vec_t item_ids;
-	parseUUIDArray(update,"_category_items_removed",item_ids);
-	for (uuid_vec_t::const_iterator it = item_ids.begin();
-		 it != item_ids.end(); ++it)
-	{
-		LLViewerInventoryItem *item = gInventory.getItem(*it);
-		mCatDeltas[item->getParentUUID()]--;
-		mObjectsDeleted.insert(*it);
-	}
-
-	// parse _broken_links_removed -> mObjectsDeleted
-	uuid_vec_t broken_link_ids;
-	parseUUIDArray(update,"_broken_links_removed",broken_link_ids);
-	for (uuid_vec_t::const_iterator it = broken_link_ids.begin();
-		 it != broken_link_ids.end(); ++it)
-	{
-		LLViewerInventoryItem *item = gInventory.getItem(*it);
-		mCatDeltas[item->getParentUUID()]--;
-		mObjectsDeleted.insert(*it);
-	}
-
-	// parse _created_items
-	parseUUIDArray(update,"_created_items",mItemsCreatedIds);
-
-	if (update.has("_embedded"))
-	{
-		const LLSD& embedded = update["_embedded"];
-		for(LLSD::map_const_iterator it = embedded.beginMap(),
-				end = embedded.endMap();
-				it != end; ++it)
-		{
-			const std::string& field = (*it).first;
-			
-			// parse created links
-			if (field == "link")
-			{
-				const LLSD& links = embedded["link"];
-				parseCreatedLinks(links);
-			}
-			else
-			{
-				llwarns << "unrecognized embedded field " << field << llendl;
-			}
-		}
-		
-	}
-
-	// Parse item update at the top level.
-	if (update.has("item_id"))
-	{
-		LLUUID item_id = update["item_id"].asUUID();
-		LLPointer<LLViewerInventoryItem> new_item(new LLViewerInventoryItem);
-		BOOL rv = new_item->unpackMessage(update);
-		if (rv)
-		{
-			mItemsUpdated[item_id] = new_item;
-			// This statement is here to cause a new entry with 0
-			// delta to be created if it does not already exist;
-			// otherwise has no effect.
-			mCatDeltas[new_item->getParentUUID()];
-		}
-		else
-		{
-			llerrs << "unpack failed" << llendl;
-		}
-	}
-
-	// Parse updated category versions.
-	const std::string& ucv = "_updated_category_versions";
-	if (update.has(ucv))
-	{
-		for(LLSD::map_const_iterator it = update[ucv].beginMap(),
-				end = update[ucv].endMap();
-			it != end; ++it)
-		{
-			const LLUUID id((*it).first);
-			S32 version = (*it).second.asInteger();
-			mCatVersions[id] = version;
-		}
-	}
-}
-
-void AISUpdate::parseUUIDArray(const LLSD& content, const std::string& name, uuid_vec_t& ids)
-{
-	ids.clear();
-	if (content.has(name))
-	{
-		for(LLSD::array_const_iterator it = content[name].beginArray(),
-				end = content[name].endArray();
-				it != end; ++it)
-		{
-			ids.push_back((*it).asUUID());
-		}
-	}
-}
-
-void AISUpdate::parseLink(const LLUUID& link_id, const LLSD& link_map)
-{
-	LLPointer<LLViewerInventoryItem> new_link(new LLViewerInventoryItem);
-	BOOL rv = new_link->unpackMessage(link_map);
-	if (rv)
-	{
-		LLPermissions default_perms;
-		default_perms.init(gAgent.getID(),gAgent.getID(),LLUUID::null,LLUUID::null);
-		default_perms.initMasks(PERM_NONE,PERM_NONE,PERM_NONE,PERM_NONE,PERM_NONE);
-		new_link->setPermissions(default_perms);
-		LLSaleInfo default_sale_info;
-		new_link->setSaleInfo(default_sale_info);
-		//LL_DEBUGS("Inventory") << "creating link from llsd: " << ll_pretty_print_sd(link_map) << llendl;
-		mItemsCreated[link_id] = new_link;
-		const LLUUID& parent_id = new_link->getParentUUID();
-		mCatDeltas[parent_id]++;
-	}
-	else
-	{
-		llwarns << "failed to parse" << llendl;
-	}
-}
-
-void AISUpdate::parseCreatedLinks(const LLSD& links)
-{
-	for(LLSD::map_const_iterator linkit = links.beginMap(),
-			linkend = links.endMap();
-		linkit != linkend; ++linkit)
-	{
-		const LLUUID link_id((*linkit).first);
-		const LLSD& link_map = (*linkit).second;
-		uuid_vec_t::const_iterator pos =
-			std::find(mItemsCreatedIds.begin(),
-					  mItemsCreatedIds.end(),link_id);
-		if (pos != mItemsCreatedIds.end())
-		{
-			parseLink(link_id,link_map);
-		}
-		else
-		{
-			LL_DEBUGS("Inventory") << "Ignoring link not in created items list " << link_id << llendl;
-		}
-	}
-}
-
-void AISUpdate::doUpdate()
-{
-	// Do descendent/version accounting.
-	// Can remove this if/when we use the version info directly.
-	for (std::map<LLUUID,S32>::const_iterator catit = mCatDeltas.begin();
-		 catit != mCatDeltas.end(); ++catit)
-	{
-		const LLUUID cat_id(catit->first);
-		S32 delta = catit->second;
-		LLInventoryModel::LLCategoryUpdate up(cat_id, delta);
-		gInventory.accountForUpdate(up);
-	}
-	
-	// TODO - how can we use this version info? Need to be sure all
-	// changes are going through AIS first, or at least through
-	// something with a reliable responder.
-	for (uuid_int_map_t::iterator ucv_it = mCatVersions.begin();
-		 ucv_it != mCatVersions.end(); ++ucv_it)
-	{
-		const LLUUID id = ucv_it->first;
-		S32 version = ucv_it->second;
-		LLViewerInventoryCategory *cat = gInventory.getCategory(id);
-		if (cat->getVersion() != version)
-		{
-			llwarns << "Possible version mismatch, viewer " << cat->getVersion()
-					<< " server " << version << llendl;
-		}
-	}
-
-	// CREATE ITEMS
-	for (deferred_item_map_t::const_iterator create_it = mItemsCreated.begin();
-		 create_it != mItemsCreated.end(); ++create_it)
-	{
-		LLUUID item_id(create_it->first);
-		LLPointer<LLViewerInventoryItem> new_item = create_it->second;
-
-		// FIXME risky function since it calls updateServer() in some
-		// cases.  Maybe break out the update/create cases, in which
-		// case this is create.
-		LL_DEBUGS("Inventory") << "created item " << item_id << llendl;
-		gInventory.updateItem(new_item);
-	}
-	
-	// UPDATE ITEMS
-	for (deferred_item_map_t::const_iterator update_it = mItemsUpdated.begin();
-		 update_it != mItemsUpdated.end(); ++update_it)
-	{
-		LLUUID item_id(update_it->first);
-		LLPointer<LLViewerInventoryItem> new_item = update_it->second;
-		// FIXME risky function since it calls updateServer() in some
-		// cases.  Maybe break out the update/create cases, in which
-		// case this is update.
-		LL_DEBUGS("Inventory") << "updated item " << item_id << llendl;
-		gInventory.updateItem(new_item);
-	}
-
-	// DELETE OBJECTS
-	for (std::set<LLUUID>::const_iterator del_it = mObjectsDeleted.begin();
-		 del_it != mObjectsDeleted.end(); ++del_it)
-	{
-		LL_DEBUGS("Inventory") << "deleted item " << *del_it << llendl;
-		gInventory.onObjectDeletedFromServer(*del_it, false, false);
-	}
-}
-
 void LLInventoryModel::onAISUpdateReceived(const std::string& context, const LLSD& update)
 {
 	if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 0608c46051..57d7d4fef6 100755
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -31,6 +31,7 @@
 #include "llsdserialize.h"
 #include "message.h"
 
+#include "llaisapi.h"
 #include "llagent.h"
 #include "llagentcamera.h"
 #include "llagentwearables.h"
@@ -258,6 +259,7 @@ public:
 };
 LLInventoryHandler gInventoryHandler;
 
+#if 0 // DELETE these when working in their new home
 
 ///----------------------------------------------------------------------------
 /// Classes for AISv3 support.
@@ -520,6 +522,7 @@ public:
 private:
 	LLSD mContents;
 };
+#endif
 
 ///----------------------------------------------------------------------------
 /// Class LLViewerInventoryItem
-- 
cgit v1.2.3