"Fossies" - the Fresh Open Source Software Archive 
Member "opengroupware-5.5rc3/Logic/LSAddress/LSVCardCompanyFormatter.m" (5 Dec 2015, 20873 Bytes) of package /linux/privat/opengroupware-5.5rc3.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Matlab source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "LSVCardCompanyFormatter.m" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
5.5rc2_vs_5.5rc3.
1 /*
2 Copyright (C) 2005 SKYRIX Software AG
3
4 This file is part of OpenGroupware.org.
5
6 OGo is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA.
20 */
21
22 #include "LSVCardCompanyFormatter.h"
23 #include "LSVCardAddressFormatter.h"
24 #include "LSVCardLabelFormatter.h"
25 #include "LSVCardNameFormatter.h"
26 #include "NSString+VCard.h"
27 #include "common.h"
28
29 NSString *LSVUidPrefix = @"vcfuid://";
30
31 @implementation LSVCardCompanyFormatter
32
33 static NSString *skyrixId = nil;
34 static NSDictionary *telephoneMapping = nil;
35 static NSDictionary *addressMapping = nil;
36 static BOOL renderOGoPhoneType = NO;
37
38 + (void)initialize {
39 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
40
41 skyrixId = [ud stringForKey:@"skyrix_id"];
42 skyrixId = [[NSString alloc] initWithFormat:@"skyrix://%@/%@/",
43 [[NSHost currentHost] name], skyrixId];
44
45 addressMapping = [[ud dictionaryForKey:@"LSVCard_AddressMapping"] copy];
46 telephoneMapping = [[ud dictionaryForKey:@"LSVCard_TelephoneMapping"] copy];
47 }
48
49 + (id)formatter {
50 return [[[self alloc] init] autorelease];
51 }
52
53 /* generic */
54
55 - (void)appendPreambleToString:(NSMutableString *)_ms {
56 [_ms appendString:@"BEGIN:VCARD\r\n"];
57 [_ms appendString:@"VERSION:3.0\r\n"];
58 [_ms appendFormat:@"PRODID:-//OpenGroupware.org//LSAddress v%i.%i.%i\r\n",
59 OGO_MAJOR_VERSION, OGO_MINOR_VERSION, OGO_SUBMINOR_VERSION];
60 [_ms appendString:@"PROFILE:vCard\r\n"];
61 }
62 - (void)appendPostambleToString:(NSMutableString *)_ms {
63 [_ms appendString:@"END:VCARD\r\n"];
64 }
65
66 /* vCard formatting */
67
68 - (void)_appendTextValue:(NSString *)_str toVCard:(NSMutableString *)_vCard {
69 [_vCard appendString:[_str stringByEscapingUnsafeVCardCharacters]];
70 }
71
72 - (void)_appendName:(NSString *)_name andValue:(id)_value
73 toVCard:(NSMutableString *)_vCard
74 {
75 [_vCard appendString:_name];
76 [_vCard appendString:@":"];
77 if ([_value isKindOfClass:[NSArray class]]) {
78 NSUInteger cnt, i;
79
80 for (i = 0, cnt = [_value count]; i < cnt; i++)
81 [self _appendTextValue:[_value objectAtIndex:i] toVCard:_vCard];
82 }
83 else if ([_value isKindOfClass:[NSString class]])
84 [self _appendTextValue:_value toVCard:_vCard];
85 else
86 [self _appendTextValue:[_value description] toVCard:_vCard];
87 [_vCard appendString:@"\r\n"];
88 }
89
90 /* common company stuff */
91
92 - (void)_appendIdentifier:(id)_contact toVCard:(NSMutableString *)_vCard {
93 // UID, SOURCE
94 NSString *sourceUrl;
95 id tmp;
96
97 if ([(sourceUrl = [_contact valueForKey:@"sourceUrl"]) isNotNull]) {
98 NSRange r;
99
100 r = [sourceUrl rangeOfString:@"://"];
101 if (r.length == 0) {
102 /* not a URL, use it as ID, prefix with UID prefix */
103 tmp = [LSVUidPrefix stringByAppendingString:sourceUrl];
104 [self _appendName:@"UID" andValue:sourceUrl toVCard:_vCard];
105 [self _appendName:@"SOURCE" andValue:tmp toVCard:_vCard];
106 }
107 else {
108 /* a URL, check for UID prefix, otherwise reuse the URL */
109 tmp = [sourceUrl hasPrefix:LSVUidPrefix]
110 ? [sourceUrl substringFromIndex:[LSVUidPrefix length]]
111 : sourceUrl;
112 [self _appendName:@"UID" andValue:tmp toVCard:_vCard];
113 [self _appendName:@"SOURCE" andValue:sourceUrl toVCard:_vCard];
114 }
115 }
116 else {
117 /* add internal OGo URL as UID _and_ SOURCE */
118 sourceUrl = [skyrixId stringByAppendingString:
119 [[_contact valueForKey:@"companyId"] stringValue]];
120 [self _appendName:@"UID" andValue:sourceUrl toVCard:_vCard];
121 [self _appendName:@"SOURCE" andValue:sourceUrl toVCard:_vCard];
122 }
123 }
124
125 - (void)_appendContactData:(id)_contact toVCard:(NSMutableString *)_vCard {
126 // COMMENT, CATEGORIES, CLASS, URL
127 id tmp;
128
129 tmp = [[NSString alloc] initWithFormat:
130 @"vCard for contact with id %@ (v%@)",
131 [_contact valueForKey:@"companyId"],
132 [_contact valueForKey:@"objectVersion"]];
133 [self _appendName:@"NAME" andValue:tmp toVCard:_vCard];
134 [tmp release]; tmp = nil;
135
136 /* COMMENT */
137 tmp = [[_contact valueForKey:@"comment"] valueForKey:@"comment"];
138 if ([tmp isNotNull])
139 [self _appendName:@"NOTE" andValue:tmp toVCard:_vCard];
140
141 /* CATEGORIES */
142 if ([(tmp = [_contact valueForKey:@"keywords"]) isNotNull]) {
143 tmp = [tmp componentsSeparatedByString:@","];
144 [self _appendName:@"CATEGORIES" andValue:tmp toVCard:_vCard];
145 }
146
147 /* CLASS */
148
149 if ([(tmp = [_contact valueForKey:@"sensitivity"]) isNotNull]) {
150 NSString *v;
151
152 if ([tmp intValue] == 2 /* private*/ || [tmp intValue] == 1 /* Personal */)
153 v = @"PRIVATE";
154 else if ([tmp intValue] == 3)
155 v = @"CONFIDENTIAL";
156 else if ([tmp intValue] == 0)
157 v = @"PUBLIC";
158 else {
159 [self errorWithFormat:@"unknown sensitivity, using private: %@", tmp];
160 v = @"PRIVATE";
161 }
162 [self _appendName:@"CLASS" andValue:v toVCard:_vCard];
163 }
164
165 /* URL */
166 if ([(tmp = [_contact valueForKey:@"url"]) isNotEmpty])
167 [self _appendName:@"URL" andValue:tmp toVCard:_vCard];
168
169 /* X-EVOLUTION-FILE-AS */
170 if ([(tmp = [_contact valueForKey:@"fileas"]) isNotEmpty])
171 [self _appendName:@"X-EVOLUTION-FILE-AS" andValue:tmp toVCard:_vCard];
172
173 /* X-EVOLUTION-MANAGER */
174 if ([(tmp = [_contact valueForKey:@"bossName"]) isNotEmpty])
175 [self _appendName:@"X-EVOLUTION-MANAGER" andValue:tmp toVCard:_vCard];
176
177 /* X-EVOLUTION-ASSISTANT */
178 if ([(tmp = [_contact valueForKey:@"assistantName"]) isNotEmpty])
179 [self _appendName:@"X-EVOLUTION-ASSISTANT" andValue:tmp toVCard:_vCard];
180
181 /* X-EVOLUTION-SPOUSE */
182 if ([(tmp = [_contact valueForKey:@"partnerName"]) isNotEmpty])
183 [self _appendName:@"X-EVOLUTION-SPOUSE" andValue:tmp toVCard:_vCard];
184
185 /* ROLE */
186 if ([(tmp = [_contact valueForKey:@"occupation"]) isNotEmpty])
187 /* 'profession' in Evo UI */
188 [self _appendName:@"ROLE" andValue:tmp toVCard:_vCard];
189
190 /* X-AIM or X-ICQ or X-JABBER */
191 if ([(tmp = [_contact valueForKey:@"imAddress"]) isNotEmpty]) {
192 if (isdigit([tmp characterAtIndex:0]))
193 [self _appendName:@"X-ICQ" andValue:tmp toVCard:_vCard];
194 else if ([tmp rangeOfString:@"@"].length > 0)
195 [self _appendName:@"X-JABBER" andValue:tmp toVCard:_vCard];
196 else
197 [self _appendName:@"X-AIM" andValue:tmp toVCard:_vCard];
198 }
199
200 /* X-EVOLUTION-ANNIVERSARY */
201 if ([(tmp = [_contact valueForKey:@"anniversary"]) isNotNull]) {
202 tmp = [[NSString alloc] initWithFormat:@"%04"PRIiPTR"-%02"PRIiPTR"-%02"PRIiPTR,
203 [tmp yearOfCommonEra], [tmp monthOfYear],
204 [tmp dayOfMonth]];
205 [self _appendName:@"X-EVOLUTION-ANNIVERSARY" andValue:tmp
206 toVCard:_vCard];
207 [tmp release];
208 }
209 }
210
211 - (NSString *)typeFromVCardTypeHack:(NSString *)type {
212 if (![type isNotNull]) return nil;
213 if (![type hasPrefix:@"V:"]) return nil;
214
215 /* a vCard specific type */
216 type = [type substringFromIndex:2];
217
218 // remove counter (eg V:1work, V:2work)
219 if ([type isNotEmpty] && isdigit([type characterAtIndex:0]))
220 type = [type substringFromIndex:1];
221
222 if ([type hasSuffix:@"untyped"]) /* imported VCF had no ADR type */
223 type = nil;
224 return type;
225 }
226
227 - (void)_appendAddressData:(id)_contact toVCard:(NSMutableString *)_vCard {
228 // ADR, LABEL
229 NSArray *addrs;
230 NSUInteger i, cnt;
231
232 if (![(addrs = [_contact valueForKey:@"addresses"]) isNotNull]) {
233 [self warnWithFormat:@"got no addresses for contact with id: %@",
234 [_contact valueForKey:@"companyId"]];
235 return;
236 }
237
238 for (i = 0, cnt = [addrs count]; i < cnt; i++) {
239 NSString *s;
240 NSString *type;
241 id address;
242
243 address = [addrs objectAtIndex:i];
244
245 type = [address valueForKey:@"type"];
246
247 type = ([type isNotNull] && [type hasPrefix:@"V:"])
248 ? [self typeFromVCardTypeHack:type]
249 : (NSString *)[addressMapping valueForKey:type];
250
251 s = [[LSVCardAddressFormatter formatter] stringForObjectValue:address];
252 if (s != nil) {
253 [_vCard appendString:@"ADR"];
254 if ([type isNotEmpty]) [_vCard appendFormat:@";TYPE=%@", type];
255 [_vCard appendString:@":"];
256 [_vCard appendString:s];
257 [_vCard appendString:@"\r\n"];
258 }
259
260 s = [[LSVCardLabelFormatter formatter] stringForObjectValue:address];
261 if ([s isNotEmpty]) {
262 [_vCard appendString:@"LABEL"];
263 if ([type isNotEmpty]) [_vCard appendFormat:@";TYPE=%@", type];
264 [_vCard appendString:@":"];
265 [_vCard appendString:s];
266 [_vCard appendString:@"\r\n"];
267 }
268 }
269 }
270
271 - (NSString *)vCardStringForTelInfo:(NSString *)info {
272 NSMutableString *ms;
273
274 if (![info isNotNull]) return nil;
275 if (![info isNotEmpty]) return nil;
276
277 if (![info hasPrefix:@"V:"]) {
278 info = [info stringByEscapingUnsafeVCardCharacters];
279 return [@";X-OGO-INFO=" stringByAppendingString:info];
280 }
281
282 info = [info substringFromIndex:2];
283 ms = [NSMutableString stringWithCapacity:32];
284
285 if ([info characterAtIndex:0] == '{') {
286 NSDictionary *plist;
287 NSEnumerator *e;
288 NSString *k;
289
290 plist = [info propertyList];
291 e = [plist keyEnumerator];
292 while ((k = [e nextObject]) != nil) {
293 [ms appendString:@";"];
294 [ms appendString:k];
295 [ms appendString:@"="];
296 [ms appendString:[[plist objectForKey:k] stringValue]];
297 }
298 }
299 else {
300 [ms appendString:@";"];
301 [ms appendString:info];
302 }
303 return ms;
304 }
305
306 static int compareKey(id o1, id o2, void *ctx) {
307 if (o1 == o2) return NSOrderedSame;
308 return [(NSString *)[o1 valueForKey:ctx] compare:[o2 valueForKey:ctx]];
309 }
310
311 - (void)_appendTelephoneData:(id)_company toVCard:(NSMutableString *)_vCard {
312 /* TEL property */
313 NSArray *telephones;
314 NSUInteger i, cnt;
315
316 /* always render phones in the same ordering */
317 telephones = [_company valueForKey:@"telephones"];
318 telephones = [telephones sortedArrayUsingFunction:compareKey
319 context:@"type"];
320 for (i = 0, cnt = [telephones count]; i < cnt; i++) {
321 NSMutableString *name;
322 NSString *num, *type, *info;
323 id telephoneEO;
324
325 telephoneEO = [telephones objectAtIndex:i];
326 type = [telephoneEO valueForKey:@"type"];
327 info = [telephoneEO valueForKey:@"info"];
328 num = [telephoneEO valueForKey:@"number"];
329
330 if (![num isNotNull]) continue;
331 if (![num isNotEmpty]) continue;
332
333 name = [[NSMutableString alloc] initWithCapacity:128];
334 [name appendString:@"TEL"];
335
336 if ([type isNotEmpty]) {
337 if (renderOGoPhoneType) {
338 [name appendString:@";X-OGO-TYPE="];
339 [name appendString:type];
340 }
341
342 if ([type hasPrefix:@"V:"]) {
343 if ((type = [self typeFromVCardTypeHack:type]) != nil) {
344 [name appendString:@";TYPE="];
345 [name appendString:type];
346 }
347 }
348 else if ((type = [telephoneMapping valueForKey:type]) != nil) {
349 NSEnumerator *e;
350
351 e = [type isKindOfClass:[NSArray class]]
352 ? [(id)type objectEnumerator]
353 : [[type componentsSeparatedByString:@","] objectEnumerator];
354 while ((type = [e nextObject]) != nil) {
355 if (![type isNotEmpty]) continue;
356 [name appendString:@";TYPE="];
357 [name appendString:type];
358 }
359 }
360 else {
361 [self logWithFormat:@"Note: did not find a mapping for phone: %@ / %@",
362 [telephoneEO valueForKey:@"telephoneId"],
363 [telephoneEO valueForKey:@"type"]];
364 }
365 }
366 else {
367 [self errorWithFormat:@"phone has no type: %@",
368 [telephoneEO valueForKey:@"telephoneId"]];
369 }
370
371 if ((info = [self vCardStringForTelInfo:info]) != nil)
372 [name appendString:info]; /* includes the preceding semicolon */
373
374 [self _appendName:name andValue:num toVCard:_vCard];
375 [name release]; name = nil;
376 }
377 }
378
379 - (void)_appendExtraEmails:(id)_person markFirstAsPreferred:(BOOL)_pref
380 toVCard:(NSMutableString *)_vCard
381 {
382 id tmp;
383
384 if ([(tmp = [_person valueForKey:@"email1"]) isNotNull]) {
385 [self _appendName:(_pref ? @"EMAIL;TYPE=PREF" : @"EMAIL") andValue:tmp
386 toVCard:_vCard];
387 }
388 if ([(tmp = [_person valueForKey:@"email2"]) isNotNull])
389 [self _appendName:@"EMAIL" andValue:tmp toVCard:_vCard];
390 if ([(tmp = [_person valueForKey:@"email3"]) isNotNull])
391 [self _appendName:@"EMAIL" andValue:tmp toVCard:_vCard];
392 if ([(tmp = [_person valueForKey:@"email4"]) isNotNull])
393 [self _appendName:@"EMAIL" andValue:tmp toVCard:_vCard];
394 }
395
396 - (void)_appendExtendedAttributes:(id)_contact
397 toVCard:(NSMutableString *)_vCard
398 {
399 // todo: deliver company values eg as Kontact X- attributes
400 }
401
402 /* main entry */
403
404 - (void)appendContentForObject:(id)_company toString:(NSMutableString *)_ms {
405 // override in subclasses
406 }
407
408 - (NSString *)stringForObjectValue:(id)_company {
409 NSMutableString *ms;
410
411 ms = [NSMutableString stringWithCapacity:1024];
412 [self appendPreambleToString:ms];
413 [self appendContentForObject:_company toString:ms];
414 [self appendPostambleToString:ms];
415 return ms;
416 }
417
418 @end /* LSVCardCompanyFormatter */
419
420
421 @implementation LSVCardTeamFormatter
422
423 - (void)_appendTeamData:(id)_team toVCard:(NSMutableString *)_vCard {
424 id tmp;
425
426 tmp = [_team valueForKey:@"description"];
427 if (![tmp isNotNull] || ![tmp isNotEmpty]) {
428 tmp = [NSString stringWithFormat:@"Team: %@",
429 [_team valueForKey:@"companyId"]];
430 }
431 // FN, formatted name
432 [self _appendName:@"FN" andValue:tmp toVCard:_vCard];
433 // N
434 [_vCard appendString:@"N:"];
435 [self _appendTextValue:tmp toVCard:_vCard];
436 if ([tmp = ([_team valueForKey:@"number"]) isNotNull]) {
437 [_vCard appendString:@";"];
438 [self _appendTextValue:tmp toVCard:_vCard];
439 }
440 [_vCard appendString:@"\r\n"];
441
442 /* EMAIL */
443
444 if ([(tmp = [_team valueForKey:@"email"]) isNotNull])
445 [self _appendName:@"EMAIL;TYPE=PREF" andValue:tmp toVCard:_vCard];
446 [self _appendExtraEmails:_team markFirstAsPreferred:NO toVCard:_vCard];
447 }
448
449 - (void)appendContentForObject:(id)_comp toString:(NSMutableString *)_ms {
450 [self _appendTeamData:_comp toVCard:_ms];
451 [self _appendIdentifier:_comp toVCard:_ms];
452 [self _appendContactData:_comp toVCard:_ms];
453 }
454
455 @end /* LSVCardTeamFormatter */
456
457
458 @implementation LSVCardPersonFormatter
459
460 - (void)_appendPersonName:(id)_person toVCard:(NSMutableString *)_vCard {
461 // FN and N are required
462 NSString *s;
463
464 // N:lastname;givenname;additional names;honorific prefixes;
465 // honorifix suffixes
466 s = [[LSVCardNameFormatter formatter] stringForObjectValue:_person];
467 [_vCard appendString:@"N:"];
468 [_vCard appendString:s];
469 [_vCard appendString:@"\r\n"];
470
471 s = [[LSVCardFormattedNameFormatter formatter] stringForObjectValue:_person];
472 [_vCard appendString:@"FN:"];
473 [_vCard appendString:s];
474 [_vCard appendString:@"\r\n"];
475 }
476
477 - (void)_appendOrg:(id)_person toVCard:(NSMutableString *)_vCard {
478 // sequence: company,department,office
479 NSString *org, *dep, *office;
480
481 // thats tricky, we might want to map 'org' to the first company?
482 org = [_person valueForKey:@"associatedCompany"]; // TODO: CSV?
483 dep = [_person valueForKey:@"department"];
484 office = [_person valueForKey:@"office"];
485 if (![org isNotNull] || ![org isNotEmpty]) org = nil;
486 if (![dep isNotNull] || ![dep isNotEmpty]) dep = nil;
487 if (![office isNotNull] || ![office isNotEmpty]) office = nil;
488
489 if (org == nil && dep == nil && office == nil)
490 return;
491
492 [_vCard appendString:@"ORG:"];
493 [_vCard appendString:(org != nil)
494 ? [org stringByEscapingUnsafeVCardCharacters] : (NSString *)@""];
495 if (dep != nil || office != nil) {
496 [_vCard appendString:@";"];
497 [_vCard appendString:(dep != nil)
498 ? [dep stringByEscapingUnsafeVCardCharacters] : (NSString *)@""];
499 }
500 if (office != nil) {
501 [_vCard appendString:@";"];
502 [_vCard appendString:[office stringByEscapingUnsafeVCardCharacters]];
503 }
504
505 [_vCard appendString:@"\r\n"];
506 }
507
508 - (void)_appendPersonData:(id)_person toVCard:(NSMutableString *)_vCard {
509 // FN, N, EMAIL, NICKNAME, BDAY, TITLE, FBURL
510 id tmp;
511
512 [self _appendPersonName:_person toVCard:_vCard]; // FN, N
513
514 // EMAIL
515 [self _appendExtraEmails:_person markFirstAsPreferred:YES toVCard:_vCard];
516 if ([(tmp = [_person valueForKey:@"email"]) isNotNull])
517 [self _appendName:@"EMAIL" andValue:tmp toVCard:_vCard];
518
519 // NICKNAME
520 if ([(tmp = [_person valueForKey:@"description"]) isNotNull])
521 [self _appendName:@"NICKNAME" andValue:tmp toVCard:_vCard];
522 // BDAY
523 if ([(tmp = [_person valueForKey:@"birthday"]) isNotNull]) {
524 tmp = [[NSString alloc] initWithFormat:@"%04"PRIiPTR"-%02"PRIiPTR"-%02"PRIiPTR,
525 [tmp yearOfCommonEra], [tmp monthOfYear],
526 [tmp dayOfMonth]];
527 [self _appendName:@"BDAY" andValue:tmp toVCard:_vCard];
528 [tmp release];
529 }
530 // TITLE
531 if ([(tmp = [_person valueForKey:@"job_title"]) isNotNull])
532 [self _appendName:@"TITLE" andValue:tmp toVCard:_vCard];
533
534 // FBURL
535 tmp = [_person valueForKey:@"isAccount"];
536 if ([tmp isNotNull] && ([tmp intValue] == 1)) {
537 tmp = [NSString stringWithFormat:@"http://%@/zidestore/so/%@.vfb",
538 [[NSHost currentHost] name],
539 [_person valueForKey:@"login"]];
540 [self _appendName:@"FBURL" andValue:tmp toVCard:_vCard];
541 } else {
542 if ([(tmp = [_person valueForKey:@"freebusyUrl"]) isNotNull])
543 [self _appendName:@"FBURL" andValue:tmp toVCard:_vCard];
544 }
545 }
546
547 - (void)appendContentForObject:(id)_comp toString:(NSMutableString *)_ms {
548 [self _appendPersonData:_comp toVCard:_ms];
549
550 [self _appendIdentifier:_comp toVCard:_ms];
551 [self _appendContactData:_comp toVCard:_ms];
552 [self _appendAddressData:_comp toVCard:_ms];
553 [self _appendTelephoneData:_comp toVCard:_ms];
554 [self _appendOrg:_comp toVCard:_ms];
555 [self _appendExtendedAttributes:_comp toVCard:_ms];
556 }
557
558 @end /* LSVCardPersonFormatter */
559
560
561 @implementation LSVCardEnterpriseFormatter
562
563 - (void)_appendOrg:(id)_contact toVCard:(NSMutableString *)_vCard {
564 // sequence: company,department,office
565 NSString *org, *dep, *office;
566
567 org = [_contact valueForKey:@"description"];
568 dep = [_contact valueForKey:@"department"];
569 office = [_contact valueForKey:@"office"];
570 if (![org isNotNull] || ![org isNotEmpty]) org = nil;
571 if (![dep isNotNull] || ![dep isNotEmpty]) dep = nil;
572 if (![office isNotNull] || ![office isNotEmpty]) office = nil;
573
574 if (org == nil && dep == nil && office == nil)
575 return;
576
577 [_vCard appendString:@"ORG:"];
578 [_vCard appendString:(org != nil)
579 ? [org stringByEscapingUnsafeVCardCharacters] : (NSString *)@""];
580 if (dep != nil || office != nil) {
581 [_vCard appendString:@";"];
582 [_vCard appendString:(dep != nil)
583 ? [dep stringByEscapingUnsafeVCardCharacters] : (NSString *)@""];
584 }
585 if (office != nil) {
586 [_vCard appendString:@";"];
587 [_vCard appendString:[office stringByEscapingUnsafeVCardCharacters]];
588 }
589
590 [_vCard appendString:@"\r\n"];
591 }
592
593 - (void)_appendEnterpriseData:(id)_e toVCard:(NSMutableString *)_vCard{
594 // FN, N, ORG, EMAIL
595 id tmp;
596
597 tmp = [_e valueForKey:@"description"];
598 if (![tmp isNotEmpty]) {
599 tmp = [NSString stringWithFormat:@"Enterprise: %@",
600 [_e valueForKey:@"companyId"]];
601 }
602 // FN, formatted name
603 [self _appendName:@"FN" andValue:tmp toVCard:_vCard];
604
605 // ORG
606 [self _appendOrg:_e toVCard:_vCard];
607
608 // N
609 [_vCard appendString:@"N:"];
610 [self _appendTextValue:tmp toVCard:_vCard];
611 if ([tmp = ([_e valueForKey:@"number"]) isNotNull]) {
612 [_vCard appendString:@";"];
613 [self _appendTextValue:tmp toVCard:_vCard];
614 }
615 [_vCard appendString:@"\r\n"];
616
617 if ([(tmp = [_e valueForKey:@"email"]) isNotNull])
618 [self _appendName:@"EMAIL;TYPE=PREF" andValue:tmp toVCard:_vCard];
619
620 [self _appendExtraEmails:_e markFirstAsPreferred:NO toVCard:_vCard];
621 }
622
623 - (void)appendContentForObject:(id)_comp toString:(NSMutableString *)_ms {
624 [self _appendEnterpriseData:_comp toVCard:_ms];
625
626 [self _appendIdentifier:_comp toVCard:_ms];
627 [self _appendContactData:_comp toVCard:_ms];
628 [self _appendAddressData:_comp toVCard:_ms];
629 [self _appendTelephoneData:_comp toVCard:_ms];
630 [self _appendExtendedAttributes:_comp toVCard:_ms];
631 }
632
633 @end /* LSVCardEnterpriseFormatter */