PageRenderTime 26ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/google/code/magja/service/category/CategoryRemoteServiceImpl.java

http://magja.googlecode.com/
Java | 693 lines | 406 code | 115 blank | 172 comment | 79 complexity | 057d2eb490dc736a1ab3555e29ba4ea3 MD5 | raw file
  1. /**
  2. * @author andre
  3. *
  4. */
  5. package com.google.code.magja.service.category;
  6. import java.util.ArrayList;
  7. import java.util.LinkedList;
  8. import java.util.List;
  9. import java.util.Map;
  10. import org.apache.axis2.AxisFault;
  11. import com.google.code.magja.magento.ResourcePath;
  12. import com.google.code.magja.model.category.Category;
  13. import com.google.code.magja.model.product.Product;
  14. import com.google.code.magja.service.GeneralServiceImpl;
  15. import com.google.code.magja.service.ServiceException;
  16. import com.google.code.magja.service.product.ProductRemoteService;
  17. public class CategoryRemoteServiceImpl extends GeneralServiceImpl<Category>
  18. implements CategoryRemoteService {
  19. private static final long serialVersionUID=5806879316902937610L;
  20. private ProductRemoteService productRemoteService;
  21. /*
  22. * (non-Javadoc)
  23. *
  24. * @seecom.google.code.magja.service.product.CategoryRemoteService#
  25. * setProductRemoteService
  26. * (com.google.code.magja.service.category.CategoryRemoteService)
  27. */
  28. @Override
  29. public void setProductRemoteService(
  30. ProductRemoteService productRemoteService) {
  31. this.productRemoteService = productRemoteService;
  32. }
  33. /**
  34. * Load children for the category
  35. *
  36. * @param category
  37. * @throws ServiceException
  38. */
  39. private void loadChildren(Category category) throws ServiceException {
  40. if (category.get("children") != null) {
  41. if (category.get("children").toString().length() > 0) {
  42. String str_children = (String) category.get("children");
  43. String[] arr_children = str_children.split(",");
  44. for (String str_child : arr_children) {
  45. Category child = getByIdClean(new Integer(str_child));
  46. if (child != null)
  47. category.addChild(child);
  48. }
  49. }
  50. }
  51. }
  52. /**
  53. * load parent for the category
  54. *
  55. * @param category
  56. * @throws ServiceException
  57. */
  58. private void loadParent(Category category) throws ServiceException {
  59. if (category.get("parent_id") != null) {
  60. Category parent = getByIdClean((Integer) category.get("parent_id"));
  61. category.setParent(parent);
  62. }
  63. }
  64. /*
  65. * (non-Javadoc)
  66. *
  67. * @see
  68. * com.google.code.magja.service.category.CategoryRemoteService#getByIdClean
  69. * (java.lang.Integer)
  70. */
  71. @Override
  72. public Category getByIdClean(Integer id) throws ServiceException {
  73. Category category = new Category();
  74. if (id == null)
  75. return null;
  76. Map<String, Object> cat;
  77. try {
  78. cat = (Map<String, Object>) soapClient.call(
  79. ResourcePath.CategoryInfo, id);
  80. } catch (AxisFault e) {
  81. if (debug)
  82. e.printStackTrace();
  83. throw new ServiceException(e.getMessage());
  84. }
  85. if (cat == null)
  86. return null;
  87. for (Map.Entry<String, Object> attribute : cat.entrySet())
  88. category.set(attribute.getKey(), attribute.getValue());
  89. return category;
  90. }
  91. /*
  92. * (non-Javadoc)
  93. *
  94. * @see com.google.code.magja.service.category.CategoryRemoteService#
  95. * getByIdWithChildren(java.lang.Integer)
  96. */
  97. @Override
  98. public Category getByIdWithChildren(Integer id) throws ServiceException {
  99. Category category = getByIdClean(id);
  100. // load category children
  101. loadChildren(category);
  102. return category;
  103. }
  104. /*
  105. * (non-Javadoc)
  106. *
  107. * @see com.google.code.magja.service.category.CategoryRemoteService#
  108. * getByIdWithParent(java.lang.Integer)
  109. */
  110. @Override
  111. public Category getByIdWithParent(Integer id) throws ServiceException {
  112. Category category = getByIdClean(id);
  113. // load category parent
  114. loadParent(category);
  115. return category;
  116. }
  117. /*
  118. * (non-Javadoc)
  119. *
  120. * @see com.google.code.magja.service.category.CategoryRemoteService#
  121. * getByIdWithParentAndChildren(java.lang.Integer)
  122. */
  123. @Override
  124. public Category getByIdWithParentAndChildren(Integer id)
  125. throws ServiceException {
  126. Category category = getByIdClean(id);
  127. // load category parent and children
  128. loadChildren(category);
  129. loadParent(category);
  130. return category;
  131. }
  132. /**
  133. * get all category with subcategory by id
  134. *
  135. * @param id
  136. * @throws ServiceException
  137. */
  138. @SuppressWarnings("unchecked")
  139. public Category getTree(Integer id) throws ServiceException {
  140. Category category = new Category();
  141. if (id == null)
  142. return null;
  143. Map<String, Object> cat;
  144. try {
  145. cat = (Map<String, Object>) soapClient.call(
  146. ResourcePath.CategoryTree, id);
  147. } catch (AxisFault e) {
  148. if (debug)
  149. e.printStackTrace();
  150. throw new ServiceException(e.getMessage());
  151. }
  152. if (cat == null)
  153. return null;
  154. category = getCategoryFromMap(cat);
  155. return category;
  156. }
  157. /**
  158. * build category from Map
  159. *
  160. * @param Map
  161. * <String, Object>
  162. */
  163. @SuppressWarnings("unchecked")
  164. private Category getCategoryFromMap(Map<String, Object> cat) {
  165. Category category = new Category();
  166. for (Map.Entry<String, Object> attribute : cat.entrySet()) {
  167. if (attribute.getKey().equals("children")) {
  168. List<Category> children = new ArrayList<Category>();
  169. List<Map<String, Object>> childrenList = (List<Map<String, Object>>) attribute
  170. .getValue();
  171. for (Map<String, Object> child : childrenList) {
  172. Category c = getCategoryFromMap(child);
  173. children.add(c);
  174. }
  175. category.setChildren(children);
  176. } else {
  177. category.set(attribute.getKey(), attribute.getValue());
  178. }
  179. }
  180. return category;
  181. }
  182. /**
  183. * print all categories
  184. *
  185. * @param id
  186. */
  187. public void print(Category category) {
  188. if (category != null) {
  189. String s = "";
  190. for (int i = 1; i < category.getLevel(); i++) {
  191. s += " ";
  192. }
  193. System.out.println(s + category.getName());
  194. for (Category child : category.getChildren()) {
  195. print(child);
  196. }
  197. }
  198. }
  199. /**
  200. * search categories
  201. *
  202. * @param id
  203. */
  204. public List<Category> search(Category category, List<String> categoryNames)
  205. throws ServiceException {
  206. List<Category> categories = new ArrayList<Category>();
  207. for (String name : categoryNames) {
  208. boolean found = false;
  209. for (Category child : category.getChildren()) {
  210. if (child.getName().equals(name)) {
  211. found = true;
  212. categories.add(child);
  213. // override parent with child
  214. category = child;
  215. break;
  216. }
  217. }
  218. if (!found) {
  219. throw new ServiceException("Category \"" + name
  220. + "\" not found.");
  221. }
  222. }
  223. return categories;
  224. }
  225. /**
  226. * search for equal child
  227. */
  228. public Category searchChild(Category category, Category search) throws ServiceException {
  229. if(category != null) {
  230. for(Category child : category.getChildren()) {
  231. if(child.getName().equals(search.getName())) {
  232. return child;
  233. }
  234. }
  235. }
  236. throw new ServiceException("Child not found");
  237. }
  238. /*
  239. * (non-Javadoc)
  240. *
  241. * @see
  242. * com.google.code.magja.service.category.CategoryRemoteService#save(code
  243. * .google .magja.model.product.Category)
  244. */
  245. @SuppressWarnings("unchecked")
  246. @Override
  247. public int save(Category category) throws ServiceException {
  248. return save(category, "");
  249. }
  250. public int save(Category category, String storeView) throws ServiceException {
  251. if (category.getId() == null) {
  252. List<Object> newCategory = new LinkedList<Object>();
  253. newCategory.add(category.getParent().getId());
  254. newCategory.add(category.getAllProperties());
  255. // means its a new category
  256. try {
  257. Integer id = Integer.parseInt((String) soapClient.call(
  258. ResourcePath.CategoryCreate, newCategory));
  259. if (id > -1) {
  260. category.setId(id);
  261. return id;
  262. } else {
  263. throw new ServiceException("Error inserting new Category");
  264. }
  265. } catch (NumberFormatException e) {
  266. if (debug)
  267. e.printStackTrace();
  268. throw new ServiceException(e.getMessage());
  269. } catch (AxisFault e) {
  270. if (debug)
  271. e.printStackTrace();
  272. if(e.getMessage().indexOf("available_sort_by") > 0) {
  273. System.out.println("Broken Magento API? Run this SQL code first\n" +
  274. "update eav_attribute set is_required = 0 where attribute_code = 'available_sort_by';");
  275. }
  276. throw new ServiceException(e.getMessage());
  277. }
  278. } else {
  279. // update existing category
  280. List<Object> newCategory = new LinkedList<Object>();
  281. newCategory.add(category.getId());
  282. newCategory.add(category.getAllProperties());
  283. if(!storeView.isEmpty()) {
  284. newCategory.add(storeView);
  285. }
  286. try {
  287. Boolean sucessed = (Boolean) soapClient.call(
  288. ResourcePath.CategoryUpdate, newCategory);
  289. if (!sucessed) {
  290. throw new ServiceException("Error on update Category");
  291. }
  292. } catch (AxisFault e) {
  293. if (debug)
  294. e.printStackTrace();
  295. throw new ServiceException(e.getMessage());
  296. }
  297. return category.getId();
  298. }
  299. }
  300. /**
  301. * Delete a category by id
  302. *
  303. * @param id
  304. * @throws ServiceException
  305. */
  306. public void delete(Integer id) throws ServiceException {
  307. Boolean success = false;
  308. try {
  309. success = (Boolean) soapClient
  310. .call(ResourcePath.CategoryDelete, id);
  311. } catch (AxisFault e) {
  312. System.out.println(e.getMessage());
  313. throw new ServiceException(e.getMessage());
  314. }
  315. if (!success) {
  316. throw new ServiceException("Not success deleting category.");
  317. }
  318. }
  319. /**
  320. * Delete a delete all children in a category
  321. *
  322. * @param parent
  323. * category id
  324. * @throws ServiceException
  325. */
  326. public void deleteAllChildren(Integer id) throws ServiceException {
  327. Category parent = getByIdWithChildren(id);
  328. List<Category> children = parent.getChildren();
  329. for (Category category : children) {
  330. delete(category.getId());
  331. }
  332. }
  333. /**
  334. * get default root category
  335. *
  336. * @param id
  337. * @throws ServiceException
  338. */
  339. public Category getDefaultParent() throws ServiceException {
  340. return getByIdClean(soapClient.getConfig().getDefaultRootCategoryId());
  341. }
  342. /**
  343. * create category from minimal parameter
  344. *
  345. * Settings: availableSortBy = name defaultSortBy = name active = true
  346. * anchor = true
  347. */
  348. public Category getMinimalCategory(Integer parentId, String categoryName) {
  349. return getRequiredCategory(parentId, categoryName, new String[] {"name"}, "name", true, true);
  350. }
  351. /**
  352. * create category with required parameter (this parameter are required by
  353. * Magento)
  354. */
  355. public Category getRequiredCategory(Integer parentId, String categoryName,
  356. String[] availableSortBy, String defaultSortBy, Boolean active,
  357. Boolean anchor) {
  358. Category parent = new Category(parentId);
  359. Category category = new Category(categoryName);
  360. category.setParent(parent);
  361. category.setAvailableSortBy(availableSortBy);
  362. category.setDefaultSortBy(defaultSortBy);
  363. category.setActive(active);
  364. category.setAnchor(anchor);
  365. return category;
  366. }
  367. /**
  368. * create category tree from String
  369. */
  370. public Category create(Integer parentId, String categoryName)
  371. throws ServiceException {
  372. List<String> categoryNames = new ArrayList<String>();
  373. categoryNames.add(categoryName);
  374. List<Category> categories = create(parentId, categoryNames);
  375. return categories.get(0);
  376. }
  377. /**
  378. * create category from category list
  379. */
  380. public Category linkCategory(List<Category> categories) throws ServiceException {
  381. if (categories.size() > 0) {
  382. for (int i = 0; i < categories.size(); i++) {
  383. // set parent
  384. if(i > 0) {
  385. Category parent = categories.get(i - 1);
  386. categories.get(i).setParent(parent);
  387. }
  388. // set children
  389. if(i < categories.size() - 1) {
  390. List<Category> children = new ArrayList<Category>();
  391. children.add(categories.get(i + 1));
  392. categories.get(i).setChildren(children);
  393. }
  394. }
  395. return categories.get(0);
  396. }
  397. throw new ServiceException("Category list is empty");
  398. }
  399. /**
  400. * create category tree from String array
  401. */
  402. public List<Category> create(Integer parentId, List<String> categoryNames)
  403. throws ServiceException {
  404. List<Category> categories = new ArrayList<Category>();
  405. for(String categoryName : categoryNames) {
  406. categories.add(getMinimalCategory(0, categoryName));
  407. }
  408. return create(parentId, linkCategory(categories));
  409. }
  410. /**
  411. * create category if not exists already
  412. */
  413. public List<Category> create(Integer parentId, Category category) throws ServiceException {
  414. if (parentId > 0 && category != null) {
  415. List<Category> categories = new ArrayList<Category>();
  416. Category parent = getTree(parentId);
  417. while(category != null) {
  418. try {
  419. // search for category
  420. Category child = searchChild(parent, category);
  421. // category exists already, set id from existing one
  422. category.setId(child.getId());
  423. // set values for next loop
  424. parent = child;
  425. parentId = parent.getId();
  426. } catch(Exception e) {
  427. parent = null;
  428. }
  429. // create / update category
  430. category.setParent(new Category(parentId));
  431. parentId = save(category);
  432. // add category to return list
  433. categories.add(category);
  434. // set values for next loop
  435. if(category.getChildren().size() > 0) {
  436. // set values for next loop
  437. // FIXME: set more then one child
  438. category = category.getChildren().get(0);
  439. } else {
  440. return categories;
  441. }
  442. }
  443. }
  444. throw new ServiceException("Fail to create a new category");
  445. }
  446. /**
  447. * Assign product to category
  448. */
  449. public void assignProduct(Category category, Product product)
  450. throws ServiceException {
  451. List<Object> list = new LinkedList<Object>();
  452. list.add(category.getId());
  453. list.add(product.getId());
  454. Boolean success = false;
  455. try {
  456. success = (Boolean) soapClient.call(
  457. ResourcePath.CategoryAssignProduct, list);
  458. } catch (AxisFault e) {
  459. System.out.println(e.getMessage());
  460. throw new ServiceException(e.getMessage());
  461. }
  462. if (!success) {
  463. throw new ServiceException(
  464. "Not success assign product to category.");
  465. }
  466. }
  467. /**
  468. * Get list of assigned products in default store
  469. */
  470. public List<Product> getProducts(Category category) throws ServiceException {
  471. return getProducts(category, 1, false);
  472. }
  473. /**
  474. * Get list of assigned products If dependencies are disabled, the Product
  475. * will contain only following attributes: product_id, type, set, sku. All
  476. * other attributes will be null.
  477. */
  478. public List<Product> getProducts(Category category, Integer storeID,
  479. boolean dependencies) throws ServiceException {
  480. if (category == null)
  481. return null;
  482. List<Object> list = new LinkedList<Object>();
  483. list.add(category.getId());
  484. list.add(storeID);
  485. List<Product> products = new ArrayList<Product>();
  486. List<Map<String, Object>> productList;
  487. try {
  488. productList = (List<Map<String, Object>>) soapClient.call(
  489. ResourcePath.CategoryAssignedProducts, list);
  490. } catch (AxisFault e) {
  491. if (debug)
  492. e.printStackTrace();
  493. throw new ServiceException(e.getMessage());
  494. }
  495. if (productList == null)
  496. return products;
  497. for (Map<String, Object> mpp : productList) {
  498. Product product = new Product();
  499. if (dependencies) {
  500. // buid a full product object if required
  501. product = productRemoteService.getBySku(mpp.get("sku").toString(), true);
  502. } else {
  503. // get minimal product object
  504. product = productRemoteService.getBySku(mpp.get("sku").toString(), false);
  505. }
  506. products.add(product);
  507. }
  508. return products;
  509. }
  510. /**
  511. * get list of last categories in a category tree
  512. */
  513. public List<Category> getLastCategories(Category categoryTree) {
  514. List<Category> categoryList = new ArrayList<Category>();
  515. for (Category child : categoryTree.getChildren()) {
  516. if (child.getChildren().isEmpty()) {
  517. categoryList.add(child);
  518. } else {
  519. List<Category> categorys = getLastCategories(child);
  520. for (Category c : categorys) {
  521. categoryList.add(c);
  522. }
  523. }
  524. }
  525. return categoryList;
  526. }
  527. /**
  528. * get list of last categories without products
  529. */
  530. public List<Category> findEmpty(Integer id) throws ServiceException {
  531. Category startCategory = getTree(id);
  532. List<Category> lastCategories = getLastCategories(startCategory);
  533. List<Category> emptyCategories = new ArrayList<Category>();
  534. for (Category category : lastCategories) {
  535. if (getProducts(category).isEmpty()) {
  536. emptyCategories.add(category);
  537. }
  538. }
  539. return emptyCategories;
  540. }
  541. /**
  542. * delete last categories without products
  543. */
  544. public Integer deleteEmpty(Integer id) throws ServiceException {
  545. List<Category> emptyCategories = findEmpty(id);
  546. for (Category category : emptyCategories) {
  547. delete(category.getId());
  548. }
  549. // FIXME: delete empty parent
  550. return emptyCategories.size();
  551. }
  552. /**
  553. * delete delete recursive if empty
  554. */
  555. public void deleteEmptyRecursive(Category category) throws ServiceException {
  556. if (isEmpty(category)) {
  557. // get parent category
  558. Category parent = getByIdWithParent(category.getId()).getParent();
  559. // delete current empty category
  560. delete(category.getId());
  561. // delete parent category if empty
  562. deleteEmptyRecursive(parent);
  563. }
  564. }
  565. /**
  566. * Check if category is empty
  567. *
  568. * @param cagegory
  569. * @throws ServiceException
  570. */
  571. public Boolean isEmpty(Category category) throws ServiceException {
  572. if (category.getChildren().isEmpty() && getProducts(category).isEmpty()) {
  573. return true;
  574. } else {
  575. return false;
  576. }
  577. }
  578. }